Appearance
System Architecture
Component overview and data flow
Component summary
| Component | Role |
|---|---|
| CX Console | Request intake, clarification prompts, confirmation screen, live progress view, final summary and recovery actions |
| Interpreter Action | Convex action (Node.js runtime) that calls OpenRouter to classify the request as a bulk operation or a policy question, grounds answers in KB articles via vector search, and returns structured intent or a Q&A response |
| Job Mutations | createDraft resolves target cards, runs the policy engine, and writes a preview job; confirmJob fans out per-item execution tasks via the Convex scheduler; cancelJob and retryFailed handle lifecycle transitions |
| Policy Rules Engine | Deterministic TypeScript function — enforces limit caps (SGD 5 000 max), excludes frozen/cancelled cards, gates >25-card ops behind approval, hard-blocks >200 items. No LLM involved |
| Executor Actions | Convex internalActions that call the (simulated) card API per item, mark outcomes, and re-schedule retries with exponential backoff via the Convex scheduler |
| Convex Scheduler | Built-in durable scheduler — replaces Redis + Celery. Handles staggered fan-out on confirm and exponential backoff on transient failures. All scheduled function IDs are stored so queued items can be cancelled |
| Live Queries | Convex reactive queries push job and item state to the UI in real time — no polling or SSE plumbing required |
| Convex Database | Managed transactional store for jobs, job_items, mock_cards, KB articles (with 1 536-dim vector index), feedback, and metrics events |
| KB / RAG | Reap Help Center articles embedded with OpenAI text-embedding-3-small (via OpenRouter), stored in Convex's built-in vector index. Semantic search runs at request time to ground policy Q&A answers |
Synchronous vs Asynchronous boundary
| Synchronous (user waits) | Asynchronous (background, live-push) |
|---|---|
| Request acknowledgment | Per-card update execution |
| Intent extraction + KB search | Retry logic with exponential backoff |
| Entity resolution + policy check | Job count aggregation after each item |
| Plan generation + confirmation screen | Job status transitions (in_progress → completed) |
| Job receipt (returned immediately on confirm) | Progress updates (Convex live subscriptions, no polling) |
Actual tech stack — built in Dispatch
This is what was actually shipped. The stack below reflects the Dispatch prototype built for this assessment — not a hypothetical recommendation.
| Layer | What we built with | Why |
|---|---|---|
| Frontend | Next.js / React · TypeScript · Tailwind CSS v4 | App Router + Server Components for fast internal tooling; TypeScript strict mode throughout |
| Unified backend | Convex (mutations · actions · scheduler · live queries · vector search) | Replaces FastAPI + Redis + Celery + Postgres in one layer — real-time subscriptions, durable background tasks, and a transactional database with zero extra infrastructure. Job status updates arrive automatically via reactive queries |
| AI pipeline | OpenRouter → openai/gpt-5.4-mini (intent + Q&A) · text-embedding-3-small (KB embeddings) | Single API key for both chat and embeddings; fast and cheap for structured JSON extraction; temperature 0 for deterministic intent output |
| Policy enforcement | Deterministic TypeScript — src/lib/policy.ts | Hard rules (limit caps, excluded statuses, approval thresholds, item-count maximums) require no LLM — deterministic code is cheaper, faster, and auditable |
| Async execution | Convex Scheduler (ctx.scheduler.runAfter) | Durable fan-out on job confirm; exponential backoff on transient failures; scheduled function IDs stored on each item so queued items can be cancelled cleanly |
| Storage | Convex managed database · Convex vector index (1 536-dim) | Transactional writes for jobs and items; vector index for KB semantic search — no separate Postgres or pgvector instance needed |
| Testing | Vitest (unit + integration) · Playwright (E2E) | Unit tests cover policy logic and executor retry behaviour; E2E tests cover the confirmation and progress screens end-to-end |