Working Alpha — Crystallized 2026-04-20 Night
Working Alpha — Crystallized 2026-04-20 Night
Section titled “Working Alpha — Crystallized 2026-04-20 Night”Status: ✅ end-to-end demo flow confirmed on web (http://localhost:8081).
Tag: alpha-2026-04-20-cofounder-demo
Purpose: stable rollback anchor for the 2026-04-21 cofounder demo. Pin every ingredient (code, env, prompts, seed data) so we can diff/revert if later edits regress the flow.
What works
Section titled “What works”| Step | Surface | Evidence |
|---|---|---|
| 1. Consumer home prompt | apps/mobile/app/(consumer)/index.tsx | types “il rubinetto perde acqua” → push /triage?prompt=...&lat=...&lng=... |
| 2. Triage SSE stream | POST /triage/stream → apps/api/src/modules/triage/triage.service.ts | emits event: typing → event: results_ready within ~2 s; GPT-5.4-mini tool-calls searchProfessionals w/ inferred categorySlug: plumbing |
| 3. Triage screen renders | apps/mobile/app/triage.tsx + lib/hooks/use-triage.ts | parses event: prefix lines, redirects to /results?category=<slug>&lat=&lng= on results_ready |
| 4. Results grid | apps/mobile/app/results.tsx | lists seeded pros (Marco Rossi / Paolo De Santis depending on lat/lng) |
| 5. Professional detail | apps/mobile/app/professional/[id].tsx | shows profile + Book CTA |
| 6. Book screen | apps/mobile/app/book/[professionalId].tsx | prefilled description summary card, address Input always rendered |
| 7. Submit booking | POST /bookings → booking.service.ts:createBooking | 201 with booking id |
| 8. Success screen | same file | animated checkmark, “View bookings” CTA |
| 9. Bookings list | GET /bookings/mine/consumer → app/(consumer)/bookings.tsx | renders BookingCard with flattened professional.businessName |
| 10. Booking detail | GET /bookings/:id → app/booking/[id].tsx | renders w/o crash (optional-chained professional + flattened shape from BE) |
Triage stream probe (localhost):
POST /triage/stream {"prompt":"il rubinetto perde acqua","latitude":45.4642,"longitude":9.19}→ event: results_ready → Marco Rossi, plumbing, categoryId cmo7e0dot0000q3jxuumcfxz9MVP/PoC SECURITY RELAXATIONS — REVERT BEFORE PUBLIC LAUNCH
Section titled “MVP/PoC SECURITY RELAXATIONS — REVERT BEFORE PUBLIC LAUNCH”All tagged with an inline HARDEN before public launch comment so rg "HARDEN" finds them in one pass.
apps/api/.env(gitignored) + Dokploy prod env:AUTH_BYPASS=1DEMO_CONSUMER_EMAIL=edoardo.demo@ideony.devapps/api/src/main.ts— HelmetcontentSecurityPolicy: false, all three cross-origin policiesfalse, CORS reflects any origin withcredentials: true, allowed headers*.apps/api/src/modules/sos/sos.gateway.ts+.../professionals/professionals.gateway.ts— Socket.IOcors.origin: true(was env-allowlist).apps/api/src/modules/auth/guards/clerk.guard.ts—AUTH_BYPASS=1short-circuits JWT verify; attaches demo consumer.apps/api/src/modules/auth/guards/roles.guard.ts—AUTH_BYPASS=1skips@Roles()check.apps/mobile/lib/stores/auth.ts+apps/mobile/lib/auth/use-continue-flow.ts—demoModestore flag +continueAsGuest()+ “Entra come ospite (demo)” CTA on/(welcome)/continue.apps/mobile/lib/api.tsskips Clerk JWT whendemoMode=trueso anonymous requests land on the BE AUTH_BYPASS path. Paired 1:1 with item 4 — remove both together.
Before the first public-facing deploy, grep rg -n "HARDEN" in apps/api/, revert each block, and add a pre-deploy CI check that fails if AUTH_BYPASS is truthy or if any HARDEN comment survives.
Anchor artifacts
Section titled “Anchor artifacts”Git tag
Section titled “Git tag”alpha-2026-04-20-cofounder-demoRollback
Section titled “Rollback”# Inspect the alphagit show alpha-2026-04-20-cofounder-demo --stat
# Hard rollback (destructive — only if main drifted past the alpha and needs to snap back)git reset --hard alpha-2026-04-20-cofounder-demo
# Cherry-pick just the demo-blocker fixes onto another branchgit cherry-pick $(git rev-list alpha-2026-04-20-cofounder-demo ^alpha-2026-04-20-cofounder-demo~1)Blob hashes (useful for surgical revert of individual files)
Section titled “Blob hashes (useful for surgical revert of individual files)”| File | SHA-1 |
|---|---|
apps/api/src/main.ts | 6fadd674eb2a5878c4d0089c2ac8f3b396551bfc |
apps/api/src/modules/ai/agent.factory.ts | 8563eae38966cd43e2bedab67a6cce49b5df166a |
apps/api/src/modules/ai/graphs/triage.prompt.ts | 349781f30e9a57c6d81a128192c014b5cef65b0d |
apps/api/src/modules/auth/guards/clerk.guard.ts | a97424f55add112bb6d936475d71cb243f781e65 |
apps/api/src/modules/booking/booking.service.ts | 28d32742697eddd822b10bb39e5f8db1c8f3af13 |
apps/mobile/lib/hooks/use-triage.ts | b2fa51663c1501564e5e51a6d08459dbb53f74d9 |
Retrieve a single file at the alpha:
git show alpha-2026-04-20-cofounder-demo:apps/api/src/main.ts > /tmp/main.alpha.tsRunning processes at crystallization time
Section titled “Running processes at crystallization time”| Service | Port | Supervisor |
|---|---|---|
| NestJS API | 3000 | nest start --watch (pid 81763) → node dist/src/main (pid 83532) |
| Expo Web | 8081 | expo start --web (pid 81975) |
Both auto-rebuild on apps/api/src/** or apps/mobile/** changes. Logs: /tmp/ideony-api.log, /tmp/ideony-metro.log.
Seeded demo data (from apps/api/scripts/seed-demo.ts)
Section titled “Seeded demo data (from apps/api/scripts/seed-demo.ts)”- Consumer: Edoardo,
edoardo.demo@ideony.dev - Professionals: Marco Rossi (Milano, plumbing), Paolo De Santis (Roma, plumbing), Giulia Bianchi (electrical)
- Bookings: 1× PENDING (Giulia / electrical), 1× ACCEPTED (Paolo / plumbing)
Known-good commit graph
Section titled “Known-good commit graph”(tag: alpha-2026-04-20-cofounder-demo, HEAD -> main)│├─ fix(api): demo-blocker batch — CORS + AUTH_BYPASS + triage tool-calling + bookings.professional flatten├─ a6a1aa8 fix(api): wire TriageModule in AppModule + export AgentFactory from AiModule├─ 9aa0785 feat(api): demo seed for cofounder walkthrough├─ c807016 fix(mobile): correct @clerk/expo import + api.ts fallback port 3000├─ 7df52f6 fix(mobile): bookings tab 401 — token null before Clerk ready├─ cc2b208 fix(mobile): HomeMap web renders — Dimensions.get at module load returns 0x0└─ 2dd5ab8 fix(mobile): web bundle crash — pretty-format@30 broken ESM + push notif web guard + ADR-0025 LTS policyDeferred to docs/plans/2026-04-21-bug-sweep.md
Section titled “Deferred to docs/plans/2026-04-21-bug-sweep.md”- B29 — image upload from
/bookcrashes web bundle (expo-image-picker + R2 presigned URL path) - B30 — service address needs GPS auto-detect (
expo-locationreverse-geocode) + typeahead autocomplete (Mapbox Places)
Every other bug in that doc is fixed in this alpha.
Don’t touch list (until post-demo)
Section titled “Don’t touch list (until post-demo)”Code paths whose current shape is load-bearing for the demo and should NOT be refactored without re-running the full walkthrough:
apps/api/src/modules/ai/graphs/triage.prompt.ts— changing the prompt may re-break tool-calling behaviourapps/api/src/modules/ai/agent.factory.ts:createOpenAIModel()— do NOT re-addresponse_format: json_object(mutually exclusive withtool_calls)apps/api/src/modules/triage/triage.service.ts— SSE header injection viabuildCorsHeaders(reply); Fastify’s CORS hook does not fire forreply.raw.writeHeadapps/mobile/lib/hooks/use-triage.ts— SSE parser reads theevent:prefix line; JSON payload does NOT carry atypefieldapps/mobile/app/book/[professionalId].tsx— address Input must always render (triage rarely populateslocationText)apps/api/.env’sAUTH_BYPASS=1— required for every browser hit since Clerk JWT isn’t attached in the demo flow
Re-enabling any of these requires a matching fix on the other side of the stack.