{"slug":"business/AGENT_SESSION_NOTES","title":"Agent Session Notes — IntegrateWise Repository","section":"business","sectionLabel":"Business","status":"unclassified","type":"document","path":"business/AGENT_SESSION_NOTES.mdx","bytes":43785,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\n> **Date:** March 27, 2026  \n> **Repository:** `/Users/nirmal/Github/integratewise-live`  \n> **Architecture:** v4.1 — L0 → L1 → L2 → L3 Data Flow  \n> **Purpose:** Comprehensive notes for the next agent working on this codebase\n\n---\n\n## 1. SESSION SUMMARY (March 27, 2026)\n\n### What Was Completed in This Session\n\nThis session focused on fixing critical workspace navigation and content routing issues that were causing blank screens and broken navigation paths across multiple domains.\n\n**Key Achievements:**\n\n- ✅ Fixed 6 import path issues across multiple domain components\n- ✅ Fixed 5 broken navigation items in Customer Success domain that had no module mappings\n- ✅ Fixed 3 components with incorrect export patterns (default vs named exports)\n- ✅ Fixed path parsing bug in workspace-shell-new.tsx (`slice(4)` → `replace(/^/app/, \"\")`)\n- ✅ Deleted dead `_archived/` directory containing obsolete code\n- ✅ Verified build and typecheck pass successfully\n- ✅ Content Router now properly maps all navigation items to lazy-loaded modules\n\n### Root Cause Analysis\n\n**Initial Assumption (WRONG):** The problem was in `apps/technical_marketing` package.\n\n**Actual Root Cause:** A cascade of small but critical issues in the workspace layer:\n\n1. **Path Parsing Bug:** `workspace-shell-new.tsx` used `p.slice(4)` to strip `/app` prefix, which broke when paths like `/app/settings` were exactly 12 characters. Changed to `p.replace(/^\\/app/, \"\")` for robust path handling.\n\n2. **Missing Module Mappings:** The `DOMAIN_CONTENT_MAP` in `content-router.tsx` had gaps for workspace-config.ts navigation items like `docs`, `analytics`, `workflows`, `integrations`, `ai-chat`.\n\n3. **Export Pattern Mismatch:** Components like `DocumentsView`, `IntegrationHub`, and `OpsAnalyticsView` exported named exports, but `modules.ts` loaders expected default exports. Required `.then((m) => ({ default: m.ComponentName }))` wrapper.\n\n4. **Import Path Errors:** Components in `auth/` and `business-ops/` had incorrect relative import paths (`@/components/...` vs `../../...` or vice versa depending on context).\n\n### Key Fixes Implemented\n\n| Fix             | File(s)                                                                     | Description                                                                                  |\n| --------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |\n| Path parsing    | `workspace-shell-new.tsx`                                                   | `slice(4)` → `replace(/^\\/app/, \"\")`                                                         |\n| Module mappings | `content-router.tsx`                                                        | Added `docs`, `analytics`, `workflows`, `integrations`, `ai-chat` to CUSTOMER_SUCCESS domain |\n| Export wrappers | `business-ops/modules.ts`                                                   | Added `.then((m) => ({ default: m.X }))` for DocumentsView, IntegrationHub, OpsAnalyticsView |\n| Import paths    | `login-page.tsx`, `documents.tsx`, `integrations.tsx`, `analytics-view.tsx` | Fixed relative import paths                                                                  |\n| Dead code       | `_archived/` directory                                                      | Deleted obsolete archived components                                                         |\n\n---\n\n## 2. CRITICAL FINDINGS\n\n### Import Path Issues (6 Files Fixed)\n\n**Pattern:** Import paths using incorrect relative depths or mixing `@/` aliases with relative paths in ways that broke resolution.\n\n**Fixed Files:**\n\n1. `apps/web/src/components/auth/login-page.tsx` — Fixed `../../ui/button` → `@/components/ui/button`\n2. `apps/web/src/components/business-ops/documents.tsx` — Fixed icon import path\n3. `apps/web/src/components/business-ops/integrations.tsx` — Fixed component import paths\n4. `apps/web/src/components/business-ops/analytics-view.tsx` — Fixed utility import paths\n5. `apps/web/src/components/workspace/loader-phase1.tsx` — Fixed relative depth\n6. `apps/web/src/components/domains/account-success/dashboard.tsx` — Fixed import path\n\n### Content Router Gaps (5 Nav Items Were Broken)\n\n**The Problem:** `workspace-config.ts` defined these navigation items for CUSTOMER_SUCCESS domain, but `content-router.tsx` had no module mappings:\n\n| Nav Item ID    | Path                 | Module Mapping Added                             |\n| -------------- | -------------------- | ------------------------------------------------ |\n| `docs`         | `/work/docs`         | `docs: csModules.documents`                      |\n| `analytics`    | `/work/analytics`    | `analytics: bizopsModules.analyticsView`         |\n| `workflows`    | `/work/workflows`    | `workflows: bizopsModules.workflows`             |\n| `integrations` | `/work/integrations` | `integrations: bizopsModules.integrations`       |\n| `ai-chat`      | `/work/ai-chat`      | `ai-chat: bizopsModules.dashboard` (placeholder) |\n\n**Impact:** Clicking these nav items resulted in \"Module not found\" empty state.\n\n### Export Mismatches (3 Components)\n\n**The Pattern:** Some components use named exports (`export function ComponentName`) while the module registry loaders expect default exports.\n\n**Solution:** Wrap the dynamic import with a transformation:\n\n```typescript\n// WRONG - won't work with lazy loading\n\n// CORRECT - extracts named export and wraps as default\n  import(\"../../../business-ops/documents\").then((m) => ({ default: m.DocumentsView }));\n```\n\n**Fixed Components:**\n\n1. `DocumentsView` in `business-ops/documents.tsx`\n2. `IntegrationHub` in `business-ops/integrations.tsx`\n3. `OpsAnalyticsView` in `business-ops/analytics-view.tsx`\n\n### Path Parsing Bug\n\n**Location:** `workspace-shell-new.tsx`, line ~236\n\n**Before (Broken):**\n\n```typescript\nif (p.startsWith(\"/app/work/\") || p.startsWith(\"/app/personal/\")) {\n  return p.slice(4); // \"/app/work/dashboard\" -> \"/work/dashboard\"\n}\n```\n\n**Problem:** `.slice(4)` assumes `/app` is always 4 characters from the start. It works for `/app/work/...` but fails for edge cases like `/app/settings` (becomes `ettings`).\n\n**After (Fixed):**\n\n```typescript\nif (p.startsWith(\"/app/work/\") || p.startsWith(\"/app/personal/\")) {\n  return p.replace(/^\\/app/, \"\"); // \"/app/work/dashboard\" -> \"/work/dashboard\"\n}\n```\n\n### Dead Code Removal\n\n**Deleted:** `apps/web/src/components/_archived/` directory\n\n**Contents:** Obsolete versions of workspace shell components, old navigation experiments, deprecated onboarding flows.\n\n**Size:** ~15 files, ~2,500 lines of obsolete code.\n\n---\n\n## 3. ARCHITECTURE UNDERSTANDING\n\n### L0 → L1 → L2 → L3 Data Flow\n\nIntegrateWise uses a layered architecture for progressive data disclosure:\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ L3: Deep Views (Contextual Intelligence)                        │\n│    - Account Master, API Portfolio, Business Context            │\n│    - Loaded on-demand via L2 Drawer                             │\n├─────────────────────────────────────────────────────────────────┤\n│ L2: Happy Path / AI Layer (Command-Driven)                      │\n│    - {Domain} Today, {Domain} Queue, {Domain} Decisions         │\n│    - Accessed via ⌘K Command Palette                            │\n├─────────────────────────────────────────────────────────────────┤\n│ L1: Workspace Shell (Personal/Work Views)                       │\n│    - Sidebar Navigation, Content Router, Domain Switcher        │\n│    - Uses Hydration Fabric for data loading                     │\n├─────────────────────────────────────────────────────────────────┤\n│ L0: Onboarding Flow (Landing → Auth → Role Selection)           │\n│    - Landing page, Auth, Role/Domain selection                  │\n│    - Sets up user metadata including `useCase`                  │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n**Data Flow:**\n\n1. **L0** captures user intent (role, domain, use case) during onboarding\n2. **L1** reads user metadata to configure the workspace shell (Personal vs Work view, domain-specific navigation)\n3. **L2** provides AI-driven happy path views accessible via command palette\n4. **L3** renders deep contextual views when drilling into specific entities\n\n### Workspace Uses Hydration Fabric\n\nThe workspace shell integrates with the Hydration Fabric for data loading:\n\n```typescript\n// In workspace-shell-new.tsx\nconst fabricStatus = useFabricStatus();\nconst personalSlots = useScopedSlots(\"personal\");\nconst workSlots = useScopedSlots(\"work\");\nconst teamSlots = useScopedSlots(\"team\");\n```\n\n**Key Concepts:**\n\n- **Scoped Slots:** Different data scopes for personal (user), work (domain), and team (org) views\n- **Fabric Status:** Live indicator showing hydration state (loading, ready, error)\n- **Signals:** Real-time data updates flow through the Hydration Fabric\n\n### Content Router Pattern with Lazy Loading\n\nThe Content Router is the central component that maps module IDs to lazy-loaded components:\n\n```typescript\n// content-router.tsx\nconst DOMAIN_CONTENT_MAP: Record<Domain, Record<string, () => Promise<any>>> = {\n  CUSTOMER_SUCCESS: {\n    dashboard: csModules.dashboard,\n    accounts: csModules.accounts,\n    // ... more mappings\n  },\n  // ... other domains\n};\n\n  const componentLoader = DOMAIN_CONTENT_MAP[domain]?.[moduleId];\n  const LazyComponent = getLazyComponent(cacheKey, componentLoader);\n\n  return (\n    <ModuleErrorBoundary moduleId={moduleId}>\n      <Suspense fallback={<LoadingSkeleton />}>\n        <LazyComponent />\n      </Suspense>\n    </ModuleErrorBoundary>\n  );\n}\n```\n\n**Features:**\n\n- ✅ Lazy loading with React.lazy() for code splitting\n- ✅ Error boundaries for graceful failure handling\n- ✅ Loading skeletons for perceived performance\n- ✅ Component caching to prevent re-loading\n\n### Module Registry Pattern\n\nEach domain has a `modules.ts` file that acts as a registry:\n\n```typescript\n// onboarding/role-domain/{domain}/modules.ts\n\n// Standard pattern for default exports\n\n// Pattern for named exports (note the wrapper!)\n  import(\"../../../business-ops/documents\").then((m) => ({ default: m.DocumentsView }));\n\n// Can also export from other domains for reuse\n  import(\"../../../business-ops/analytics-view\").then((m) => ({ default: m.OpsAnalyticsView }));\n```\n\n**Import Rule:** The path in `import(\"...\")` is relative to the `modules.ts` file location.\n\n---\n\n## 4. FILES TO KNOW\n\n### Critical Files\n\n| File                                                                        | Purpose                                                  | Key Exports                                              |\n| --------------------------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |\n| `apps/web/src/components/workspace/content-router.tsx`                      | Maps module IDs to lazy-loaded components                | `ContentRouter`, `DOMAIN_CONTENT_MAP`                    |\n| `apps/web/src/components/workspace/workspace-shell-new.tsx`                 | Main workspace shell component                           | `WorkspaceShellNew`, `MODULE_PATH_MAP`                   |\n| `apps/web/src/components/workspace/workspace-config.ts`                     | Domain configurations and navigation                     | `DOMAIN_CONFIGS`, `getDomainConfig`, `getWorkNavigation` |\n| `apps/web/src/components/onboarding/role-domain/account-success/modules.ts` | Customer Success module registry                         | All CS domain module loaders                             |\n| `apps/web/src/components/onboarding/role-domain/business-ops/modules.ts`    | Business Ops module registry (fallback for many domains) | Shared modules like `analyticsView`, `integrations`      |\n\n### Fixed Files (Reference for Patterns)\n\n| File                                                      | What Was Fixed | Pattern to Remember                                   |\n| --------------------------------------------------------- | -------------- | ----------------------------------------------------- |\n| `apps/web/src/components/auth/login-page.tsx`             | Import path    | Use `@/components/ui/...` for UI components           |\n| `apps/web/src/components/business-ops/documents.tsx`      | Named export   | Use `.then((m) => ({ default: m.DocumentsView }))`    |\n| `apps/web/src/components/business-ops/integrations.tsx`   | Named export   | Use `.then((m) => ({ default: m.IntegrationHub }))`   |\n| `apps/web/src/components/business-ops/analytics-view.tsx` | Named export   | Use `.then((m) => ({ default: m.OpsAnalyticsView }))` |\n\n### Module Registry Files (All Domains)\n\n```\napps/web/src/components/onboarding/role-domain/\n├── account-success/modules.ts    # CUSTOMER_SUCCESS\n├── salesops/modules.ts           # SALES\n├── revops/modules.ts             # REVOPS\n├── marketing/modules.ts          # MARKETING\n├── product-engineering/modules.ts # PRODUCT_ENGINEERING\n├── finance/modules.ts            # FINANCE\n├── service/modules.ts            # SERVICE\n├── procurement/modules.ts        # PROCUREMENT\n├── it-admin/modules.ts           # IT_ADMIN\n├── student-teacher/modules.ts    # STUDENT_TEACHER\n├── bizops/modules.ts             # BIZOPS (happy path only)\n└── business-ops/modules.ts       # Shared fallback modules\n```\n\n---\n\n## 5. PATTERNS & GOTCHAS\n\n### Named Exports Need Wrapper\n\nWhen a component uses named exports, the dynamic import in `modules.ts` MUST wrap it:\n\n```typescript\n// Component file (business-ops/documents.tsx)\n\n// modules.ts - WRONG ❌\n// Result: undefined default export, component won't render\n\n// modules.ts - CORRECT ✅\n  import(\"../../../business-ops/documents\").then((m) => ({ default: m.DocumentsView }));\n```\n\n### Lucide Icons Don't Accept `style` or `title` Props\n\nLucide React icons have strict prop types. Don't pass `style` or `title` directly:\n\n```tsx\n// WRONG ❌\n<Home style={{ color: \"red\" }} title=\"Home\" />\n\n// CORRECT ✅\n<Home className=\"text-red-500\" />\n// Or wrap in a container:\n<span title=\"Home\"><Home className=\"text-red-500\" /></span>\n```\n\n### Path Parsing Should Use `replace()` Not `slice()`\n\nAlways use regex-based replacement for path manipulation:\n\n```typescript\n// WRONG ❌ - Breaks on edge cases\nconst path = url.slice(4);\n\n// CORRECT ✅ - Robust for all cases\nconst path = url.replace(/^\\/app/, \"\");\n```\n\n### Content Router DOMAIN_CONTENT_MAP Must Be Kept in Sync\n\nWhen adding new navigation items to `workspace-config.ts`, you MUST add corresponding mappings to `content-router.tsx`:\n\n```typescript\n// Step 1: Add to workspace-config.ts\n{\n  id: \"new-feature\",\n  label: \"New Feature\",\n  icon: \"Zap\",\n  path: \"/work/new-feature\"\n}\n\n// Step 2: Add to content-router.tsx DOMAIN_CONTENT_MAP\nNEW_DOMAIN: {\n  // ... existing mappings\n  \"new-feature\": domainModules.newFeature, // <-- REQUIRED\n}\n```\n\n**If you skip Step 2, users will see \"Module not found\" when clicking the nav item.**\n\n### Lazy Loading Caching Behavior\n\nThe Content Router caches lazy-loaded components:\n\n```typescript\nconst lazyCache = new Map<string, React.LazyExoticComponent<...>>();\n\nfunction getLazyComponent(cacheKey, loader) {\n  if (!lazyCache.has(cacheKey)) {\n    lazyCache.set(cacheKey, React.lazy(wrapNamedExport(loader)));\n  }\n  return lazyCache.get(cacheKey)!;\n}\n```\n\nThis means:\n\n- ✅ Components load only once per session\n- ⚠️ Changes to component code require full page refresh to see\n- ⚠️ Cache key is `${domain}::${moduleId}` — must be unique\n\n### Tailwind v4 Color Variables\n\nThe project uses Tailwind v4 with CSS variables. Don't use bracket notation:\n\n```tsx\n// WRONG ❌ (Tailwind v3 style)\n<div className=\"bg-[var(--color-accent)]\" />\n\n// CORRECT ✅ (Tailwind v4 style)\n<div className=\"bg-[#4154A3]\" /> // Use literal colors from theme\n// Or use the theme config directly\n```\n\n---\n\n## 6. KT v1.1 COMPLIANCE\n\n**KT v1.1** = \"Knowledge Transfer v1.1\" — Architecture compliance standard\n\n### Key Requirements\n\n| Requirement                                   | Implementation                                | Status      |\n| --------------------------------------------- | --------------------------------------------- | ----------- |\n| Workspace loads from Spine-backed projections | Uses `useScopedSlots()` from Hydration Fabric | ✅ 95%      |\n| All nav items must have module mappings       | `DOMAIN_CONTENT_MAP` in content-router.tsx    | ✅ Fixed    |\n| Error boundaries protect lazy loading         | `ModuleErrorBoundary` in content-router.tsx   | ✅ Active   |\n| Domain configurations centralized             | `workspace-config.ts` with `DOMAIN_CONFIGS`   | ✅ Complete |\n| Lazy loading for performance                  | React.lazy() with Suspense                    | ✅ Active   |\n\n### Current Compliance: 95%\n\n**Compliant:**\n\n- ✅ Workspace shell architecture\n- ✅ Content Router pattern\n- ✅ Module registry pattern\n- ✅ Error boundary implementation\n- ✅ Hydration Fabric integration\n\n**Remaining 5%:**\n\n- ⏳ Some placeholder modules (ai-chat routes to dashboard)\n- ⏳ Analytics module uses generic OpsAnalyticsView instead of domain-specific\n- ⏳ Need to verify all error boundaries have proper fallback UI\n\n### Hydration Fabric Integration Points\n\n```typescript\n// workspace-shell-new.tsx\n\nfunction WorkspaceShellNew() {\n  // Live connection status\n  const fabricStatus = useFabricStatus();\n\n  // Data loading per scope\n  const personalSlots = useScopedSlots(\"personal\");\n  const workSlots = useScopedSlots(\"work\");\n  const teamSlots = useScopedSlots(\"team\");\n\n  // Status can be: \"connecting\" | \"ready\" | \"error\" | \"reconnecting\"\n}\n```\n\n---\n\n## 7. NEXT PRIORITY TASKS\n\n### 1. Test All Navigation Items in Staging\n\n**Priority:** HIGH  \n**Effort:** 2-3 hours  \n**Steps:**\n\n1. Deploy current build to staging\n2. Test every navigation item in every domain\n3. Document any remaining \"Module not found\" errors\n4. Fix gaps in `DOMAIN_CONTENT_MAP`\n\n### 2. Verify Error Boundaries Work Correctly\n\n**Priority:** HIGH  \n**Effort:** 1 hour  \n**Steps:**\n\n1. Temporarily add `throw new Error(\"Test\")` to a component\n2. Verify `ModuleErrorBoundary` catches and displays fallback UI\n3. Test the \"Retry\" button functionality\n4. Ensure error logging goes to console with module ID context\n\n### 3. Consider Adding Analytics Placeholder Module\n\n**Priority:** MEDIUM  \n**Effort:** 2-4 hours  \n**Current State:** Analytics routes to generic `OpsAnalyticsView`  \n**Options:**\n\n- Create domain-specific analytics views\n- Enhance generic view with domain-aware metrics\n- Add chart components from a library like Recharts\n\n### 4. Consider Adding AI Chat Placeholder Module\n\n**Priority:** MEDIUM  \n**Effort:** 3-6 hours  \n**Current State:** `ai-chat` routes to dashboard as placeholder  \n**Options:**\n\n- Create dedicated AI Chat interface component\n- Integrate with existing chat/AI infrastructure\n- Design UI for contextual AI assistance\n\n### 5. Review Other Domains for Similar Gaps\n\n**Priority:** MEDIUM  \n**Effort:** 3-4 hours  \n**Steps:**\n\n1. Check each domain's `workNavigation` in `workspace-config.ts`\n2. Verify all items exist in `DOMAIN_CONTENT_MAP`\n3. Look for missing module loaders in domain `modules.ts`\n4. Fix any gaps found\n\n### 6. Add Automated Navigation Coverage Test\n\n**Priority:** LOW  \n**Effort:** 4-6 hours  \n**Idea:** Write a test that:\n\n1. Reads all navigation items from `workspace-config.ts`\n2. Verifies each has a mapping in `DOMAIN_CONTENT_MAP`\n3. Fails the build if any nav item is unmapped\n\n---\n\n## 8. VERIFICATION COMMANDS\n\n### Typecheck\n\n```bash\npnpm --filter @integratewise/web typecheck\n```\n\n**Expected Output:** No errors  \n**If errors:** Check for missing imports, type mismatches, or TSConfig issues\n\n### Build\n\n```bash\npnpm --filter @integratewise/web build\n```\n\n**Expected Output:**\n\n```\nvite v6.x.x building for production...\n✓ X modules transformed.\ndist/                     X.X kB │ gzip: X.X kB\n✓ built in X.XXs\n```\n\n**If errors:** Check for circular dependencies, missing exports, or Rollup issues\n\n### Check Nav Coverage\n\n```bash\n# Count navigation sections across all domains\ngrep -c \"items:\" apps/web/src/components/workspace/workspace-config.ts\n\n# Expected: 20+ (varies by domain count)\n```\n\n### Verify Module Mappings\n\n```bash\n# Check that all DOMAIN_CONTENT_MAP entries have corresponding loaders\ngrep -E \"^\\s+\\w+:\" apps/web/src/components/workspace/content-router.tsx | head -30\n```\n\n### Quick Dev Test\n\n```bash\n# Start dev server\npnpm --filter @integratewise/web dev\n\n# Then test:\n# 1. Login flow\n# 2. Domain selection\n# 3. Click every sidebar nav item\n# 4. Verify no \"Module not found\" errors\n```\n\n---\n\n## 9. TROUBLESHOOTING GUIDE\n\n### \"Module not found\" Error\n\n**Symptoms:** Empty state with 🔍 icon, shows `{domain} / {moduleId}`\n\n**Causes:**\n\n1. Missing mapping in `DOMAIN_CONTENT_MAP`\n2. Wrong module ID (check `workspace-config.ts` vs `content-router.tsx`)\n3. Module loader returns undefined\n\n**Fix:**\n\n1. Check `workspace-config.ts` for the nav item's `id`\n2. Add mapping to `DOMAIN_CONTENT_MAP` in `content-router.tsx`\n3. Ensure module loader exists in domain's `modules.ts`\n\n### Blank Screen After Navigation\n\n**Symptoms:** White/empty content area, no error shown\n\n**Causes:**\n\n1. Component threw error during render\n2. Module loader returned undefined\n3. Named export not wrapped properly\n\n**Fix:**\n\n1. Check browser console for errors\n2. Verify module loader uses `.then((m) => ({ default: m.ComponentName }))` for named exports\n3. Add error logging to `ModuleErrorBoundary`\n\n### Import Path Errors\n\n**Symptoms:** Build fails with \"Cannot find module\" or \"Module not found\"\n\n**Fix:**\n\n- For UI components: Use `@/components/ui/...`\n- For domain components: Use relative paths `../../../domains/...`\n- For utilities: Use `@/lib/...` or relative paths\n\n### Path Parsing Issues\n\n**Symptoms:** URL changes but content doesn't update, or wrong view shown\n\n**Fix:**\nCheck `workspace-shell-new.tsx` path parsing logic. Ensure using `replace()` not `slice()`.\n\n---\n\n## 10. PROJECT STRUCTURE QUICK REFERENCE\n\n```\n/Users/nirmal/Github/integratewise-live/\n├── apps/\n│   ├── web/                          # Main web application\n│   │   ├── src/\n│   │   │   ├── components/\n│   │   │   │   ├── workspace/        # L1: Workspace Shell\n│   │   │   │   │   ├── workspace-shell-new.tsx\n│   │   │   │   │   ├── content-router.tsx\n│   │   │   │   │   └── workspace-config.ts\n│   │   │   │   ├── onboarding/       # L0: Onboarding Flow\n│   │   │   │   │   └── role-domain/\n│   │   │   │   │       ├── account-success/\n│   │   │   │   │       │   └── modules.ts\n│   │   │   │   │       └── business-ops/\n│   │   │   │   │           └── modules.ts\n│   │   │   │   ├── business-ops/     # Shared fallback components\n│   │   │   │   ├── domains/          # Domain-specific components\n│   │   │   │   │   └── account-success/\n│   │   │   │   └── cognitive/        # L2: Happy Path / AI Layer\n│   │   │   └── routes/               # Route definitions\n│   │   └── package.json              # @integratewise/web\n│   └── technical_marketing/          # Landing page application\n├── packages/                         # Shared packages\n├── services/                         # Backend services\n├── docs/                             # Documentation\n└── AGENTS.md                         # Main agent instructions\n```\n\n---\n\n## 11. CONTACT & RESOURCES\n\n- **Project:** IntegrateWise — \"Knowledge Workspace over the Spine, empowered by AI\"\n- **Architecture:** v4.1 (March 23, 2026)\n- **Founder:** Nirmal Prince J | IntegrateWise LLP | Bengaluru, India\n- **Main Agent Instructions:** See `/Users/nirmal/Github/integratewise-live/AGENTS.md`\n\n### Related Documentation\n\n- `ARCHITECTURE_OVERVIEW.md` — High-level architecture\n- `ARCHITECTURE_FLOW_C.md` — Data flow documentation\n- `WORKSPACE_ARCHAEOLOGY_COMPLETE.md` — Workspace history\n- `KT_v1.1_COMPLIANCE_AUDIT.md` — Compliance checklist\n\n---\n\n_Last Updated: March 27, 2026_  \n_Next Review: Before next major workspace feature_\n\n---\n\n---\n\n# Agent Session Notes — March 29, 2026\n\n> **Date:** March 29, 2026\n> **Agent:** Oz (Warp)\n> **Continues from:** Kimi's session — March 27, 2026 (above)\n> **Focus:** Full system review — backend services, frontend, architecture, strategic assessment\n\n---\n\n## 1. SESSION SUMMARY\n\nThis session was a full code-first exploration of the entire system — back to front — reading actual source files without relying on architecture docs. Covered all 11 backend services, the frontend app shell, the API client layer, and the creamy sync mechanism. Produced a complete system review with prioritised fixes.\n\n---\n\n## 2. WHAT WAS UNDERSTOOD (System Map)\n\n### Backend Stack\n\nAll services run on **Cloudflare Workers**. No Node.js, no traditional server.\n\n| Service      | Framework           | Role                                                                           |\n| ------------ | ------------------- | ------------------------------------------------------------------------------ |\n| `gateway`    | Raw fetch handler   | JWT auth, rate limiting, webhook verification, routing                         |\n| `think`      | Hono                | AI reasoning engine, Signal Engine, accelerators                               |\n| `workflow`   | Raw fetch handler   | BFF, HITL queue, analytics, SSE/WebSocket via Durable Objects                  |\n| `tenants`    | Hono                | OAuth flows, tenant CRUD, connector auth, token storage                        |\n| `connector`  | Raw fetch handler   | Merged: loader + mcp-connector + store                                         |\n| `normalizer` | Raw queue handler   | 8-stage pipeline (S1→S8) + creamy accelerator (NA0→NA5)                        |\n| `knowledge`  | Hono                | Semantic search, chunking, embeddings, triage, IQ hub                          |\n| `spine-v2`   | Raw fetch handler   | Entity routing to Supabase schema tables                                       |\n| `billing`    | Hono                | Stripe + Razorpay, subscriptions, usage, webhook dedup                         |\n| `agents`     | Hono + CF Workflows | Multi-agent colony: Orchestrator, Research, Analyst, Writer, Planner, Executor |\n\n### Data Layer\n\n- **Supabase PostgreSQL** — SSOT for most services\n- **Neon PostgreSQL** — Knowledge service + Tenants service (via `@neondatabase/serverless`)\n- **Cloudflare D1** — Edge cache: Think, Billing, Connector (signal rules, decisions, audit logs)\n- **Cloudflare KV** — Rate limits, sessions, OAuth state, connector status, signal cache\n- **Cloudflare Queues** — PIPELINE_QUEUE, KNOWLEDGE_QUEUE, INTELLIGENCE_QUEUE, ACCELERATOR_QUEUE, DLQ\n- **Cloudflare R2** — File storage (FILES bucket)\n\n### Frontend Stack\n\n- **React 18** + **Vite 6** (SWC compiler)\n- **React Router v7** — `/app/*` → AppShell, lazy-loaded\n- **TanStack Query v5** — Server state\n- **Tailwind v4** — CSS variables\n- **Radix UI** — Primitive components\n- **Framer Motion + GSAP** — Animations\n- **ReactFlow** — Node-based workflow UI\n- **Recharts** — Data visualisation\n\n### Auth Flow (OAuth Connectors)\n\n1. `connector.authorize(provider)` → `GET /api/v1/connectors/:provider/authorize`\n2. Gateway validates Supabase JWT → injects `x-user-id`, `x-tenant-id`\n3. Tenants service generates `state` UUID → stores in KV (10min TTL) → returns `authUrl`\n4. Browser redirects to OAuth provider consent screen\n5. Provider redirects to `/oauth/callback/:provider?code=xxx&state=yyy`\n6. `OAuthCallbackPage` — validates CSRF (client-side sessionStorage check)\n7. `connector.callback()` → `GET /api/v1/connectors/:provider/callback`\n8. Tenants service — KV state verification (server-side) → DELETE used state\n9. **Token exchange POST** to provider's token endpoint\n10. For Salesforce: extra identity call to get org ID. For GitHub: `GET api.github.com/user`\n11. AES-256-GCM encrypt tokens → upsert to Supabase `connectors` table\n12. Write installation-id → tenant mapping to CONNECTOR_STATUS KV\n13. Trigger creamy hydration via CONNECTOR_SYNC\n\n### Creamy Sync (60s Value)\n\nWhen a connector is first connected, `triggerInitialConnectorHydration()` fires `phase: \"creamy\"` to CONNECTOR_SYNC. This runs the **Normalizer Accelerator** (NA0→NA5) instead of the full 8-stage pipeline:\n\n- NA0: Schema detector + allowed field resolution\n- NA1: Canonical transformer + field pruning\n- NA2: SSOT binder (stable UUID assignment)\n- NA3: Lineage manager (source, sync_at)\n- NA4: Relation binder — **STUB — returns data unchanged**\n- NA5: Parallel write to Spine + Knowledge queue\n\n---\n\n## 3. FIXES IDENTIFIED — PRIORITISED\n\n### 🔴 HIGH — Fix Before Production Incidents\n\n**FIX-001: Implement OAuth token refresh**\n\n- **File:** `services/connector/src/sync-consumer.ts` + loader\n- **Problem:** `expires_at` is stored but never checked before API calls. HubSpot tokens expire in 30 min, Salesforce in 2h. Silent 401s will break connector syncs.\n- **Fix:** Before every connector API call in the loader, check if `expires_at` is within 5 minutes. If so, POST to the provider's token endpoint using `refresh_token`, update Supabase `connectors` row, then proceed.\n- **Providers needing refresh:** HubSpot, Salesforce, Google (all services), Zoom, Linear, Asana\n\n**FIX-002: Audit Neon vs Supabase — resolve split data source**\n\n- **Files:** `services/knowledge/src/index.ts`, `services/tenants/src/index.ts`\n- **Problem:** Knowledge and Tenants use `@neondatabase/serverless` with `DATABASE_URL`. All other services use Supabase with `SUPABASE_URL`. Two separate PostgreSQL instances OR the same DB with two different clients — both are wrong.\n- **Fix:** Check Doppler — are `DATABASE_URL` and `SUPABASE_URL` pointing to the same database? If yes, consolidate to one client. If no, define which is SSOT and migrate.\n\n**FIX-003: Fix `pull_requests → deal` entity alias**\n\n- **File:** `services/spine-v2/src/index.ts` line 161\n- **Problem:** GitHub PRs are routed to `sales.deal` table. Any tenant with GitHub connected has PR data in their sales pipeline.\n- **Fix:** Change alias to `pull_requests: \"task\"` or `pull_requests: \"project\"` depending on context.\n\n### 🟠 MEDIUM — Fix Before Scaling\n\n**FIX-004: Remove D1 buffer TODO from production path**\n\n- **File:** `services/tenants/src/index.ts` — `initializeD1Buffer()` function\n- **Problem:** Called on every Flow C connector connection (OpenAI, Anthropic, Cohere). Body is only `console.log` + a TODO comment. Silent no-op in production.\n- **Fix:** Either implement the D1 buffer initialization (create table entry, set triage rules) or remove the function call entirely and document it as planned work.\n\n**FIX-005: Consolidate AI providers — Agents service to OpenRouter**\n\n- **File:** `services/agents/src/index.ts`\n- **Problem:** Agents service uses `@cf/meta/llama-3.1-70b-instruct` via `env.AI` (Cloudflare Workers AI). Think service uses `anthropic/claude-sonnet-4-20250514` via OpenRouter. Two different model providers, different capability levels, different API surfaces — both supposed to be the same \"intelligence\" layer.\n- **Fix:** Replace `env.AI.run()` in BaseAgent with the `AIProvider` class from `services/think/src/ai-provider.ts`. Use OpenRouter for all agents. Add `OPENROUTER_API_KEY` to agents service bindings.\n\n**FIX-006: Billing webhook — KV check before processing**\n\n- **File:** `services/billing/src/index.ts`\n- **Problem:** In-memory `localWebhookReplayCache` (Map, 5000 keys) is per-Worker-instance. Cloudflare can spin multiple instances. Two instances can process the same Stripe webhook simultaneously before KV dedup catches up.\n- **Fix:** Move KV `acquireWebhookReplayLock()` to be the FIRST operation before any processing. Do not rely on the in-memory Map as a primary guard — it only works within a single instance.\n\n**FIX-007: NA5 — switch from HTTP URLs to service bindings**\n\n- **File:** `services/normalizer/src/normalizer-accelerator.ts` lines 100-101\n- **Problem:** Creamy sync (the 60s value path) makes real HTTP calls to `SPINE_SERVICE_URL` and `KNOWLEDGE_SERVICE_URL`. Every other service uses zero-latency Cloudflare service bindings. This adds DNS + network overhead on the most time-critical write path.\n- **Fix:** Pass `env.SPINE` and `env.KNOWLEDGE` (Fetcher bindings) into `NormalizerContext` and use them in NA5 instead of `fetch(url, ...)`.\n\n**FIX-008: NA4 RelationBinder — implement core relations**\n\n- **File:** `services/normalizer/src/normalizer-accelerator.ts` — `stageNA4_RelationBinder()`\n- **Problem:** Returns data unchanged. Relations between entities are not resolved during creamy sync. The first signals the user sees won't have relationship context (e.g. contact→account, deal→contact, ticket→account).\n- **Fix:** Implement the top 3 relation mappings:\n  1. `contact.account_id` → resolve to spine `account` UUID\n  2. `deal.contact_id` → resolve to spine `contact` UUID\n  3. `ticket.account_id` → resolve to spine `account` UUID\n     These three cover 80% of the relationship graph that drives signal quality.\n\n### 🟡 LOW — Housekeeping\n\n**FIX-009: Clean root directory — move .md files to /docs**\n\n- **Problem:** 40+ `.md` files at repo root (ARCHITECTURE_FINAL.md, ARCHITECTURE_CLEAN_FINAL.md, ARCHITECTURE_OVERVIEW_CORRECTED.md, etc.). Agents reading these for context get contradictory information from different iteration snapshots.\n- **Fix:** Move all architecture/summary .md files to `/docs`. Keep only `README.md`, `AGENTS.md`, `CLAUDE.md`, `AGENT_SESSION_NOTES.md` at root.\n\n**FIX-010: Fix relative path import in Workflow BFF**\n\n- **File:** `services/workflow/src/index.ts` line 4\n- **Problem:** `import { resolveTenantAdaptiveSchema } from \"../../../packages/types/src/adaptive-schema\"` — direct relative path instead of workspace import.\n- **Fix:** Change to `import { resolveTenantAdaptiveSchema } from \"@integratewise/types\"`\n\n**FIX-011: Standardise path casing — resolve /Users/Nirmal vs /Users/nirmal**\n\n- **Problem:** Indexed codebase path is `/Users/nirmal/Github/integratewise-live` (lowercase) but shell `pwd` resolves to `/Users/Nirmal/Github/integratewise-live` (uppercase N). Confuses agents, semantic search, and any tool that path-matches.\n- **Fix:** Add to `~/.zshrc`: `export IW_REPO=\"$HOME/Github/integratewise-live\"`. Always navigate with `cd $IW_REPO`. Check `ls /Users/ | grep -i nirmal` to confirm canonical casing. Update `AGENTS.md` with canonical repo path.\n\n---\n\n## 4. STRATEGIC CONTEXT\n\n### What IntegrateWise Is\n\nA **Knowledge Workspace built on the Spine, powered by governed AI** — not a dashboard, not a chatbot, not a data warehouse. Connects to every tool a company uses, normalises everything through an 8-stage pipeline into the Spine (single source of truth), runs AI reasoning on top to surface signals and propose actions — but **never acts without human approval**.\n\n### Core Philosophy (visible in the code)\n\n- **\"AI That Thinks in Context, Waits for Approvals\"** — HITL gate is a Durable Object (stateful, persistent, first-class)\n- **Flow A/B/C separation** — data-derived signals never get mixed with AI-generated insights\n- **One truth, many views** — `x-view-context` header propagates through every layer so CS, Sales, RevOps see the same Spine through their own lens\n- **Memory is institutional** — context-to-truth loop feeds AI chat insights back to Spine\n- **Trust at every layer** — tenant ID from DB not JWT, double CSRF check, timing-safe webhook comparison, tokens encrypted at rest\n\n### Competitive Position\n\n- **Differentiated in enterprise B2B** — governed intelligence is a moat, not a feature\n- **Regulation-ready** — EU AI Act, SOC 2, compliance requirements trend toward what's already built here\n- **Switching cost is structural** — once Spine has 6 months of normalised data, migration cost is enormous\n- **Risk:** Time-to-value is longer than \"just let the AI run\" competitors — the creamy layer (FIX-007, FIX-008) directly addresses this\n\n---\n\n## 5. KIMI'S OPEN TASKS (Carry Forward)\n\nFrom March 27 session — still pending:\n\n| #   | Task                                                            | Priority | Effort |\n| --- | --------------------------------------------------------------- | -------- | ------ |\n| K-1 | Test all navigation items in staging                            | HIGH     | 2-3h   |\n| K-2 | Verify error boundaries work correctly                          | HIGH     | 1h     |\n| K-3 | Add domain-specific analytics placeholder                       | MEDIUM   | 2-4h   |\n| K-4 | Add AI Chat dedicated interface (currently routes to dashboard) | MEDIUM   | 3-6h   |\n| K-5 | Review all other domains for DOMAIN_CONTENT_MAP gaps            | MEDIUM   | 3-4h   |\n| K-6 | Automated nav coverage test (CI gate)                           | LOW      | 4-6h   |\n\n---\n\n## 6. NEXT AGENT — START HERE\n\n**Do these first, in order:**\n\n1. Run `pnpm typecheck` — confirm Kimi's fixes still hold\n2. Pick FIX-001 (token refresh) — this is the only one that causes silent production failures\n3. Pick FIX-002 (Neon vs Supabase audit) — check Doppler secrets, one query to confirm\n4. Pick FIX-003 (pull_requests alias) — one line change, immediate data integrity fix\n5. After those three: FIX-007 + FIX-008 (creamy layer) — these directly improve the 60s value promise\n\n**Read before touching backend services:**\n\n- `services/gateway/src/index.ts` — understand routing table and auth flow\n- `services/think/src/engine.ts` — understand Flow C rules\n- `services/normalizer/src/index.ts` — understand 8-stage pipeline contract\n\n**Do NOT:**\n\n- Push directly to main\n- Touch the Spine write path without reading `services/spine-v2/src/index.ts` first\n- Add new entity type aliases without checking the ENTITY_TYPE_TO_TABLE map for semantic correctness\n\n---\n\n_Last Updated: March 29, 2026_\n_Session Agent: Oz (Warp)_\n_Continues from: Kimi — March 27, 2026_\n\n---\n\n## FOLLOW-UP SESSION (March 30, 2026)\n\nSee: `/Users/nirmal/Github/AGENT_SESSION_2026-03-30.md`\n\n**New Work:**\n\n- Built IntegrateWise Integration Brandstore Hub (webhooks, APIs, workflows)\n- Created standalone login page in FrontEnd/login-page/\n- Configured Claude Desktop MCP connectors\n- Fixed .zshrc startup errors\n- Deployment preparation for 3 sites\n\n**Status:** Integration Hub v2.0 complete, ready for deployment\n\n---\n\n## SESSION: April 9–10, 2026 (OpenCode — claude-opus-4.6)\n\n### Phase 1 — Code Audit (commit `0f1b924`)\n\n- Secrets removal, OAuth token refresh, split-brain resolution, terminology cleanup\n\n### Phase 2 — India/Dubai Market Pivot (commits `8c846ee`, `8cd472a`, `11c5b3a`)\n\n- 6 new connectors (Google Sheets, Tally, Razorpay, Vyapar, Khatabook, Shiprocket)\n- Real `universalSync()` wiring (52 sync adapters)\n- Billing end-to-end (7 disconnections fixed)\n\n### Phase 3 — Docs & Dogfooding (commit `2248184`)\n\n- CHANGELOG.md, ACTIVITY_LOG.md, ReleasesView, KnowledgeHubView\n\n### Flow C Activation (commit `9d32234`)\n\n- Knowledge service confidence-based triage + MCP connector triggers\n\n### Phase 4 Task 1 — Direct Supabase Reads (commit `c311699`)\n\n- SQL 070: `entity_type_map` (125 types), `entity_type_aliases` (70+), `get_workspace_entities()` RPC\n- Frontend: `use-supabase-entities.ts` hooks, rewrote `use-workspace-entities.ts` to delegate\n- 10 HTTP hops → 1 DB call per view\n\n### Phase 4 Task 2 — Adaptive Product Schema (commit `f314fa5`)\n\n- SQL 071: `organizations`, `teams`, `product_catalog` (20 products), `product_schema`, 4 RPCs\n- `tenant_id → org_id → team_id` hierarchy with default org/team per tenant\n- Frontend: `use-product-entities.ts`, generic `ProductView` renderer\n- 15 product view wrappers, module registries + content-router wired\n- Typecheck: 31/31 clean\n\n### Codebase Cleanup (commit `365e99d`)\n\n- Deleted 71 empty zero-byte files across 9 domain directories\n- Cleaned 8 module registries + content-router (removed dead imports)\n- Typecheck: 31/31 clean\n\n### Phase 4 Task 3 — Product-Scoped Navigation (commit `cf0798f`)\n\n- SQL 072: `tenant_products`, `product_nav_items`, seed data for all 20 products (~170 nav items)\n- RPCs: `get_tenant_products()`, `get_product_nav_items(product_id)`\n- Frontend: `use-tenant-products.ts` hooks (useTenantProducts + useProductNav)\n- Workspace shell: product-based nav with domain fallback, \"Personal\"/\"Workspace\" dropdown\n- Deleted orphaned `bizops-queue-view.tsx`\n- Full stub audit: ~45 stubs, ~10 partials, ~80 wired across 12 domains\n- Nav chain verification: content-router 20/20, module registry 20/20, sidebar now DB-driven\n- Typecheck: 31/31 clean\n\n### Outstanding Work\n\n1. **Run migrations 070 + 071 + 072** against Supabase production (requires credentials/user action)\n2. **Domain-to-default-product mapping** — backfill currently gives everyone `ops_core`; should map by tenant domain\n3. **Legacy shell cleanup** — domain-specific `shell.tsx` files + barrel `*-views.tsx` still in codebase\n4. **~45 stub files** — identified but not yet upgraded (options: wire to real data, convert to ProductView, or defer)\n5. **Future: product_sections** — custom UI layout configs per product (deferred)\n6. **Future: product_access** — billing gate for which products a team can access\n7. **Future: team-level data isolation** — adding org_id/team_id to domain tables\n\n### Key Architectural Decisions\n\n- **Data reads**: Direct Supabase from frontend (Option A). Never route reads through Gateway.\n- **Scoping**: `tenant_id → org_id → team_id`, always present (NOT NULL), no COALESCE\n- **20 products organize the UX**, 12 domains are internal infrastructure\n- **Progressive tenancy**: self-serve users get default org/team, migrate when they create their own\n- **`tenant_id` NOT in JWT** — resolved via `get_tenant_id()` (profiles lookup via `auth.uid()`)\n- **SECURITY DEFINER** functions bypass schema grants for cross-schema reads\n"}