A-Z
Shared from "Bonkers" on Inkdown
CREATOR.md - Bonkers Monorepo Architecture Document
System: Bonkers Monorepo
Date: March 2026
Author: Principal Engineering Team
Purpose: Zero-compromise architecture and engineering knowledge transfer
1. SYSTEM OVERVIEW
1.1 What Is Bonkers
Bonkers is a TypeScript monorepo containing a multi-platform AI application stack.
Applications:
- Website (
apps/website) - Next.js 14 web application (port 3001)
- Extension (
apps/extension) - Chrome Extension (Manifest V3, Vite)
Arcane (apps/arcane) - Express.js API server (port 8080)Session Manager (apps/session-manager) - Session state synchronization service
packages/app-config - Configuration (models, prompts, feature flags)
packages/components - Reusable React components
packages/hooks - Custom React hooks
packages/types - Shared TypeScript types
packages/utils - Utility functions
packages/config - ESLint, Prettier, TypeScript configs
packages/assets - Static assets
- Package Manager: pnpm 9.15.5 (workspaces)
- Build System: Turborepo
- Backend Framework: Express-Zod-API
- Database: Firestore (GCP)
- Cache: Redis
- Deployment: Vercel (frontend), Cloud Run (backend)
1.2 Architecture Layers
2. REPOSITORY STRUCTURE
2.1 Monorepo Layout
2.2 Key Configuration Files
3. APPLICATION ARCHITECTURE
3.1 Website (apps/website/)
Tech Stack: Next.js 14, React 18, TypeScript, Tailwind CSS, shadcn/ui
| File | Purpose |
|---|
middleware.ts | Auth routing, locale prefixing, cookie management |
navigation.ts | Custom navigation (replaces next/link) |
auth/auth.config.ts | NextAuth configuration, token refresh |
auth/auth.cookies.ts | Cookie configuration for production |
next.config.js | Transpile packages, image domains |
tailwind.config.ts | Theme, plugins, typography |
- Do NOT use
next/link - use custom navigation.ts
- Do NOT use
useRouter from next/navigation - use wrapper
- All API calls use axios
- All React queries wrapped in react-query
3.2 Extension (apps/extension/)
Tech Stack: Vite, React 18, Manifest V3, Tailwind CSS
| File | Purpose |
|---|
manifest.config.ts | Extension manifest (permissions, content scripts) |
src/background/index.ts | Service worker entry point |
src/background/background.messages.ts | Message handler |
src/contents/index.ts | Content script (injected into pages) |
src/lib/storage.ts | LocalStorageInstance (NOT chrome.storage) |
- Do NOT use
chrome.storage - use LocalStorageInstance
- All API calls proxied through background script
- Content scripts run at
document_end
3.3 Arcane Backend (apps/arcane/)
Tech Stack: Express, Express-Zod-API, TypeScript, Firebase Admin
Entry Point: src/index.ts
Middleware Chain (execution order):
3.4 Session Manager (apps/session-manager/)
Tech Stack: Express, Express-Zod-API, Firebase Admin, jose
Purpose: Real-time session state synchronization across devices
express-zod-api - API framework
firebase-admin - Auth verification
jose - JWT handling
@panva/hkdf - Key derivation
4. BACKEND DEEP DIVE
4.1 Middleware Architecture
Init Context (middlewares/initContext/initContext.ts):
Auth (middlewares/auth/auth.ts):
Usage Limits (middlewares/usageLimits/usageLimits.ts):
Thread Preware (middlewares/threadPreware/threadPreware.ts):
4.2 Request Context (AsyncLocalStorage)
4.3 Models
User Model (models/user.ts):
Thread Model (models/thread.ts):
4.4 Repositories
Context (repositories/context/requestContext.ts):
Schema (repositories/engine/schema.ts):
Side Actions (repositories/sideActions/sideActions.ts):
Streamer (repositories/streamer/streamer.ts):
Inter-Request Communication (repositories/irc/irc.ts):
5. DATA MODELS
5.1 User Document
5.2 Thread Document
5.3 Message Document (V2)
6. API ROUTES
6.1 Public Routes
| Route | Method | Description |
|---|
/v1/public/health | GET | Health check |
/v1/rewards | GET | Get rewards |
/v1/register-ads | POST | Register ad views |
6.2 Private Routes (Auth Required)
| Route | Method | Description |
|---|
/v1/thread/unified | POST | Main endpoint |
/v1/thread/stop | POST | Stop generation |
/v1/thread/message | POST | Send message |
| Route | Method | Description |
|---|
/v1/user/canvas/:canvasId | GET | Get canvas content |
/v1/user/canvas/:canvasId | POST | Update canvas content |
- Canvas content stored in GCP Storage (GCS) as JSON
- Path:
{uid}/canvas/{canvasId}.json
- Structure:
{ values: TCanvasValues[], history: { undos: [], redos: [] } }
- Supports version history with undo/redo
- Content type:
application/json (gzipped)
| Route | Method | Description |
|---|
/v1/user/status | GET | Get user status |
/v1/user/history | GET | List history |
/v1/user/settings | GET/POST | Get/set settings |
/v1/user/shareChat | POST | Share chat |
| Route | Method | Description |
|---|
/v1/projects | GET | List projects |
/v1/projects/create | POST | Create project |
/v1/projects/:id | GET/DELETE | Get/archive project |
| Route | Method | Description |
|---|
/v1/tools/text/:toolId | POST | Text tools |
/v1/tools/image/:toolId | POST | Image tools |
/v1/tools/ai-detector | POST | AI detection |
Wallflower (Image Generation):
| Route | Method | Description |
|---|
/v1/wallflower/image-generation | POST | Generate images |
/v1/wallflower/images | GET | Get image history |
/v1/wallflower/like | POST | Like image |
/v1/wallflower/pin-image | POST | Pin image |
Full Route List: apps/arcane/src/config/routing.ts
7. TEMPLATES (WALLFLOWER)
7.1 Available Templates
Templates are pre-configured image generation presets:
| Template ID | Name | Model | Description |
|---|
ghibli-style | Ghiblify | gpt-image-1-medium | Convert to Studio Ghibli style |
watermark-remover | Watermark Remover | gemini-2.0-flash-exp | Remove watermarks |
product-photography | Product Photography | gpt-image-1-high | Professional product shots |
make-me-bald | Make Me Bald | gemini-2.0-flash-exp | Bald transformation |
minecraft-style | Minecraft Style | gpt-image-1-medium | Minecraft block style |
simpson-style | Simpson Style | gpt-image-1-high | Simpsons cartoon style |
pixar-style | Pixar Style | gpt-image-1-high | Pixar 3D animation style |
humanize-my-pet | Humanize My Pet | gpt-image-1-medium | Pet to human transformation |
7.2 Template Structure
7.3 Template Processing
Controller: endpoints/wallflower/unified-generation.controller.ts
Usage Limits: Templates inherit model config from presets, usage calculated based on model + numberOfImages.
8. FALLBACK STRATEGIES
8.1 Generic Fallback Pattern
Utility: utilities/call-function-with-fallback.ts
8.2 Image Generation Fallbacks
Fal.ai ↔ Replicate Fallback:
Fallback Models Map (constantsSchemasAndTypes/wallflower/unified-generation.constants.ts):
8.3 Deep Research Fallbacks
Serp Query Fallback (features/deepResearch/firecrawlSerp.ts):
- Primary: Bing-based scraping
- Fallback 1: Firecrawl scraping
- Fallback 2: Basic URL fetch
Google Search Fallback (features/deepResearch/generateSerpQueries.ts):
8.4 AI Detection Fallback
Service: services/aiDetection.ts
endpoints/tools/aiDetection.ts
endpoints/tools/public/aiDetectionPublic.ts
endpoints/tools/aiEssayMetricsGenerator.ts
8.5 RAG Embeddings Fallback
File: endpoints/unified/features/rag.ts
8.6 Model Selection Fallback (Merlin Magic)
File: endpoints/unified/features/merlinMagic.ts
8.7 YouTube Transcription Fallback
File: utilities/youtube/youtube.ts
8.8 MCP Tool Result Fallback
File: utilities/mcp/functions/zapMCPToolResult.ts
8.9 Progress Event Fallback Index
File: constantsSchemasAndTypes/streamer/streamer.constants.ts
Usage: When tool result index is not specified, defaults to 0.
9. CRITICAL ARCHITECTURE DECISIONS
9.1 Why Express-Zod-API?
Decision: Use express-zod-api over raw Express, NestJS, Fastify
- Type safety with Zod schemas
- Auto-generated OpenAPI documentation
- Type-safe API client generation
- Clean middleware composition
- Built-in error serialization
- ✅ Pros: Type safety, auto-docs, less boilerplate
- ❌ Cons: Learning curve, vendor lock-in
9.2 Why AsyncLocalStorage?
Decision: Use Node.js AsyncLocalStorage for request context
- No prop drilling across 6+ middleware layers
- Global access without parameters
- Request isolation
- Minimal overhead
Risk: Single point of failure - if initContext fails, all context access returns empty object
9.3 Why Firestore?
Decision: Use Firestore (NoSQL) over PostgreSQL/MySQL
- Flexible schema for varying message structures
- Auto-scaling without sharding
- Nested data model (Thread → Messages)
- Firebase Auth integration
- No SQL joins (must denormalize)
- Transactions limited to 25 documents
- Eventual consistency
9.4 Why SSE Over WebSockets?
Decision: Use Server-Sent Events for streaming
- HTTP-based, no upgrade handshake
- Auto-reconnect built-in
- Firewall friendly
- One-way is sufficient for streaming
- ✅ Pros: Simple, low overhead, auto-reconnect
- ❌ Cons: One-way only, no binary data
9.5 Why Monorepo?
Decision: Use pnpm monorepo with Turborepo
- Code sharing across apps
- Atomic commits
- Consistent tooling
- Efficient builds (caching, parallelization)
- ✅ Pros: Code sharing, atomic commits, efficient builds
- ❌ Cons: Larger repo, coupled deployments
10. SECURITY
10.1 Authentication Flow
- JWT verification (Firebase Admin SDK)
- Custom claims for RBAC
- User document for additional permissions
- Token refresh via NextAuth
| Vulnerability | Risk | Status |
|---|
| JWT token theft | High | ✅ Mitigated (short expiry, HttpOnly cookies) |
| Custom claims tampering | Critical | ✅ Mitigated (server-side only) |
| Firestore rule bypass | Critical | ✅ Mitigated (all queries through backend) |
| CSRF | Medium | ⚠️ Needs review |
10.2 Rate Limiting
Current: Only guest users rate limited (50 requests / 15 min via Redis)
- No rate limiting for authenticated users
- IP-based (bypassable with rotating IPs)
- No endpoint-specific limits
10.3 Input Validation
- Zod schemas (all API inputs)
- Content moderation (async side action)
- Token limits (query size validation)
- File type validation (MIME type)
11. SCALABILITY
11.1 Current Scaling
Horizontal Scaling (Cloud Run):
arcane (primary)
arcane-copy (failover)
arcane-deepresearch (specialized)
| Component | Current | At Scale | Solution |
|---|
| Firestore writes | ~1K/sec | Sharding needed | Shard by user ID |
| Redis | Single instance | Connection pool exhausted | Redis Cluster |
| LLM APIs | Rate limited per key | Multiple keys | Round-robin keys |
11.2 Performance Optimizations
- Async side actions (non-blocking)
- Redis caching (user settings, model configs)
- SSE streaming (reduced time-to-first-token)
- Skip embeddings for large contexts (>6000 tokens)
- Pre-calculated token counts
- Response caching (identical queries)
- Embedding caching (RAG queries)
- Database indexing
- Connection pooling
11.3 Memory Management
Cloud Run Limits: 16GB max, 60min timeout, 4 vCPU
- AsyncLocalStorage context not cleaned up on error
- Redis IRC subscriptions not cleaned up
- PassThrough streams not destroyed on error
12. FAILURE MODES
12.1 Single Points of Failure
| Component | Impact | Recovery |
|---|
| Firebase Auth | Complete auth failure | 5-10 min |
| Firestore | All data operations fail | 10-30 min |
| Redis | Rate limiting, IRC fails | Immediate (bypass) |
| OpenAI API | GPT models unavailable | Immediate (fallback) |
12.2 Error Handling
- No retry logic for transient failures
- No circuit breakers
- No graceful degradation
12.3 Database Conflict Resolution
Retry Logic (Firestore document conflicts):
13. DEPLOYMENT
13.1 Pipelines
Backend (Cloud Run via cloudbuild.yaml):
- Auto-deploy on push to develop/review branches
- Environment variables in Vercel dashboard
13.2 Environment Variables
Critical: Environment variables NOT validated at startup - missing vars cause runtime errors.
13.3 Rollback
14. PRINCIPAL ENGINEER INTERVIEW Q&A
Q1: How do you ensure atomic writes for related documents?
Problem: Two Firestore writes can result in orphaned documents if the second fails.
Current Solution: Retry with document index increment
- Firestore Transactions: Atomic but limited to 25 docs
- Outbox Pattern: Write to outbox, process async
- Event Sourcing: Store changes as events
Key Insight: Retry-with-increment is pragmatic for Firestore contention. Not truly atomic but achieves eventual consistency.
Q2: How would you scale to 100K concurrent users?
| Component | Current | Solution |
|---|
| Firestore writes | ~1K/sec | Shard by user ID |
| Redis | Single instance | Redis Cluster |
| LLM APIs | Rate limited | Multiple keys + round-robin |
Key Insight: LLM API rate limits are the biggest bottleneck, not infrastructure. Solution: multi-key rotation + caching.
Q3: How do you handle slow LLM providers?
Current: No timeout, no fallback - request hangs.
Better: Circuit Breaker + Timeout + Fallback
Key Insight: Use circuit breakers to fail fast, not just timeouts. Prevents cascading failures.
Q4: How would you implement fair rate limiting?
Current: Only guest users limited (50/15min).
Key Insight: Rate limit by user ID (not IP), apply endpoint-specific costs.
Q5: How do you prevent prompt injection?
Current: Basic content moderation, no specific injection detection.
Key Insight: Prompt injection is an input validation problem. Defense in depth: sanitize, structure, validate.
Q6: How would you optimize history retrieval from O(n) to O(1)?
Current: Linear traversal through threadMap
- Denormalized Last N Messages:
- Message Index with Pointers:
Key Insight: For chat, you almost always need recent messages first. Denormalize last N, lazy load older.
Q7: How do you handle concurrent edits from multiple devices?
Current: Last-write-wins with Firestore server timestamp. No conflict resolution.
- Optimistic Concurrency Control:
- Queue-Based Serialization:
Key Insight: For chat, optimistic concurrency + client-side merge is sufficient.
Q8: What's the cost structure per request?
| Component | Cost |
|---|
| Input tokens (1K) | $0.0075 |
| Output tokens (500) | $0.01125 |
| Embeddings (RAG) | $0.0001 |
| Firestore writes | $0.00002 |
| Cloud Run | $0.00001 |
| Total | ~$0.02 |
Deep Research (Claude 3 Opus, 50x): ~$1.00 per request
Key Insight: LLM API costs dominate (99%+). Optimize: reduce tokens, cache responses, use cheaper models.
Q9: What would cause catastrophic failure?
Answer: Firebase Auth + Firestore simultaneous outage.
- No auth fallback → all requests rejected
- No database fallback → can't read any data
- No offline mode → complete failure
- Session Cache (Immediate):
Key Insight: System has no graceful degradation. Any Firebase failure causes complete outage.
15. QUICK REFERENCE
Commands
Key Files
| Purpose | File |
|---|
| API Routes | apps/arcane/src/config/routing.ts |
| Main Endpoint | apps/arcane/src/server/endpoints/unified/unified.ts |
| Auth Middleware | apps/arcane/src/server/middlewares/auth/auth.ts |
| User Model | apps/arcane/src/server/models/user.ts |
| Thread Model | apps/arcane/src/server/models/thread.ts |
| Schema Builder | apps/arcane/src/server/repositories/engine/schema.ts |
| Website Middleware | apps/website/middleware.ts |
Troubleshooting
| Symptom | Fix |
|---|
| 401 Unauthorized | Check Authorization header |
| 429 Rate Limited | Wait 15 minutes or upgrade |
| 500 Internal Error | Check Cloud Logging |
| Streaming fails | Check network, retry |
Last Updated: March 27, 2026
Version: 6.0.0 (Complete Architecture + Canvas + Templates + Fallbacks)
Document Status: ✅ Complete — Bonkers monorepo architecture with all critical systems