Bonkers 5 files · 0 subfolders
Copy to Workspace shubho-learning-bonkers Shared from "Bonkers" on Inkdown
Bonkers — Interview Revision Sheet
Last updated: June 11, 2026 · Final pass — principal engineer review
Use: Read top-to-bottom once, then §0 Cheat Sheet + §12 Scripts before interview
Mental model: Bonkers = product · Wallflower = backend engine · Your work = v2→v3 rebuild
0. Cheat Sheet (60-second scan)
BONKERS_INTERVIEW_QUESTIONS.md
Product AI creative production — generate, edit, template, gallery (not chat-with-images) Company / URL Foyer · getmerlin.in Scale ~50K generations /month (~1.7K/day, ~70/hr) — NOT 50K users Impact +50% DAU · -30% latency · 10K template images month 1 (~20% of volume) Stack bonkers/ frontend · merlin-arcane/ backend · /v1/wallflower/Controller unified-generation.controller.tsStorage GCS wallflower-images/{uid}/{iid}.png · Firestore wallflower/{uid}/images/ Providers 5: FAL · Replicate · OpenAI · Google Vertex · GoAPIModels / Features / Templates 20+ / 8 / 9 Killer differentiator Abstract model mapping — Zod .transform(), zero frontend changes on provider swap One sentence Cross-provider image engine — 5 providers, unified API, sequential failover, moderation, GCS normalization
Codenames: Cauldron = bonkers/ · Arcane = merlin-arcane/ · Wallflower = image API group
1. What & Why What: Foyer's AI image creative production platform. Originally standalone, consolidated into Merlin monorepo. Users generate, edit (8 features), apply templates (9), browse a public gallery (likes/shares), and iterate on history via parent lineage.
One-shot tools (prompt → image → leave) don't retain users
Dedicated product with own plans (BONKERS_PRO / BONKERS_BASIC) separate from Merlin chat
v2 = text→image only → v3 = templates + image→image + multi-model + parallel execution
vs Bonkers wins because ChatGPT/Gemini Image IS the product — 8 edit features, gallery, templates Midjourney Multi-provider web app, not Discord-locked Ideogram/Flux playgrounds Abstract model IDs + cross-provider fallback Canva/Firefly AI-native; templates = generation configs, not static files
2. Your Contribution — v2 → v3 Dimension v2 v3 (your rebuild) Core action Text→image once Template → generate → edit → remix → repeat Pipeline Separate controllers per feature Unified unified-generation.controller.ts Input Text only Text + image upload + mask Models Limited 20+ models, abstract IDs Templates None / saved prompts First-class Firestore configs Performance Serial Parallel post-processing, smart routing (-30%) Retention Low Repeat workflows (+50% DAU) Routes /{lang}/old-bonkers · /image-generation/{lang}/bonkers · /unified-generation
4 pillars: (1) unified pipeline {feature, modelConfig, prompt, image?} · (2) abstract model mapping · (3) templates as product · (4) image→image + GCS presigned uploads + parent lineage + Photon mask inversion + Replicate↔FAL fallback
Hardest problems: provider format divergence (GCS normalize-once) · mask semantics (FAL mask_url vs Replicate inverted via getInvertedMaskUrl()) · unifying 8 API shapes · legacy quota keys (wallflower vs bonkers)
Shipped: weekly release train · feature flags · Vercel instant rollback · old-bonkers kept during migration
Legacy migration: monitor both → legacy delegates to unified → 308 + deprecation header → remove after 30 days zero traffic (preserve quota keys)
+50% DAU attribution (if challenged): 4-week before/after, day-of-week controlled, cohort new vs returning, checked novelty decay, feature flags isolated other launches
2-min STAR: v2 one-shot, users didn't return → rebuild creative production → unified pipeline, abstract models, templates, GCS normalization, fallback → +50% DAU, -30% latency, 10K template images month 1
3. Abstract Model Mapping (core pattern) Users never see black-forest-labs/flux-schnell or fal-ai/ideogram/v3. They see abstract IDs. Resolution = Zod .transform() before controller runs.
User-facing Abstract ID Resolves to Query cost Bonkers Lite bonkers-liteprunaai/hidream-l1-fast10 / image Bonkers Advance bonkers-advancefal-ai/ideogram/v3120 / imageBonkers Magic Fill bonkers-magic-fillfal-ai/ideogram/v3/edit(inpaint tier)
Pricing override: bonkers-advance = 120 queries even though Ideogram V3 underlying cost = 75. Controller explicitly overrides usageConfig.queries = numberOfImages * 120. Intentionally decouples abstract pricing from provider cost — premium tier + rate limiter.
Benefits: provider swaps without frontend changes · model deprecation = remap one Zod map · A/B routing · business pricing independent of provider $
4. Eight Features + Nine Templates # Feature Provider / model Resilience One-liner 1 GENERATE Any model ✅ Replicate ↔ FAL fallback 20+ models, auto-failover 2 INPAINT Mask fill ⚠️ Photon SPOF for Replicate Cross-provider mask inversion 3 UPSCALE fal-ai/clarity-upscaler❌ FAL only One-click resolution boost 4 ERASE fal-ai/bria/eraser❌ FAL only AI object removal 5 EDIT_BG fal-ai/bria/background/replace❌ FAL only Background swap, no subject refs 6 OMNI_EDIT fal-ai/flux-pro/kontext/multi❌ FAL only Multi-image edit 7 TEMPLATE Per-template provider ⚠️ Provider lock One-click styled generation 8 REMIX GPT Image 1 ❌ OpenAI only Image→image (your v3 addition)
9 templates: Ghibli · Minecraft · Simpson · Pixar · Humanize My Pet · Watermark Remover · Make Me Bald · Product Photography · Logo Wizard
Firestore: {id, promptTemplate, modelConfig, style, thumbnail, category, version}
Versioned — frontend requests latest; model deprecation = remap abstract layer only
10K images month 1 = ~20% of ~50K total
User-facing extras: creations gallery (/{lang}/creations/[iid]) · public feed + likes · parent lineage · SSE progress · SEO/OG descriptions · ImageKit CDN · dual entry (Bonkers UI or Merlin chat tool)
5. Six Platform Layers Layer Mechanism Interview detail Abstract models Zod .transform() See §3 Fallback FALLBACK_MODELS_MAP + sequential callWithFallback()GENERATE only; inexact OK (Ideogram V2 → Flux Pro) Magic prompt MAGIC_PROMPT_SYSTEM_PROMPT + MAGIC_PROMPT_MODELSPer-feature LLM before provider GCS normalization getAttachmentWithGBucketUrl()Download temp provider URL → permanent GCS Moderation Pre: checkPromptFlagged() · Post: isImageFlagged() (templates only) Pre = block-before-spend; fails open on bad JSON Style system PRESET_STYLES_MAP + getStyleModifiedPrompt()Provider-specific application
Magic prompt per feature:
Feature Model Output GENERATE GPT-4o-mini { enhancedPrompt } ≤1000 charsINPAINT GPT-4o { enhancedPrompt, isRemoveOnly } — "remove car" vs "replace with tree"EDIT_BG GPT-4o-mini Background only — never "the subject" / "the person" GHIBLI / Product / Logo GPT-4o-mini Hyper-detailed style system prompts OFF Defaults e.g. isRemoveOnly: false, imageStrength: 0.8 for GHIBLI
9 style presets: Auto · Anime · Realistic · Digital Art · Vintage · Cinematic · Fantasy · Neon Noir · Minimalist
Ideogram → native ideogramStyle param · Recraft → recraftStyle API param · Others → append to prompt
Exception: Recraft V3 Realistic skips prompt append · Ideogram V2 Turbo returns prompt unmodified (native style)
6. Request Flow — Middleware + 11 Steps + SSE Phase 0 — Middleware:
Firebase JWT (authMiddleware) → usageLimits (block over-quota / free guests on FEATURE_LIMITS.bonkers) → fail = controller never runs
Step What Note 1 Zod validation prompt, modelConfig, feature, style, numImages, isPublic 2 Auth + usage confirm — 3 checkPromptFlagged()Blocking — saves provider $4 improvePrompt() magic prompt~700 tokens 5 Abstract model .transform() bonkers-advance → fal-ai/ideogram/v36 Prefix dispatch (helpers/generate.ts) See §7 7 callWithFallback()2–30s — slowest step8 formatImageGenerations()See §8 9 Firestore save wallflower/{uid}/images/10 SSE events attachments + usage11 incrementUserUsage()Charge abstract model query cost
SSE lifecycle: streamer.init → progress message → [provider 2–30s] → attachments (image) → usage (quota) → attachments (Firestore doc ID) → close
SSE event types: message (progress) · attachments (image) · usage (quota) · metadata
Why SSE not WebSockets: HTTP, no sticky sessions on Cloud Run, proxy-safe, reuses repositories/streamer/
Client: @microsoft/fetch-event-source — native EventSource can't POST or send Firebase JWT; handles parse, reconnect, AbortController + Redis STOP_GENERATING
isToolCall (Merlin chat tool): skips SSE → JSON response; skips GCS in post-processing; same provider handlers
Error gap: no explicit error SSE event — connection drops, frontend detects disconnect
7. Smart Routing & Fallback NOT parallel providers — would 2× API cost every request.
Prefix dispatch (helpers/generate.ts):
Model prefix Handler Try first black-forest-labs/*, recraft-ai/*, ideogram-ai/*handleReplicateWithFalAIFallback()Replicate fal-ai/*handleFalWithReplicateFallback()FAL gpt-image-1-*OpenAI handler OpenAI gemini-*Google Vertex Google midjourney-*GoAPI handler GoAPI
Fallback: sequential callWithFallback() — primary ANY error → FALLBACK_MODELS_MAP (10+ bidirectional Replicate↔FAL). Inexact mappings exist (something > nothing). Only GENERATE — 4 edit features have no equivalent.
-30% latency sources: parallel SEO (Promise.allSettled) · unified pipeline (one middleware chain) · native-provider-first · GCS normalize-once
Parallel post-processing: runs AFTER provider returns inside formatImageGenerations() — SEO + GCS per variation. 4 variations ~500ms vs ~2000ms serial. Does NOT speed provider gen (still 2–30s). SEO still blocks SSE — fix = Cloud Tasks.
8. Post-Processing & Data Model formatImageGenerations() — 5 steps:
Aspect ratio — auto-detect via Photon getDimensionsFromImage(); fallback 1024×1024 if Photon fails
SEO — describeImage() GPT-4o-mini per variation, parallel via Promise.allSettled (OG tags)
GCS upload — download temp provider URL → wallflower-images/{uid}/{iid}.png permanent URL
Parent lineage — parentImage / parentImages for edits, remix, templates
Cost calc — queryCost * numberOfImages from IMAGE_MODELS_INFO
GCS→Firestore sequencing risk: GCS first, then Firestore — if Firestore fails = orphaned image in GCS. Fix: write-ahead Firestore pending → update complete after GCS.
Firestore image doc fields: prompt · enhanced prompt · model ID · style · GCS URL · seed · aspect ratio · likes [] · visibility · metadata · parent refs
Public feed: /v1/wallflower/images · likes per image · daily questions
Photon: getDimensionsFromImage() + getInvertedMaskUrl() — if down: Replicate INPAINT/ERASE fail; dimensions fall back 1024×1024
ImageKit CDN: transformed delivery URLs · gap: 0–5s propagation race on fresh uploads (404 briefly)
9. Architecture & Scaling Layer Detail Cloud Run 0→N autoscale · stateless · 6GB RAM · 60min timeout · us-west1 · shares container with chat Providers They scale GPUs — Bonkers = orchestrator Firestore Image subcollections scale; customers/{uid} = 1 write/sec bottleneck Redis rate-limiter-flexible · IRC pub/sub · STOP_GENERATING TTL cache
Comfortable at 50K gens/month. At 10× (~500K):
Bottleneck Fix Firestore usage counter Redis-sharded distributed counters SEO blocking Async via Cloud Tasks Gallery SSR ISR + on-demand revalidation Photon SPOF Inline JS + circuit breaker FAL outage 5/8 features down (no fallback) No decision logging Sentry breadcrumbs per pipeline step
Per-generation resources: 1 Cloud Run req · 1 image Firestore write · 1 usage read+write · 1 GCS upload · 0–2 LLM (mod + magic) · 0–4 LLM (SEO) · 1 provider API call
Key design decisions: express-zod-api (OpenAPI + types) · SSE over WebSockets · AsyncLocalStorage request context · Firestore schema-on-read · Rune Cloudflare Worker for LLM proxy (magic prompt/moderation)
Interview framing: "Scalable today as serverless orchestrator. Bottlenecks at 10× are documented with fixes — roadmap, not current failure."
10. Quota & Auth (one section, minimal) Feature key Who consumes bonkersBONKERS_PRO / BONKERS_BASIC subscribers merlinFree/PRO/TEAMS/ELITE using image gen via chat — 1 FLUX Pro image (140 queries) can exhaust daily chat quota wallflowerLegacy /image-generation endpoint only
Flow: firebase.auth().getIdToken() → Axios Authorization: Bearer → authMiddleware.verifyIdToken() → load customers/{uid} → usageLimits middleware → controller
11. Known Gaps + Fixes (say proactively) # Gap Fix 1 4/8 features die on FAL outage Add redundant providers for edit features 2 GCS orphan on Firestore failure Write-ahead pending status 3 Moderation fails open on bad JSON try/catch → default flagged: true 4 Regenerate inconsistency Magic prompt temp > 0; fallback changes model; seed not tied to concrete modelId 5 Post-gen moderation templates only Extend isImageFlagged() to all features 6 SEO blocks response 500ms–2s Async Cloud Tasks 7 No real per-provider $ tracking IMAGE_TOKEN_TO_QUERY_RATIO is fictional8 Firestore usage hotspot Redis counter shards 9 ImageKit CDN race Retry/poll or serve GCS directly until propagated 10 No error SSE event Add explicit error event type 11 No pipeline decision logging Sentry breadcrumbs (chat has decisionLog, images don't)
12. Interview Scripts
Foyer's AI image creative production platform — generate, edit, template, gallery. Multi-provider engine with abstract models and unified 8-feature pipeline.
Walk through a request (30 sec):
Firebase auth and quota middleware, then unified controller: Zod validate, block-before-spend moderation, magic prompt, abstract model resolve, prefix-based provider dispatch with sequential fallback, post-process to GCS, save Firestore, stream via SSE — progress, image, quota. SSE over WebSockets because Cloud Run autoscales without sticky sessions.
Your contribution (30 sec):
Led v2→v3 from one-shot generator to template-first creative production — unified cross-provider pipeline, abstract models, templates as product. +50% DAU, -30% latency, 10K template images month 1.
Abstract models (20 sec):
Users see bonkers-lite and bonkers-advance, not provider IDs. Zod transform resolves before the controller. Provider swap = one map update, zero frontend changes. bonkers-advance intentionally costs 120 queries — decoupled from underlying provider cost.
50K generations/month, not users. Stateless Cloud Run orchestrator, providers handle inference, GCS stores, ImageKit serves from edge. Comfortable today; at 10× I'd shard Firestore usage counters via Redis.
Parallel vs routing (25 sec):
Promise.allSettled parallelizes SEO after provider returns — not parallel providers. Smart routing = prefix dispatch, native provider first, sequential fallback on error. -30% latency = post-processing + unified pipeline, not faster models.
GPT-4o returns isRemoveOnly boolean — distinguishes "remove the car" from "replace with tree". FAL uses mask_url; Replicate needs inverted mask via Photon getInvertedMaskUrl().
FALLBACK_MODELS_MAP, 10+ bidirectional Replicate↔FAL equivalents, sequential only. Inexact fallbacks exist. ERASE, UPSCALE, EDIT_BG, OMNI_EDIT have zero fallback — FAL outage kills 5/8 features.
2-min walkthrough outline:
Big picture — Bonkers at getmerlin.in, Wallflower backend, 50K gens/month
Abstract models — why, how, pricing override
8 features — unified pipeline, GCS normalization
Click Generate — 11 steps, SSE lifecycle
Your v2→v3 story + impact numbers
Honest gaps — FAL dependency, moderation fails open, usage hotspot
13. Probe Q&A (quick follow-ups) They ask You say Why not WebSockets? Sticky sessions on Cloud Run; SSE = HTTP, autoscale-friendly Why @microsoft/fetch-event-source? EventSource can't POST or send Firebase JWT 50K users? No — 50K generations /month, ~1.7K/day Scalable? Yes today; bottlenecks at 10× with known fixes Promise.allSettled speed up gen? No — speeds post-processing SEO/GCS after provider returns What if FAL goes down? GENERATE degrades via fallback; 4 edit features + templates on FAL-only models break Regenerate gives different image? Magic prompt non-determinism + fallback may switch provider; seed tied to model ImageKit 404 on fresh upload? CDN propagation race 0–5s — image exists in GCS Free users? Blocked at usageLimits — never reach controller Chat tool vs direct Bonkers? isToolCall skips SSE/GCS; same engine underneathTemplates vs saved prompts? Firestore configs with versioned model+prompt — product feature, not user saves NDA / no code? Walk architecture and data flow; reference codenames and patterns not proprietary keys
14. Key Files Path Role endpoints/wallflower/unified-generation.controller.tsCentral orchestrator unified-generation.schema.tsZod + abstract model .transform() helpers/generate.tsPrefix routing + callWithFallback() repositories/streamer/SSE server engine middlewares/usageLimits/Quota gate utilities/usage.tsincrementUserUsage()Provider helpers replicate/ · fal-ai/ · ideogram/ · openai-image-gen.ts · google-image-gen/
Companion services: Photon (dimensions + mask inversion) · Session Manager (JWT cookie chunking) · LlamaIndex (RAG — decoupled)
15. Skip (Merlin ecosystem, not Bonkers engine) Chrome extension · MCP · Deep Research · Context window engine · Tool orchestrator · Monorepo/Turbo · i18n · Stripe internals · Auth deep dive · System design hypotheticals (collaborative canvas, 100K DAU feed — not built )