CI/CD Pipeline / lint-and-test (pull_request) Successful in 2m46s
CI/CD Pipeline / backend-unit-tests (pull_request) Successful in 34m42s
CI/CD Pipeline / deploy (pull_request) Skipped
CI/CD Pipeline / Publish release notes + notify users (pull_request) Skipped
Semgrep SAST / Static Security Scan (pull_request) Successful in 38s
- ci.yml deploy: run on the Azure VM host (/opt/sapl/prod, hermes git auth, apk mirror loop, BusyBox-safe ownership restore) - backend/Dockerfile: UV_DEFAULT_INDEX -> Tsinghua mirror (pypi.org flaps from Azure, broke backend builds twice) - docs: Gitea URL -> git.*
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 style number + fabric quality + 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.