Twill Engineering Patterns

For Dash

Read this before starting any implementation. Add new patterns as you discover them.

Stack

LayerTechnologyRepoNotes
BackendPython / FastAPIfacadeREST API, JWT auth, PostgreSQL
FrontendReact / Next.jstwill-ai-uiTypeScript, Tailwind
AI/LLMPython / Azure OpenAItwill-llm-engineLangChain, vector search
InfraDocker / CloudflareiacAzure hosting, CF Tunnel
DatabasePostgreSQL 15Via 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 detail field
  • 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_id foreign 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 staging branch
  • Prod: manual trigger after staging validation
  • Rollback: revert commit + redeploy (no blue/green yet)

Known Gotchas

Multi-tenant data isolation

Always filter by partner_id or merchant_id in 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.