Hermes Agent 37f386eeba
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(azure): repoint prod CI to Azure VM + PyPI mirror for uv
- 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.*
2026-11-03 23:05:50 +05:30

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:

  1. 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.
  2. 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.md is 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:

  1. backend/.env → QR_BASE_URL=http://<your-LAN-IP>:5173 and CORS_ORIGINS=http://<your-LAN-IP>:5173
  2. frontend/.env.local → VITE_API_URL=http://<your-LAN-IP>:8000/api
  3. Run the backend on all interfaces: uvicorn main:app --reload --host 0.0.0.0 --port 8000 (Vite is already exposed via server.host: true). Phone must share the Wi-Fi; allow the macOS firewall prompt.
  4. Deploy: swap QR_BASE_URL to the deploy URL and remove frontend/.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.
S
Description
No description provided
Readme
92 MiB
Languages
Python 81.8%
TypeScript 15.9%
JavaScript 1.8%
CSS 0.4%