The demo link's fillDemo helper hard-coded real demo credentials into the frontend bundle, so anyone with the login URL or viewing source could sign in. Remove the link, the fillDemo helper, and its CSS. Verified the creds are no longer present in the built bundle. Follow-up: the demo account still exists server-side (and the creds are now in git history) — deactivate it or rotate its password via /admin for full closure. tsc -b + build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SAPL Garment Intelligence
POC for Sonal Apparels Private Limited (SAPL) · Built by Ajay Sable — Senior Gen AI Developer
An AI platform for a garment export house, built around two pillars:
- Design Library / PLM portal ("the studio's Pinterest") — every style, fabric and graphic in one searchable, AI-tagged home, with auto style-numbering, QR hangtags and physical-sample tracking.
- TNA (Time & Action) order tracking — a live, plain-English dashboard over the WFX → Stitch order lifecycle so merchants and the CEO can see where every order is and what needs action today.
plans/STATUS.mdis the living system-of-record (dated work log). This README is the orientation + run guide.
Modules
Design Library / PLM
- AI tagging — upload up to 4 shots (front, back, swatch, detail); Mistral Pixtral extracts the 17-field taxonomy with a confidence score per field. ≥85% auto-saves, 65–85% goes to review, <65% is flagged.
- Auto style-numbering — on upload, a gap-safe style number is reserved per segment (new-dev / shopping)
× category (mens / womens / kids), e.g.
M0001,W0002,SM0001; colourways use a shared base +-A/-B. - QR hangtag — once a style has fabric quality + pattern no. + counters, a frozen QR is generated and stored; a printable hangtag shows Style No. + Fabric Quality with everything else behind the scan.
- QR scan landing (
/g/:style, public) — scanning resolves to the full garment detail view. - Semantic + intent search, faceted filters, Boards/Collections (personal + public "playlists"), duplicate detection (cosine ≥ 0.90 on upload), PDF/PPT deck ingest, physical-sample tracking, analytics.
- Moodboard decoder (image + buyer PDF deck) and market/trend scraper feed the design process.
TNA order tracking
- Production Line glance view (
/tna) — PCD-split parallel-zone cards (pre-production vs factory), each zone an independent, colour-blind-safe status dot; triage-by-exception headline; buyer/owner lens. - Tap a zone → inline lifecycle (WFX → Stitch) with a spotlight; "Detailed PERT view" = a linear-metro critical-path timeline with an AI "what's happening" read.
- Morning Watchdog daily brief, All Orders table, "Waiting for a TNA" lane. Data syncs from Stitch + WFX every 2 min.
Platform
- Auth (login-gated SPA; users seeded on first run), Admin DB explorer (Ajay-only), deploy-ready Docker/Caddy stack.
Stack
React 18 + TypeScript + Tailwind (Vite, :5173)
│ REST JSON
▼
FastAPI + Python 3.11+ (:8000)
├── Mistral Pixtral → 17-field garment tag extraction
├── Gemini (google-genai) → embeddings (gemini-embedding-2-preview, 1024-dim)
│ + moodboard decode / TNA recommender / PERT narrator (gemini-3-flash-preview)
├── Groq llama-3.3-70b → market-scraper agent loop
├── ChromaDB (local) → vector similarity search
├── SQLite → garments, tags, audit, TNA mirror, collections
├── qrcode + Pillow → QR codes + printable hangtags
└── WFX WebAPI + Stitch API → order / TNA lifecycle data
Setup
Prerequisites
- Python 3.11+ · Node 18+
- API keys:
MISTRAL_API_KEY(tagging),GEMINI_API_KEY(embeddings + AI features),GROQ_API_KEY(scraper). TNA also uses WFX/Stitch credentials (see.env.example).
Backend
cd backend
python3 -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # then fill in the API keys
python data/seed/seed.py # seed garments + ChromaDB embeddings (first run)
uvicorn main:app --reload --port 8000
API docs: http://localhost:8000/docs · Login users are seeded on first startup (see main.py).
Frontend
cd frontend
npm install
npm run dev # http://localhost:5173
LAN access (for QR scanning from a phone)
A phone can't reach the dev box's localhost, so for live QR-scan testing:
backend/.env→QR_BASE_URL=http://<your-LAN-IP>:5173andCORS_ORIGINS=http://<your-LAN-IP>:5173frontend/.env.local→VITE_API_URL=http://<your-LAN-IP>:8000/api- Run the backend on all interfaces:
uvicorn main:app --reload --host 0.0.0.0 --port 8000(Vite is already exposed viaserver.host: true). Phone must share the Wi-Fi; allow the macOS firewall prompt. - Deploy: swap
QR_BASE_URLto the deploy URL and removefrontend/.env.local.
Key routes
| Area | Frontend | Notable API |
|---|---|---|
| Library / PLM | /, /upload, /search, /review, /boards, /analytics, /ingest |
POST /api/garments/upload, POST /api/plm/next-style-number, POST /api/plm/{id}/qr, GET /api/plm/{id}/hangtag.png |
| QR scan landing | /g/:style (public) |
GET /api/plm/scan/{style} |
| TNA | /tna, /tna/all, /tna/board, /tna/{style}/pert, /tna/lifecycle/:lot |
GET /api/tna/line, /api/tna/watchdog, /api/tna/orders/{style}/pert |
| Moodboard / Trends | /moodboard, /scraper |
POST /api/moodboard/decode, POST /api/scraper/run |
| Admin | /admin/data (Ajay only) |
GET /api/admin/tables |
Full interactive docs: http://localhost:8000/docs
Project structure
backend/
main.py FastAPI app, CORS, static files, startup sync
config.py pydantic-settings (.env): API keys, thresholds, qr_base_url, cors_origins
models/ garment (+ style_counters), tna_stitch, collection, moodboard, trend, user, …
services/ tagging · embedding · similarity · search · plm (numbering + QR) · stitch · wfx · cascade · pert · …
routers/ garments · plm · search · review · ingest · moodboard · scraper · tna · collections · auth · admin
migrate_*.py one-off idempotent schema migrations (e.g. migrate_plm.py)
frontend/src/
pages/ Library · Upload · Search · Review · Boards · Moodboard · Scraper · Analytics · Ingest · GarmentScan · TNA* · Admin
components/ library/* (cards, detail modal), tna/* (LifecycleTimeline, charts), editorial/*
api/client.ts all API calls
plans/ STATUS.md (system of record) + design/plan docs + revert snapshots
Known limitations (POC scope)
- Images on local filesystem (
images_path) — move to object storage for production. - SQLite single-writer — move to Postgres for concurrent multi-user writes.
- ChromaDB in-process — swap for a managed vector DB at scale.
- QR target depends on
QR_BASE_URL; the scan landing is intentionally public (un-authenticated) so phones resolve it. - TNA write-back to Stitch is not yet available (no TNA-create endpoint confirmed); the recommender outputs into our layer for now.