Being the Entire Product Team Across Two Fashion-Tech Businesses
Led architecture for a bespoke manufacturer and its digital tech-pack partner. I separated their shared AWS environment, decomposed one overloaded database into Tech Packs, WMS, and per-facility WES systems, and rebuilt the tech-pack application.
- 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 joined through a former manager who asked me to lead systems architecture for two partnered companies: a bespoke manufacturer building a franchise-able production model, and a fashion technical-design startup building digital tech packs. A tech pack is the structured specification a factory uses to turn a design into a manufactured garment. Because the businesses shared operational systems, the architecture had to support both while establishing clear ownership boundaries.
There was no PM or designer. I owned product discovery, UI design, and engineering: I interviewed working fashion designers, defined personas and roadmaps, designed in Figma, and implemented the product across the stack.
What I Walked Into
Both businesses ran in one default VPC with no environment or company boundary. Databases were on public subnets. Hundreds of reused security groups had no naming convention or documented ownership, so it was unclear which rules were deprecated and which were required by active workloads. Deployments were also manual: build a JAR from the CLI, copy it to a server over SSH, and manually validate the release for hours.
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 with CDK infrastructure as code. Each application received a repeatable deployment definition rather than a set of manually managed resources:
- Segmented VPCs: production, test, and development replaced the single default VPC.
- Per-application CI/CD: CDK provisioned CodeBuild, CodePipeline, ECR, ECS on Fargate, and an application load balancer for each app.
- Scoped security groups: each application received CDK-owned, named rules instead of relying on the reused pool of unnamed groups.
- Per-facility Lambda overrides: versioned functions let each warehouse facility customize execution behavior without forking the platform
- Private database placement: databases were moved off public subnets as part of the security remediation.
flowchart TB
subgraph CDK ["Per application: provisioned 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 data model was the harder problem. One schema served both businesses, and key entities had no single source of truth. Some tables were shared across companies. The manufacturer was opening a second facility, but digital tech-pack data needed to remain global rather than being duplicated per facility. I needed to split a live database according to data ownership: facility-scoped execution data could scale horizontally, while tech-pack data remained centralized.
I normalized the data model to 3NF and migrated it live with AWS DMS, with zero data loss. The resulting system had three databases with explicit responsibilities:
- Digital Tech Packs (PostgreSQL): the startup's product and 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 order-processing integration connected the systems without collapsing their boundaries. Cron jobs read incoming orders, retrieve the associated tech pack, build a facility-specific order detail, and dispatch it to that facility's WES. The WES queues work for industrial fabric-cutting and printing machines and coordinates 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 fragmented sub-application workflow. To add fabrics to a tech pack, users had to close the tech pack, open a separate application, add fabrics, return, refresh, and import them. Validation was limited, leaving manufacturing-relevant user errors uncaught.
I rebuilt it as a Remix full-stack application. Server-side calculations and validation rejected user errors before data reached production. I moved fabric management into the tech-pack workflow, eliminating the cross-application import loop, and improved load times. Working designers used the product throughout development, which kept feedback cycles to days. I built more than 95% of the application myself, from Figma mockups to production code.
Outcome
- Established separate infrastructure, deployment, and data-ownership boundaries for two partnered businesses
- Created a franchise-able facility model: opening a warehouse means provisioning a WES instance and its Lambda overrides instead of untangling shared tables
- Replaced manual SSH releases with health-checked ECS Fargate pipeline cutovers
- Converted an undocumented environment into documented, CDK-managed infrastructure
- Replaced fragmented sub-app workflows with one faster, validated tech-pack flow