Mirobody
The canonical registry of human health — roughly two thousand standardized indicators, clinical and lifestyle, resolved into one language.
翻訳待ち
リポジトリ情報はまだ収集していません。
No updates detected yet. GitHub releases will appear here.
official website for dozy
翻訳待ち
Loading the full README.
Read the full README ↗Official marketing site + web subscription for Dozy — Next.js on Vercel.
Same plan as iOS: $19/month with a 3-day free trial, then subscribe to use the product.
| Route / API | Purpose |
|---|---|
POST /api/checkout | Create Checkout Session (mode: subscription, trial_period_days: 3) |
POST /api/checkout/complete | Success-page session sync + cookie (webhook remains authoritative) |
POST /api/webhooks/stripe | Fulfill entitlement on Checkout + subscription lifecycle events |
POST /api/portal | Stripe Customer Portal (manage / cancel) |
GET /api/entitlement | Current entitlement for the signed session |
/subscribe | Paywall |
/success, /cancel | Checkout return URLs |
/app | Gated product shell (requires active or trialing) |
Copy .env.example → .env.local and set:
STRIPE_SECRET_KEY — prefer a restricted API key (rk_)STRIPE_WEBHOOK_SECRETNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYSTRIPE_PRICE_ID — Price for $19/monthNEXT_PUBLIC_APP_URLSESSION_SECRETJUNCTION_API_KEY / JUNCTION_ENVIRONMENT — optional; cloud sleep sources (Oura / Garmin / Whoop via Junction)Apple Health stays on-device in the iOS app. For Oura / Garmin / Whoop cloud connect:
| Route | Purpose |
|---|---|
POST /api/auth/apple | Exchange an Apple identity token for an app session |
POST /api/junction/user | Create/map Junction user |
POST /api/junction/link-token | Open Junction Link widget |
POST /api/junction/demo-connect | Sandbox synthetic provider (no wearable account) |
GET /api/junction/sleep | Normalized sleep summaries |
POST /api/webhooks/junction | Sleep created/updated webhooks |
/junction/connected | Link redirect landing |
The iOS app signs in once with POST /api/auth/apple ({ "identityToken": "<Sign in with Apple identity token>" }). The server checks Apple's signature, issuer, audience (APPLE_BUNDLE_ID, default charvibansall.dozy) and expiry, then returns { userId, sessionToken, expiresAt }. The session lasts 90 days and is signed with SESSION_SECRET.
The app sends Authorization: Bearer <sessionToken> on /api/junction/user, /link-token, /sleep and /demo-connect. A session only works for the clientUserId it was issued for (401 without a valid session, 403 for someone else's id).
JUNCTION_ENVIRONMENT=production: a session is always required.JUNCTION_REQUIRE_AUTH=true to require it there too.Run the checks with npm test.
Sandbox demo providers: oura, whoop_v2, apple_health_kit, freestyle_libre. Garmin has no demo — needs a real Garmin Connect login via Link. Whoop production also needs bring-your-own Whoop OAuth. See Project store docs/junction-setup.md.
price_… id into STRIPE_PRICE_ID.subscription_data.trial_period_days: 3 (no need to hard-code trial on the Price).https://<your-domain>/api/webhooks/stripe for at least:
checkout.session.completedcheckout.session.async_payment_succeededcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.paidinvoice.payment_failedcharge.refunded, charge.dispute.created, radar.early_fraud_warning.createdstripe listen --forward-to localhost:3000/api/webhooks/stripeWebhook handlers upsert subscription status into a durable local store (.data/entitlements.json when the filesystem is writable) and the app sets a signed dozy_entitlement cookie after Checkout. Protected /app routes require status active or trialing. Lookups reconcile from the Stripe Subscriptions API when the local cache is cold (e.g. serverless).
If you charge US/EU customers, consider enabling Stripe Tax and active tax registrations before turning on automatic_tax.
npm install
npm run dev
npm run build