System Architecture

Full-stack Cloudflare edge architecture: Workers + D1 + KV + R2 + DO + Queues + AI + Vectorize. Zero cold starts, globally distributed.

Deployment Topology

                    ┌─────────────────────────────────────┐
                    │       societee.pages.dev             │
                    │   (React 19 SPA — Cloudflare Pages)  │
                    └──────────┬──────────────┬────────────┘
                               │              │
                    ┌──────────▼──────┐ ┌─────▼──────────────────┐
                    │ societee.       │ │ auth.societee.          │
                    │ workers.dev     │ │ workers.dev             │
                    │ (Hono API)      │ │ (OpenAuth Server)       │
                    └──────────┬──────┘ └─────┬──────────────────┘
                               │              │
              ┌────────────────┼──────────────┼────────────────┐
              │                │              │                │
    ┌─────────▼──┐  ┌─────────▼──┐  ┌────────▼──┐  ┌─────────▼──┐
    │ D1:        │  │ D1:        │  │ KV:       │  │ R2:        │
    │ societee-db│  │ auth-db    │  │ KV_CACHE  │  │ societee-  │
    │ (113 tbls) │  │ (users)    │  │ AUTH_STORE│  │ vault      │
    └────────────┘  └────────────┘  └───────────┘  └────────────┘
              │                │              │                │
    ┌─────────▼────────────────▼──────────────▼────────────────▼──┐
    │                    Cloudflare Edge                           │
    │  Queues (async tasks)  ·  Workers AI (7 agents)            │
    │  Vectorize (RAG index)  ·  DO (GateSync + SOS broadcast)   │
    └────────────────────────────────────────────────────────────┘

Cloudflare Resources

ResourceNamePurpose
D1 Databasesocietee-db113 tables — all app data (societies, users, billing, accounting, complaints, etc.)
D1 Databasesocietee-auth-dbOpenAuth user records, sessions, refresh tokens
KV NamespaceKV_CACHERate limiting, session store, feature flag cache (5-min TTL), RBAC permission cache
KV NamespaceAUTH_STORAGEOpenAuth token storage, authorization codes
R2 Bucketsocietee-vaultInvoices, receipts, documents, profile photos, feed media
Queuesocietee-events-queueAsync billing runs, notification dispatch, audit log writes
Vectorizesocietee-rag-indexRAG embedding index for bylaws, policies, legal documents
Workers AI(built-in)7 AI agents: accountant, secretary, compliance, communication, analytics, gatekeeper, emergency
Durable ObjectGateSyncDOReal-time WebSocket hub for guard terminal sync (368 lines)
Durable ObjectEmergencySosDOEmergency SOS broadcast hub (377 lines)

Middleware Pipeline

Applied globally in order (from src/index.ts):

1. Security Headers      — CSP nonce, HSTS, X-Frame-Options DENY
2. Output Sanitization   — Auto-strip PII from responses
3. Audit Logger          — Immutable hash-chain audit trail for all mutations
4. Request Logger        — Request ID, timing, correlation
5. Multi-Tenant Isolation— X-Tenant-ID / X-Society-ID header extraction
6. JWT Auth + ABAC       — Applied per-route-group
7. Request Signing       — HMAC-SHA256 nonce + timestamp
8. Anomaly Detection     — 6-signal behavioral analysis
9. Global Error Handler  — Catch-all with error sanitization

Request Flow

Client Request (Authorization: Bearer <jwt>, X-Tenant-ID: <society_id>)
    │
    ├─→ Security Headers middleware
    ├─→ Output Sanitization middleware
    ├─→ Audit Logger middleware
    ├─→ Request Logger middleware
    ├─→ Multi-Tenant Isolation (extracts society_id)
    │
    ├─→ authMiddleware() — verifies JWT, loads user + roles + permissions
    ├─→ abacMiddleware() — checks ABAC conditions
    │
    ├─→ enhancedRateLimit('READ'|'WRITE') — per-user + per-IP
    ├─→ requireFeature('feature.key') — checks society_features table (KV-cached)
    │
    ├─→ Route Handler (Hono)
    │   ├─→ Zod schema validation
    │   ├─→ D1 query (all queries bound to society_id)
    │   └─→ Response with PII sanitized
    │
    └─→ Response (Access-Control-Allow-Origin: *, security headers)

Multi-Tenancy

Every single D1 table includes a society_id TEXT NOT NULL foreign key. Every query is scoped by this. The tenant ID is extracted from the X-Tenant-ID or X-Society-ID request header by the Multi-Tenant Isolation middleware.

-- Every query is automatically scoped
SELECT * FROM invoices WHERE society_id = ? AND status = 'OVERDUE'

-- Middleware extracts tenant from header
const societyId = c.get('tenantId') || c.get('user')?.activeContext?.tenantId

Real-Time Architecture

GateSyncDO (368 lines)
WebSocket hub for guard terminal real-time sync. Handles: visitor entry/exit events, ANPR readings, boom barrier signals, overstay alerts. All guards in a society connect to the same DO instance.
EmergencySosDO (377 lines)
Emergency SOS broadcast hub. Handles: SOS trigger from residents/guards, guard acknowledgment, resolution, lockdown broadcast, active alarm management. Geofenced per society.

Authentication Flow

┌─────────────────────────────────────────────────────────────┐
│                    AUTHENTICATION OPTIONS                     │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Option A: OpenAuth (primary)                               │
│  ─────────────────────────                                  │
│  1. Frontend redirects to auth.societee.workers.dev         │
│  2. User logs in via email + verification code              │
│  3. OpenAuth looks up/creates user in societee-db           │
│  4. Returns JWT: { id, email, name }                        │
│  5. Frontend stores access_token + refresh_token            │
│  6. Backend verifies via OpenAuth JWKS endpoint             │
│                                                              │
│  Option B: PBKDF2 (legacy/fallback)                        │
│  ─────────────────────────────────                          │
│  1. POST /v1/auth/login with email + password               │
│  2. PBKDF2 (SHA-256, 100K iterations) password verify       │
│  3. HMAC-SHA256 JWT signed (15min access, 7d refresh)       │
│  4. Refresh token rotation on /v1/auth/refresh              │
│                                                              │
│  Both paths populate: roles, permissions, persona, context  │
└─────────────────────────────────────────────────────────────┘

Persona System

JWT contains active_context (persona_id, tenant_id, role, unit_id, permissions) + available_contexts array. Persona switching via X-Societee-Persona-ID header or /v1/auth/switch-persona endpoint. Frontend stores mode in localStorage('societee_mode') as 'resident' | 'official'.

AI Agent Architecture

7 specialized AI agents dispatched via Cloudflare Workers AI. Each agent has a dedicated prompt template, access to specific tools, and can request human approval before executing actions.

POST /v1/ai/copilot/swarm
Body: { "query": "Summarize all overdue invoices above ₹5000" }
Response: {
  "agent": "accountant",
  "response": "Found 12 overdue invoices totaling ₹1,24,500...",
  "sources": ["invoices table", "payment history"]
}

Edge Latency Profile

OperationLocationExpected Latency
JWT verificationEdge Worker< 5ms
D1 read queryEdge (nearest replica)5-15ms
KV cache hitEdge (global)< 5ms
R2 presigned URLEdge Worker< 10ms
Workers AI inferenceEdge100-500ms
Full API request (auth + query + response)Edge15-50ms
WebSocket DO messageEdge< 10ms