Being the Entire Product Team Across Two Fashion-Tech Businesses
Recruited to spearhead systems architecture for two partnered companies — a franchise-able bespoke manufacturer and a digital tech-pack startup. Untangled a shared AWS environment, split one overloaded database into three purpose-built systems, and rebuilt the tech-pack product end to end.
- Role
- System Architect / Full-Stack Engineer (Lead)
- Where
- Fashion technical-design startup & partnered bespoke manufacturer
- TypeScript
- Remix (React)
- Vue (legacy)
- PostgreSQL
- MySQL
- Prisma
- AWS CDK
- CodePipeline / CodeBuild
- ECS Fargate
- AWS Lambda
- AWS DMS
- TailwindCSS
- Figma
Context
I came into this work through a manager I'd worked with at a previous employer — he knew my work and wanted me to spearhead systems architecture for two companies in partnership: a bespoke manufacturer building a franchise-able production model, and a fashion technical-design startup pioneering "digital tech packs" — the structured specification documents that turn a design into something a factory can actually produce. Because the two businesses operated in partnership, I moved fluidly between them, and the architecture had to serve both.
No PM. No designer. I owned product, design, and engineering across the stack — interviewing working fashion designers, building personas and roadmaps, designing the UI in Figma, and writing the code.
What I Walked Into
The environment was a kitchen sink. Everything for both businesses lived in one default VPC with no separation between companies. Databases sat on public subnets. Hundreds of security groups had no naming convention — some deprecated, some load-bearing, nobody could say which — and they were reused across so many platforms that when I mapped them into a mind-map, the result was a genuinely tangled web. Deployments were manual: build a JAR from the CLI, SSH the file to the server, then spend hours validating the deployment by hand.
flowchart TB
subgraph Before ["Deployments — before"]
direction LR
A["Build JAR via CLI"] --> B["SSH file transfer<br/>to server"] --> C["Hours of manual<br/>validation"]
end
subgraph After ["Deployments — after"]
direction LR
M["Merge to main /<br/>dev / test branch"] --> P["CodePipeline<br/>triggers CodeBuild"] --> I["Docker image<br/>built & tagged"] --> F["ECS Fargate task<br/>deploys image"] --> H["Health checks pass"] --> T["Load balancer swaps<br/>to new target group"]
end
Before ~~~ After
Re-architecting the Cloud
I rebuilt the AWS footprint as infrastructure-as-code with CDK, so every application got its own provisioned pipeline instead of hand-managed resources:
- Segmented VPCs — production, test, and development, replacing the single default VPC where everything had lived together
- Per-application CI/CD — CodeBuild, CodePipeline, ECR, ECS on Fargate, and an application load balancer, all stamped out by CDK per app
- Scoped security groups — replacing the tangle of hundreds of unnamed, reused groups with per-application groups that CDK owns and names
- Per-facility Lambda overrides — versioned functions that let each warehouse facility customize execution behavior without forking the platform
- Databases off public subnets — among the security remediations that came with the redesign
flowchart TB
subgraph CDK ["Per application — stamped out by CDK"]
CB["CodeBuild"] --> CP["CodePipeline"]
end
CDK --> PROD & TEST & DEV
subgraph PROD ["Production VPC"]
SG["Scoped security group"] --> ECS["ECR → ECS Fargate → ALB"]
L["Per-facility Lambda<br/>overrides (versioned)"]
end
TEST["Test VPC"]
DEV["Development VPC"]
Untangling the Data
The deeper problem was the database. One schema served both businesses with no single source of truth for key entities — some tables were shared across companies. The manufacturer was opening a second facility, but the database was married to the digital tech-pack data, which must never be duplicated per facility. The question became: how do you split a live database so part of it scales per-warehouse and part of it stays global?
The answer was three purpose-built databases, re-architected to 3NF and migrated live via AWS DMS with zero data loss:
- Digital Tech Packs (PostgreSQL) — the startup's product; one global source of truth
- WMS (MySQL) — orders and multi-warehouse management, shared across facilities
- WES (MySQL, per facility) — warehouse execution, one database per facility so new facilities scale by stamping out another instance
The tech packs feed the warehouse directly: cron jobs read incoming orders, pull the tech pack associated with each order, build a facility-specific order detail, and dispatch it to that facility's WES — which queues work for industrial fabric cutting and printing machines and coordinates the specialized autonomous bots that move fabric bins across the floor.
flowchart LR
O["3rd-party<br/>ordering sites"] -->|cron jobs| WMSA["WMS application"]
WMSA --> WMSD[("MySQL WMS<br/>orders & multi-warehouse")]
TP[("PostgreSQL<br/>Digital Tech Packs<br/>(global source of truth)")] -->|"pull tech pack<br/>per order"| CRON["Cron: build facility-specific<br/>order detail"]
WMSD --> CRON
CRON --> WES1[("MySQL WES<br/>Facility 1")]
CRON --> WES2[("MySQL WES<br/>Facility 2")]
WES1 --> M1["Cutting & printing machine queues<br/>· autonomous fabric-bin bots"]
Rebuilding the Tech-Pack Product
The startup's production app was a Vue application with long screen loads and a disjointed sub-app experience — to add fabrics to a tech pack, users had to close the tech pack, open a separate sub-app to add fabrics, then return, refresh, and import them. Validation was thin, and user-error classes that mattered in manufacturing weren't being caught.
I rebuilt it as a Remix.run full-stack application: heavy server-side calculation and validation to catch user error before it reached production, fabrics managed inline without ever leaving the tech pack, and dramatically faster loads. Designers used the product live throughout — feedback loops in days, not quarters — with 95%+ of the application built solo, from Figma mockups to production code.
Outcome
- Two partnered businesses, one coherent architecture — with clean separation where it mattered
- A franchise-able facility model: opening a warehouse now means stamping out a WES instance and its Lambda overrides, not untangling shared tables
- Deployments went from SSH-and-pray to health-checked pipeline cutover
- An undocumented environment became documented, CDK-managed infrastructure
- The tech-pack experience went from fragmented sub-apps to a single fast, validated flow