泣き声が“わかる”ようになるアプリ。
The awababy funnel,
as a pure-function engine.
@awababy/funnel decides when to ask a happy parent for a rating, when to route a struggling one to support, and when the store rating has recovered enough to spend on acquisition. Be bubbly with your baby!
125 tests
96% coverage
0 runtime deps
policy · metrics · gate
Session simulator
Every app event flows through step(state, event, now).
session 1
analyses 0
review requests 0
nudges 0
Weekly cohort metrics
The same event log, replayed through the calculator.
| Cohort | Users | Activated ≤7d | Day-7 return |
|---|---|---|---|
| Cohort | Open→record | Completion | Review req. |
|---|---|---|---|
The acquisition gate
No paid traffic until the rating recovers.
At ship
Week 8
Where this data comes from
// CryAnalysisViewController.swift — result handler let event = FunnelEvent.analysisCompleted( id: analysisId, confidence: 0.87, category: "hungry") Telemetry.post(event) // → POST /api/events let r = engine.step(state, event, now) state = r.state // persist as JSON for d in r.decisions { switch d { case .requestReview: SKStoreReviewController.requestReview(in: scene) case .showNudge: present(SupportSheet(), animated: true) } }
// functions/api/events.js — live on this site import { validateEvent, step, INITIAL_POLICY_STATE } from '../../funnel/index.js' export async function onRequest({ request }) { const v = validateEvent(await request.json()) if (!v.ok) return json({ ok: false, errors: v.errors }, 422) // demo: run the shipped engine server-side too const r = step(INITIAL_POLICY_STATE, v.event, v.event.ts) return json({ ok: true, decisions: r.decisions }) }