Skip to content

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.


StepSurfaceEvidence
1. Consumer home promptapps/mobile/app/(consumer)/index.tsxtypes “il rubinetto perde acqua” → push /triage?prompt=...&lat=...&lng=...
2. Triage SSE streamPOST /triage/streamapps/api/src/modules/triage/triage.service.tsemits event: typingevent: results_ready within ~2 s; GPT-5.4-mini tool-calls searchProfessionals w/ inferred categorySlug: plumbing
3. Triage screen rendersapps/mobile/app/triage.tsx + lib/hooks/use-triage.tsparses event: prefix lines, redirects to /results?category=<slug>&lat=&lng= on results_ready
4. Results gridapps/mobile/app/results.tsxlists seeded pros (Marco Rossi / Paolo De Santis depending on lat/lng)
5. Professional detailapps/mobile/app/professional/[id].tsxshows profile + Book CTA
6. Book screenapps/mobile/app/book/[professionalId].tsxprefilled description summary card, address Input always rendered
7. Submit bookingPOST /bookingsbooking.service.ts:createBooking201 with booking id
8. Success screensame fileanimated checkmark, “View bookings” CTA
9. Bookings listGET /bookings/mine/consumerapp/(consumer)/bookings.tsxrenders BookingCard with flattened professional.businessName
10. Booking detailGET /bookings/:idapp/booking/[id].tsxrenders 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 cmo7e0dot0000q3jxuumcfxz9

MVP/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.

  1. apps/api/.env (gitignored) + Dokploy prod env:
    AUTH_BYPASS=1
    DEMO_CONSUMER_EMAIL=edoardo.demo@ideony.dev
  2. apps/api/src/main.ts — Helmet contentSecurityPolicy: false, all three cross-origin policies false, CORS reflects any origin with credentials: true, allowed headers *.
  3. apps/api/src/modules/sos/sos.gateway.ts + .../professionals/professionals.gateway.ts — Socket.IO cors.origin: true (was env-allowlist).
  4. apps/api/src/modules/auth/guards/clerk.guard.tsAUTH_BYPASS=1 short-circuits JWT verify; attaches demo consumer.
  5. apps/api/src/modules/auth/guards/roles.guard.tsAUTH_BYPASS=1 skips @Roles() check.
  6. apps/mobile/lib/stores/auth.ts + apps/mobile/lib/auth/use-continue-flow.tsdemoMode store flag + continueAsGuest() + “Entra come ospite (demo)” CTA on /(welcome)/continue. apps/mobile/lib/api.ts skips Clerk JWT when demoMode=true so 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.


Terminal window
alpha-2026-04-20-cofounder-demo
Terminal window
# Inspect the alpha
git 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 branch
git 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)”
FileSHA-1
apps/api/src/main.ts6fadd674eb2a5878c4d0089c2ac8f3b396551bfc
apps/api/src/modules/ai/agent.factory.ts8563eae38966cd43e2bedab67a6cce49b5df166a
apps/api/src/modules/ai/graphs/triage.prompt.ts349781f30e9a57c6d81a128192c014b5cef65b0d
apps/api/src/modules/auth/guards/clerk.guard.tsa97424f55add112bb6d936475d71cb243f781e65
apps/api/src/modules/booking/booking.service.ts28d32742697eddd822b10bb39e5f8db1c8f3af13
apps/mobile/lib/hooks/use-triage.tsb2fa51663c1501564e5e51a6d08459dbb53f74d9

Retrieve a single file at the alpha:

Terminal window
git show alpha-2026-04-20-cofounder-demo:apps/api/src/main.ts > /tmp/main.alpha.ts
ServicePortSupervisor
NestJS API3000nest start --watch (pid 81763) → node dist/src/main (pid 83532)
Expo Web8081expo 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)

(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 policy

Deferred 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 /book crashes web bundle (expo-image-picker + R2 presigned URL path)
  • B30 — service address needs GPS auto-detect (expo-location reverse-geocode) + typeahead autocomplete (Mapbox Places)

Every other bug in that doc is fixed in this alpha.


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 behaviour
  • apps/api/src/modules/ai/agent.factory.ts:createOpenAIModel() — do NOT re-add response_format: json_object (mutually exclusive with tool_calls)
  • apps/api/src/modules/triage/triage.service.ts — SSE header injection via buildCorsHeaders(reply); Fastify’s CORS hook does not fire for reply.raw.writeHead
  • apps/mobile/lib/hooks/use-triage.ts — SSE parser reads the event: prefix line; JSON payload does NOT carry a type field
  • apps/mobile/app/book/[professionalId].tsx — address Input must always render (triage rarely populates locationText)
  • apps/api/.env’s AUTH_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.