Twill Engineering Patterns
For Dash
Read this before starting any implementation. Add new patterns as you discover them.
Stack
| Layer | Technology | Repo | Notes |
|---|---|---|---|
| Backend | Python / FastAPI | facade | REST API, JWT auth, PostgreSQL |
| Frontend | React / Next.js | twill-ai-ui | TypeScript, Tailwind |
| AI/LLM | Python / Azure OpenAI | twill-llm-engine | LangChain, vector search |
| Infra | Docker / Cloudflare | iac | Azure hosting, CF Tunnel |
| Database | PostgreSQL 15 | — | Via facade, Supabase connection |
Active Epics (facade)
None found
Auth Pattern
- JWT tokens issued by facade
- Frontend stores token, sends in
Authorization: Bearer <token>header - Facade validates on every request
- Multi-tenant: each partner/merchant has isolated data scope
API Design Pattern
- FastAPI routers organized by domain (merchants, partners, payments, etc.)
- Response models use Pydantic
- Errors return structured JSON with
detailfield - Pagination: cursor-based for large collections
Frontend Patterns
- React Query for data fetching + caching
- Component library: custom (no external UI lib — design system is internal)
- Widget system: dashboard widgets are composable, configurable units
- Notifications: WebSocket-based real-time updates
Database Patterns
- Migrations via Alembic
- Multi-tenant isolation via
partner_id/merchant_idforeign keys - Soft deletes (no hard DELETE on core entities)
- Activity logging on all merchant state changes
LLM Patterns
- SQL generation: LLM generates SQL → validated → executed against merchant’s data
- Widget generation: LLM generates widget config → frontend renders
- Context: merchant schema + recent data provided as LLM context
- Error handling: SQL errors fed back to LLM for retry (max 2 attempts)
Testing Pattern
- Backend: pytest, fixtures per module
- Frontend: Playwright for E2E, Jest for unit
- QA sign-off required before merge (Dash runs this before pushing)
Deployment
- Staging: auto-deploy on push to
stagingbranch - Prod: manual trigger after staging validation
- Rollback: revert commit + redeploy (no blue/green yet)
Known Gotchas
Multi-tenant data isolation
Always filter by
partner_idormerchant_idin every query. Missing this = data leak between tenants.
JWT expiry handling
Frontend must handle 401 responses by refreshing token. Several issues (#411, etc.) relate to this.
WebSocket connections
Long-running WS connections drop silently on Azure — always implement client-side reconnect.