{"slug":"strategy/product-strategy/FIREBASE_ARCHITECTURE_SPEC","title":"Firebase Architecture Spec — SMB Layer","section":"strategy","sectionLabel":"Strategy","status":"unclassified","type":"document","path":"strategy/product-strategy/FIREBASE_ARCHITECTURE_SPEC.mdx","bytes":7857,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\n> Separate project. Integrates with main repo via API.\n> Context transfer this doc when ready to wire.\n\n---\n\n## PROJECT STRUCTURE\n\n```\nintegratewise-firebase/              ← SEPARATE REPO\n├── functions/                       ← Cloud Functions\n│   ├── src/\n│   │   ├── triggers/\n│   │   │   ├── onEntityWrite.ts     ← Twin trigger evaluation\n│   │   │   ├── onTriageCreate.ts    ← Genkit AI extraction\n│   │   │   ├── onApprovalUpdate.ts  ← Execute approved actions\n│   │   │   └── onConnectorSync.ts   ← Pipeline processing\n│   │   ├── api/\n│   │   │   ├── entity360.ts         ← Entity 360 assembly\n│   │   │   ├── connectors.ts        ← OAuth + sync\n│   │   │   └── triage.ts            ← Triage endpoints\n│   │   ├── ai/\n│   │   │   ├── triage-bot.ts        ← Genkit triage (Gemini)\n│   │   │   ├── memory-consolidator.ts\n│   │   │   └── twin-engine.ts       ← Twin trigger evaluation\n│   │   └── index.ts\n│   └── package.json\n├── firestore.rules                  ← Security rules (tenant isolation)\n├── firestore.indexes.json\n├── firebase.json\n└── .firebaserc\n```\n\n## FIRESTORE SCHEMA\n\n```\ntenants/{tenantId}/\n├── config/\n│   ├── schema          { domain, industry, entity_types[], priority_fields{} }\n│   ├── flow_c          { auto_approve_sources[], min_confidence, ... }\n│   └── triggers        { enabled_triggers[], max_per_day }\n│\n├── entities/{entityId}\n│   ├── entity_type: string\n│   ├── display_name: string\n│   ├── truth: { data{}, source, updated_at, freshness }\n│   ├── health_score: number\n│   ├── sources: string[]\n│   └── meta: { hydration_bucket, department }\n│\n├── context/{contextId}\n│   ├── entity_id: string\n│   ├── type: \"email\" | \"document\" | \"meeting\" | \"note\"\n│   ├── title: string\n│   ├── summary: string\n│   ├── source: string\n│   └── created_at: timestamp\n│\n├── signals/{signalId}\n│   ├── entity_id: string\n│   ├── type: string\n│   ├── severity: \"critical\" | \"high\" | \"medium\" | \"low\" | \"info\"\n│   ├── title: string\n│   ├── evidence: array\n│   ├── confidence: number\n│   └── status: \"active\" | \"resolved\"\n│\n├── memories/{memoryId}\n│   ├── entity_id: string\n│   ├── type: \"decision\" | \"preference\" | \"insight\" | \"action\" | \"rule\" | \"fact\"\n│   ├── content: string\n│   ├── confidence: number\n│   ├── source: string (which AI)\n│   ├── approved_by: string\n│   └── status: \"approved\" | \"revoked\"\n│\n├── triage/{triageId}\n│   ├── content: string\n│   ├── source: string (AI provider)\n│   ├── confidence: number\n│   ├── entities_mentioned: string[]\n│   ├── status: \"pending\" | \"approved\" | \"rejected\"\n│   ├── reviewed_by: string\n│   └── created_at: timestamp\n│\n├── insights/{insightId}\n│   ├── entity_id: string\n│   ├── trigger_id: string\n│   ├── severity: string\n│   ├── title: string\n│   ├── what: string\n│   ├── why: string\n│   ├── action: string\n│   ├── risk_if_ignored: string\n│   ├── evidence: array\n│   ├── confidence: number\n│   └── created_at: timestamp\n│\n├── approvals/{approvalId}\n│   ├── action_type: string\n│   ├── entity_id: string\n│   ├── proposed_by: string (system/AI)\n│   ├── status: \"pending\" | \"approved\" | \"rejected\"\n│   ├── reviewed_by: string\n│   ├── reason: string\n│   └── created_at: timestamp\n│\n├── connectors/{connectorId}\n│   ├── provider: string\n│   ├── status: \"connected\" | \"error\" | \"syncing\"\n│   ├── tokens: { encrypted }\n│   ├── last_sync: timestamp\n│   └── entity_count: number\n│\n└── audit/{auditId}\n    ├── action: string\n    ├── actor: string\n    ├── details: map\n    └── created_at: timestamp\n```\n\n## FIRESTORE SECURITY RULES\n\n```javascript\nrules_version = '2';\nservice cloud.firestore {\n  match /databases/{database}/documents {\n    // Tenant isolation — user can only access their tenant\n    match /tenants/{tenantId}/{document=**} {\n      allow read, write: if request.auth != null\n        && request.auth.token.tenant_id == tenantId;\n    }\n  }\n}\n```\n\n## CLOUD FUNCTIONS\n\n### onEntityWrite — Twin Trigger Evaluation\n\n```\nTrigger: Firestore onWrite on tenants/{tenantId}/entities/{entityId}\nLogic:\n  1. Read entity data (truth, context, signals, memory, goals)\n  2. Evaluate 10 Twin triggers\n  3. If triggered, write to tenants/{tenantId}/insights/{insightId}\n  4. Check max 3 insights/entity/day\n  5. Send FCM push notification if critical/high\n```\n\n### onTriageCreate — Genkit AI Extraction\n\n```\nTrigger: Firestore onCreate on tenants/{tenantId}/triage/{triageId}\nLogic:\n  1. Read triage content\n  2. Call Genkit with Gemini model\n  3. Extract: entities, sentiment, key facts, confidence\n  4. Check flow_c_config rules\n  5. If auto-approve: move to memories collection\n  6. If HITL: keep in triage with status \"pending\"\n  7. Send FCM notification for HITL review\n```\n\n### onApprovalUpdate — Execute Approved Actions\n\n```\nTrigger: Firestore onUpdate on tenants/{tenantId}/approvals/{approvalId}\nLogic:\n  1. Check if status changed to \"approved\"\n  2. Execute the approved action (merge, update, etc.)\n  3. Write to audit collection\n  4. Send FCM confirmation\n```\n\n## INTEGRATION WITH MAIN REPO\n\n```\nMain repo (Cloudflare)                Firebase project\n─────────────────────                 ─────────────────\nGateway Worker                   →    Firebase Cloud Functions (HTTP)\n  /api/v1/firebase/*                  Proxied to Firebase endpoints\n\nOR\n\nFrontend (apps/web)              →    Firebase SDK directly\n\nConnector Workers               →    Write to Firestore via Admin SDK\n  After pipeline processing,\n  write entity to Firestore\n  in addition to Spine DB\n```\n\n## WHAT STAYS ON CLOUDFLARE\n\n- Gateway (edge routing, CORS)\n- Connector OAuth flows (already built)\n- Static hosting (Cloudflare Pages)\n- Enterprise tenant data (Spine DB RLS for SQL queries)\n\n## WHAT MOVES TO FIREBASE\n\n- SMB auth (phone OTP)\n- SMB entity data (Firestore, real-time, offline)\n- Push notifications (FCM)\n- Triage bot (Genkit + Gemini)\n- Workflow triggers (Firestore triggers)\n- Analytics (Firebase Analytics)\n\n## CONTEXT TRANSFER TEMPLATE\n\nWhen Firebase project is ready, transfer this to main repo:\n\n```\nCONTEXT TRANSFER: Firebase Integration\n\nFirebase Project ID: [your-project-id]\nRegion: [asia-south1 for India, me-central1 for UAE]\n\nEndpoints:\n- Auth: Firebase Auth (phone OTP enabled)\n- Firestore: tenants/{tenantId}/entities, memories, triage, insights\n- Functions: onEntityWrite, onTriageCreate, onApprovalUpdate\n- FCM: configured for web + mobile push\n\nFrontend changes needed:\n1. Add firebase SDK to apps/web/package.json\n2. Initialize Firebase in apps/web/src/lib/firebase.ts\n3. Add Firestore hooks for real-time entity updates\n4. Add FCM service worker for push notifications\n5. Add phone OTP option to login page\n\nBackend changes needed:\n1. After pipeline S8 (sectorize), also write to Firestore\n2. Gateway proxy /api/v1/firebase/* to Cloud Functions\n3. Connector sync writes to both Spine DB and Firestore\n```\n"}