Architecture Overview
This document describes the system architecture of the C_AI Platform, a compliance intelligence platform for regulatory license readiness.
System Layers
┌─────────────────────────────────────────────────────────────┐
│ Client Layer │
│ React + Vite + TailwindCSS + Radix UI │
│ client/src/ │
├─────────────────────────────────────────────────────────────┤
│ API Layer │
│ Express REST API │
│ server/routes.ts │
├─────────────────────────────────────────────────────────────┤
│ Service Layer │
│ Assessment Pipeline | Pack Resolver | Vector Store │
│ server/lib/ │
├─────────────────────────────────────────────────────────────┤
│ Data Layer │
│ PostgreSQL + pgvector | Drizzle ORM │
│ shared/schema.ts | server/db.ts │
├─────────────────────────────────────────────────────────────┤
│ Observability Layer │
│ OpenTelemetry → Phoenix (Arize) │
│ server/lib/tracing.ts │
└─────────────────────────────────────────────────────────────┘
Key Directories
| Directory | Purpose | Key Files |
|---|---|---|
client/src/ | React frontend | App.tsx, pages/, components/ |
server/ | Express backend | routes.ts, storage.ts, db.ts |
server/lib/ | Business logic services | assessmentPipeline.ts, packResolver.ts |
shared/ | Shared types and schema | schema.ts, constants.ts |
docs-site/ | Documentation (Docusaurus) | docs/, docusaurus.config.ts |
(Verified: directory structure via ls command)
Core Subsystems
1. Evidence Ingestion Pipeline
Handles document upload, text extraction, chunking, and vector indexing.
Entry point: server/routes.ts → POST /api/documents/upload (line 88 defines 100MB limit)
Processing flow:
- Upload →
server/lib/evidenceStorage.tsstores file with SHA256 hash - Extract →
server/lib/contentExtractor.tsextracts text from PDF/DOCX/XLSX - Chunk →
server/lib/chunker.tssplits text into indexed segments - Embed →
server/lib/embeddings/openai.tsgenerates 1536-dimensional vectors - Index →
server/lib/vectorStore.tsstores embeddings in pgvector
Status enum: EvidenceStatus in shared/schema.ts:160-167 tracks lifecycle:
- UPLOADED → EXTRACTED → PARSED → INDEXED → READY (or FAILED)
2. Assessment Pipeline
Evaluates evidence against requirements using LLM and vector search.
Entry point: server/lib/assessmentPipeline.ts
Key functions:
startAssessmentRun()(line 92) - Creates run, resolves pack binding, processes requirementscheckForInProgressRun()(line 80) - Prevents concurrent runs per tenant
Processing per requirement:
- Generate embedding for requirement text
- Vector search for similar chunks (
server/lib/vectorStore.ts:59-80) - LLM evaluation with retrieved context (
server/lib/llmProvider.ts) - Store assessment with status, confidence, citations
Status enum: AssessmentStatus in shared/schema.ts:318-323:
- COMPLETE | PARTIAL | MISSING | FAILED
3. Pack Resolution System
Resolves effective configuration bindings for a tenant+pack+environment.
Entry point: server/lib/packResolver.ts
Key functions:
resolvePackBinding()(line 25) - Resolves criteria, corpus, engine bindingscreateRunSnapshot()(line 107) - Creates snapshot for deterministic replay
Resolved bindings (EffectivePackBinding interface, lines 12-23):
criteriaVersionId- Which criteria set version to usecorpusActivationId- Which regulatory corpus activationretrievalVersionId,promptVersionId,chunkingVersionId,agentVersionId- Engine configs
4. Tenant Isolation
All data operations are scoped by tenant_id.
Security helpers in server/routes.ts:107-172:
resolveTenantSecure()- Resolves tenant from session with security checksrequireTenant()- Express helper that returns 400/403 on missing/invalid tenant
Hard rules:
- No silent fallbacks - missing tenant returns error
- Query param override requires
SUPER_ADMIN_MODE=trueANDSUPER_ADMINrole - Every DB query must include
tenant_idin WHERE clause
5. Observability
Distributed tracing via OpenTelemetry exported to Phoenix (Arize).
Entry point: server/lib/tracing.ts
Key functions:
initTracing()(line 117) - Initializes OTLP exporterstartRunSpan()(line 178) - Creates root span for assessment runstartStepSpan()(line 197) - Creates child span for processing stepsrecordLLMCall()(line 305) - Records LLM usage metrics
Allowed attributes: Lines 7-47 define allowlist for trace attributes (prevents PII leakage)
Phoenix endpoint: Configured via PHOENIX_OTLP_ENDPOINT env var (default: http://localhost:6006/v1/traces)
Request Flow Example
User uploads document
│
▼
POST /api/documents/upload (server/routes.ts)
│
▼
uploadAndProcess() (server/lib/pipeline.ts)
│
├─► evidenceStorage.saveFile()
│
├─► contentExtractor.extract()
│
├─► chunker.chunk()
│
└─► vectorStore.storeEmbedding()
│
▼
Document status: READY
│
▼
User triggers assessment
│
▼
POST /api/runs (server/routes.ts)
│
▼
startAssessmentRun() (server/lib/assessmentPipeline.ts)
│
├─► resolvePackBinding() (server/lib/packResolver.ts)
│
├─► For each requirement:
│ ├─► vectorStore.searchSimilar()
│ ├─► llmProvider.evaluate()
│ └─► db.insert(assessments)
│
└─► captureReplaySnapshot() (server/lib/adminService.ts)
│
▼
Run status: COMPLETED
Database Architecture
See Data Model for full schema reference.
Key tables (defined in shared/schema.ts):
| Table | Purpose | Key Columns |
|---|---|---|
tenants (line 39) | Multi-tenant isolation | id, name |
packs (line 67) | Requirement packs | id, name, regulator_code |
documents (line 192) | Evidence files | tenant_id, status, sha256_hash |
chunks (line 236) | Text segments | document_id, content, token_count |
runs (line 330) | Assessment runs | tenant_id, pack_id, status, snapshot_* |
assessments (line 419) | Requirement evaluations | run_id, status, confidence, citations |
Environment Configuration
| Variable | Purpose | Default |
|---|---|---|
DATABASE_URL | PostgreSQL connection | Required |
OPENAI_API_KEY | Embeddings and LLM | Required |
PHOENIX_OTLP_ENDPOINT | Tracing endpoint | http://localhost:6006/v1/traces |
APP_ENVIRONMENT | DEV/STAGING/PROD | DEV |
SUPER_ADMIN_MODE | Enable cross-tenant access | false |
Legacy (internal identifier): the current codebase uses WALLY_ENVIRONMENT as the environment variable name.
(Verified: server/routes.ts:99, server/lib/tracing.ts:120, server/lib/assessmentPipeline.ts:118)
Related Pages
- Repository Map - Where to edit for common changes
- Data Model - Schema reference with tenant rules
- Determinism and Replay - Snapshot pinning for reproducibility
- Testing and Debugging - How to reproduce and trace runs