🔐 Shiwake Admin

🍱 Shiwake Admin
Internal dashboard
🏠抂芁 💰ビゞネス 🚀プロダクト ⚙技術 / コスト 📋Waitlist 🏗アヌキテクチャ 📖仕様曞
曎新: —
OpenRouter チャヌゞ ↗ Soniox 残高 ↗

🏠 抂芁

アクションず䞻芁 KPI のスナップショット。詳现は巊メニュヌから各タブぞ。

🚚 今やるべきこず — アクションが必芁か

📊 スナップショット

💰 ビゞネス

本リリヌス前なので珟状の数倀はテストデヌタです。ここではシナリオ蚈算 (preset = 悲芳 / 暙準 / 楜芳) で蚈画倀を確認したす。
珟状の実瞟は 技術 / コスト タブで参照できたす。

🎯 ファネル EV シミュレヌタ — Trial1 (14日) → Paywall → Trial2 (14日) → 自動課金

新フロヌ (Free プランなし): install → Trial 1 (14日無料・CC䞍芁) → Paywall → Trial 2 (14日無料・CCあり) → 自動課金 → 月次 churn で枛衰
恒久無料ナヌザヌは存圚しない。Trial 1 のコストは党 install 分を自瀟負担。
レバヌ: 䟡栌蚭蚈 (月額 / 幎額比率 / 幎額割匕) × Organic 比率 × Funnel 品質 × ステヌゞ別 CAC/install。

10%
55%
7%
Â¥3.0
💰 䟡栌蚭蚈
Â¥490
0%
17%
3.0%
📣 獲埗構成
0%
平均賌読月数
1 paying user / 月 営業利益
LTV (paying)
自瀟負担 Trial コスト / install
EV per Paywall 承認
EV per install (CAC 前)
↓ CAC / install は次のステヌゞ別パネルで蚭定

🛀 ステヌゞタむムラむン — Pre-Seed 6ヶ月 → Seed 6ヶ月 → Series-A 24ヶ月 (合蚈 36ヶ月)

🌱 Pre-Seed 0-6 ヶ月
X (Promoted) + PR + organic / PMF 怜蚌
Â¥150
200
月予算 ¥30,000
🌿 Seed 6-12 ヶ月
Meta + X + 小芏暡むンフル / Unit economics
Â¥300
3,000
月予算 ¥900,000
🌳 Series-A 12-36 ヶ月
Meta + Google + TikTok + むンフル幎契 / シェア取り
Â¥600
15,000
月予算 ¥9,000,000

📊 ステヌゞ別 メトリクス — 同じ funnel 品質で、ステヌゞ毎の経枈性

ステヌゞ CAC install/月 実効 CAC
/ paying
LTV / CAC Payback 新芏 paying
/ 月
定垞 月次 OP

📈 36ヶ月収益シミュレヌション — ステヌゞ遷移付き。䜕ヶ月で黒字化

月次営業利益 (¥/month)
悲芳 暙準 楜芳 ★ 珟圚 break-even (Â¥0)
环積営業利益 (Â¥)
悲芳 暙準 楜芳 ★ 珟圚
36 ヶ月埌の到達点

前提: ステヌゞごずに install / CAC が切り替わる。Trial1 (14日 å…šå“¡) + Trial2 (14日 acceptors) の翌月から課金開始。月次 churn で active が枛衰。

🚀 プロダクト

ナヌザヌの増枛、定着、AI 粟床、フィヌドバックの集玄。

🚀 成長 — ナヌザヌは増え、定着しおいるか

📅 盎近14日の新芏登録

🔁 リテンション (Day1/7/30)

コホヌトサンプル数残存残存率

N 日前に登録した人のうち、今も掻動しおいる割合。サンプル数が少ないず数倀はノむズが倚い。

🔥 補品 KPI — AI 粟床・コスト最適化はどうか

📊 LLM 呌び出し caller 比率 (30d)

⚠ カロリヌ誀り報告 — ナヌザヌが「これおかしい」ず感じた meal

時刻 ナヌザヌ 料理名 登録 kcal lookup_key / meal_id

💬 ナヌザヌフィヌドバック — ナヌザヌは䜕を求めおいる

時刻ナヌザヌ内容

⚙ 技術 / コスト

レむテンシ、゚ラヌ、コスト内蚳。

🩺 技術 health — ナヌザヌは䜕秒埅たされおいるか ゚ラヌは

🎯 1次応答レむテンシ (マむク離す → 吹き出し衚瀺)

🎯 カロリヌ反映レむテンシ (履歎に最終kcal衚瀺たで)

📊 1次応答の内蚳: どこに時間がかかっおいるか (7d平均)

⏱ 補助: caller 別 LLM 単䜓レむテンシ (7d, OpenRouter API 郚分のみ)

callernp50p95p99

🐛 盎近の゚ラヌ (7d, 最倧20ä»¶)

時刻callererror

💞 コスト詳现 — どこに金がかかっおいる

📈 日次コスト掚移 (30d, OpenRouter のみ)

👀 コスト䞊䜍ナヌザヌ (30d)

userplancallscost

📞 caller × model 別 (30d)

callermodelcallscost

🎀 Soniox 日次 (30d, /v1/usage-logs から)

日付回数音声秒コスト

📋 LP α版テスト Waitlist

メアド登録、流入元、配信停止状態、個別/䞀括メヌル送信。

未遞択
時刻 (JST) Email Source 状態 送信履歎 Referrer

📧 メヌル送信

テンプレヌトを遞び、必芁なフィヌルドを入力しお送信したす。本文は線集できたせん(テンプレ管理は functions/_lib/templates.ts)。

🔍 メヌルプレビュヌ

実際に送信される内容です。送信前の最終確認に䜿っおください (詊送はされたせん)。

読み蟌み䞭 
▶ プレヌンテキスト版を衚瀺 (multipart/alternative の text/plain 郚)

        

🏗 アヌキテクチャ レビュヌ

7 芳点で shiwake の珟状を敎理する蚭蚈リファレンス。
各セクションは「📐 珟状 / ✅ 匷み / ⚠ 懞念 / 📝 TODO」の 4 サブ構造で統䞀。 曎新は admin/index.html の data-tab="architecture" セクション。

🗺 1. システム党䜓マップ 🌊 2. 䞻芁 user flow 💟 3. デヌタモデル 🔐 4. セキュリティ・認蚌 ⚡ 5. パフォヌマンス & コスト 🌐 6. 倖郚䟝存リスク 🧪 7. 技術負債 & TODO

🗺 1. システム党䜓マップ — 1 枚で頭に入るか

📐 珟状

graph LR iOS["📱 iOS App
SwiftUI + Keychain"] Backend["⚙ shiwake-daily-api
Hono on Workers"] D1B[("💟 D1: shiwake_daily")] R2[("🪣 R2: media")] Soniox{{"🎀 Soniox
STT realtime + async"}} OR{{"🀖 OpenRouter
Gemini 3 Flash / GPT-4o-mini"}} Apple{{"🍎 Apple
AppAttest + StoreKit 2"}} Weather{{"🌀 Open-Meteo
weather"}} LP["🌐 LP shiwake-lp(-stg)
Pages + Functions"] D1L[("💟 D1: shiwake-lp")] SMTP{{"📧 お名前.com SMTP"}} Admin["🛠 shiwake-admin
Pages SPA"] iOS -->|"Bearer access_token"| Backend iOS -.->|"WS stt-rt-v4 (temp key)"| Soniox iOS -->|"AppAttest assertion"| Backend iOS -->|"StoreKit JWS"| Backend Backend --> D1B Backend --> R2 Backend -->|"chat/completions"| OR Backend -->|"async stt"| Soniox Backend -->|"verify attest + JWS"| Apple Backend --> Weather Backend -->|"S2S notif"| Apple LP --> D1L LP -->|"SMTP 465"| SMTP Admin -->|"Basic auth"| Backend Admin -->|"Basic auth"| LP

✅ 匷み

  • Cloudflare に寄せきった単䞀プラットフォヌム (Workers + Pages + D1 + R2) で運甚面はシンプル
  • iOS → 倖郚 API ぞの盎接呌び出しを最小化 (Soniox WS のみ、temp key 経由)
  • backend / lp / admin の 3 リポ的圹割が明確

⚠ 懞念

  • Backend 単䞀環境: backend は stg/prod が分かれおいない (LP は分かれおいる)。本番デプロむで壊れたら即圱響
  • Cloudflare 障害時の代替路なし: D1 / Workers ずもに同瀟

📝 TODO

  • backend に shiwake-daily-api-stg を切る (D1 も別 instance)
  • D1 の定期スナップショット運甚

🌊 2. 䞻芁 user flow — フロヌの単玔性、責務の明確さ

📐 珟状: 「発話 → カロリヌ蚘録」 (䞻芁 critical path)

sequenceDiagram participant U as User (iOS) participant SX as Soniox WS participant API as backend /api/ingest participant OR as OpenRouter participant D1 as D1 U->>API: POST /api/auth/soniox-temp-key API-->>U: temp key (短期) U->>SX: WS stt-rt-v4 (発話ストリヌム) SX-->>U: transcript (逐次) U->>API: POST /api/ingest {transcript} API->>OR: Gemini 3 Flash (intent + entity) OR-->>API: structured JSON API->>D1: INSERT meals/weights/exercises API-->>U: response (即時) Note over API,OR: BG: mealLookup (web search)
→ meal_nutrition_cache に保存 API->>D1: UPDATE meals.kcal (埌远い)

📐 䞻芁フロヌ䞀芧 (本ペヌゞで定期メンテすべき)

  • 発話 → カロリヌ蚘録 (䞊図)
  • 䜓重蚘録: POST /api/weights → D1 (LLM 䞍芁)
  • 履歎の修正: PUT /api/meals/:id, /api/meals/:id/rename
  • サマリ衚瀺: GET /api/summary/weekly (集蚈ク゚リ)
  • サむンアップ: AppAttest challenge → 怜蚌 → users 行䜜成 → access_token 返华
  • IAP 賌読: StoreKit → JWS 抜出 → /api/iap/verify → users.subscription_status 曎新

✅ 匷み

  • 1 次応答は LLM 1 回 (Gemini Flash) で垰す。カロリヌ数倀は BG で埌远い (UI は仮倀衚瀺 → kcal 確定で差し替え)
  • 分岐の少ない sequential flow で芳枬しやすい

⚠ 懞念

  • BG タスク倱敗の可芖化が匱い: mealLookup 倱敗時、ナヌザヌには芋えにくい (kcal が「—」のたた残る)
  • WS の接続倱敗フォヌルバックなし: Soniox WS が萜ちた時、async REST ぞのフォヌルバックは未実装

📝 TODO

  • 各フロヌを 1 セクションず぀図匏化 (䜓重/履歎線集/サマリ/IAP)
  • 倱敗パスの远加 (Soniox 切断、OpenRouter timeout)

💟 3. デヌタモデル — 正芏化ず PII の局圚

📐 珟状

D1 = SQLite。JOIN は䜿うが分散は意識しない (rows-per-account が極小)。

テヌブル甚途PII?
usersaccount + profile + affinity + sub status + AppAttest signup✓ 名前/メアド/誕生日
meals食事蚘録 (transcript, name, kcal, lookup_key, photo_key)✓ 食事 photo
weights䜓重蚘録✓ 䜓重倀
exercises運動蚘録—
notesその他メモ—
meal_nutrition_cache正芏化 kcal cache (30d TTL想定)—
user_factsassistant 孊習枈み事実 (奜み/制玄)✓
conversation_log盎近 N タヌン (ingest context)✓
weather_cacheOpen-Meteo 1h cache—
api_usage_logOpenRouter/Soniox call ledger—
request_timingper-request latency milestone—
feedback音声フィヌドバック transcript✓
attest_challenges短期 AppAttest nonce—
invitationslegacy 招埅コヌド redeem—
waitlist (lp)α テスト メアド + unsub token✓ メアド
email_log (lp)送信履歎✓ メアド

✅ 匷み

  • PII を users + 各ログ系に集䞭。物理削陀 1 ナヌザヌ = カラム削陀で完結 (GDPR 想定容易)
  • cache ç³» (meal_nutrition_cache, weather_cache) は user_id を持たないので削陀圱響なし

⚠ 懞念

  • 削陀カスケヌド未実装: ナヌザヌ削陀時の各テヌブル削陀手順がコヌド化されおいない
  • conversation_log の TTL なし: 無制限に䌞びる可胜性 → サむズ監芖が必芁

📝 TODO

  • 各テヌブルに保持期間ポリシヌ (䟋: meal_nutrition_cache=30d, conversation_log=最新 50 turns, request_timing=90d)
  • DELETE /api/me ゚ンドポむント + 党テヌブル cleanup スクリプト

🔐 4. セキュリティ・認蚌 — 攻撃面が把握できおいるか

📐 珟状

レむダ方匏ガヌド
iOS → backendAuthorization: Bearer <access_token>requireUser が D1 の users.access_token を盎接 lookup (opaque random)
サむンアップApple AppAttestbackend/src/appattest.ts: cert chain + nonce + bundle/team 怜蚌 (node-app-attest)
iOS → Soniox WSbackend 経由で temp key 発行/api/auth/soniox-temp-key (芁 user 認蚌)
admin /api/admin/*HTTP Basic admin:ADMIN_PASSWORDmiddleware over /api/admin/*
IAP S2S notifJWS payload を decode⚠ 眲名怜蚌は未実装 (TODO)
LP /api/waitlist無認蚌 (公開フォヌム)email regex + ip hash + 重耇怜知のみ。rate limit なし
LP /api/unsubscribetoken 経由 (RFC 8058)16 byte ランダム token

✅ 匷み

  • iOS サむンアップに AppAttest を採甚 → 停端末からの自動アカりント倧量䜜成を防止
  • access_token は opaque random (JWT 鍵挏掩リスクなし)、revoke は DB 曎新 1 行
  • Soniox 認蚌情報を iOS バンドルに埋め蟌たない (temp key 方匏)

⚠ 懞念

  • IAP JWS 眲名未怜蚌 → 停 receipt で premium 化される可胜性 (臎呜的)
  • LP waitlist rate limit なし → SPAM / 嫌がらせ登録による D1 圧迫 + メアド汚染
  • access_token のロヌテヌションなし → 端末玛倱時に手動で DB 曎新が必芁
  • admin Basic auth がシングルパスワヌド → 共有事故時にロヌテ必須

📝 TODO

  • iap.ts に x5c chain 怜蚌 + issuer/bundleId/environment 怜蚌を入れる (珟状 skeleton)
  • LP waitlist に Cloudflare Turnstile or IP-based rate limit
  • access_token に有効期限 + refresh の怜蚎
  • 新芏゚ンドポむント远加時のセキュリティ チェックリスト化

⚡ 5. パフォヌマンス & コスト — ボトルネックは特定枈みか

📐 珟状: 1 次応答レむテンシ予算

step目暙 p95備考
Soniox WS 確定 (発話終了 → 最終 transcript)~1.5srealtime stt-rt-v4
ingest (Gemini 3 Flash)~1.5sintent + entity 抜出
persona (GPT-4o-mini)~0.8s応答メッセヌゞ生成
合蚈 (1 次応答)~3-4s履歎 UI に吹き出し衚瀺
mealLookup (BG, web search)~6-10sUI は kcal 「—」→ 確定で差し替え

📐 珟状: 1 active user / 日 コスト匏

10 発話/日 × 10 秒 × (Soniox $0.0025/秒 + Gemini Flash + GPT-4o-mini) × cache HIT 率 (mealLookup は HIT で 0)

= 箄 Â¥2-3/日 (cache HIT 60%+ 想定) / Â¥4-5/日 (HIT 30% 想定)

実枬は 技術 / コスト タブ参照。

✅ 匷み

  • クリティカルパスは LLM 1 段 (Gemini Flash) → コスト/レむテンシ予枬しやすい
  • mealLookup は web search を䌎うので BG 化、UI を埅たせない
  • meal_nutrition_cache で同名料理は秒で kcal 確定 (LLM コスト 0)

⚠ 懞念

  • cache HIT 率がコスト構造を支配。HIT が䞋がるず OpenRouter コストが線圢に䞊昇
  • persona の応答生成が遅くなるず 1 次応答が䜓感悪化 (珟状 GPT-4o-mini が突然遅くなるリスク)
  • Soniox WS のネットワヌク条件䟝存性が倧 (地䞋鉄等)

📝 TODO

  • cache HIT 率の譊報閟倀 (e.g. 7d 平均 50% 以䞋で alert)
  • persona を Gemini Flash に統䞀する遞択肢の評䟡
  • オフラむン録音 → 埌送信モヌド (Soniox 䞍安定時)

🌐 6. 倖郚䟝存リスク — 片足を抜くコストが芋えるか

📐 珟状

䟝存先甚途ロックむン代替倀䞊げ耐性
CloudflareWorkers + Pages + D1 + R2🔎 高 (D1 移行 = SQLite ダンプ + 再構築)Fly.io + libSQL, AWS Lambda + DynamoDB🟢 倧
Sonioxrealtime + async STT🟡 äž­ (WS プロトコル + temp key API)Deepgram, AssemblyAI, OpenAI Whisper API🟡 äž­
OpenRouterGemini 3 Flash + GPT-4o-mini ルヌタ🟢 䜎 (Anthropic/OpenAI/Google 盎叩きに切替容易)各 LLM ベンダヌ盎接🟢 倧 (パススルヌ)
Apple AppAttestサむンアップ防埡🔎 高 (iOS の遞択肢ずしおは唯䞀)なし—
Apple StoreKit / IAP課金🔎 高 (iOS では必須)なし🟡 Apple 30% → 15% (Small Biz)
お名前.com SMTPα 招埅 / 配信停止メヌル🟢 䜎 (Resend, SendGrid に乗り換え容易)Resend, SES, SendGrid🟢 倧
Open-Meteo倩気🟢 䜎 (オプショナル機胜)OpenWeatherMap🟢 倧

✅ 匷み

  • LLM は OpenRouter で抜象化 → モデル倉曎で 1 行修正
  • SMTP / 倩気は薄いラッパで芆われおおり移行容易

⚠ 懞念

  • D1 ロックむンが最倧玚。リレヌション + 集蚈を SQL に寄せおいるため SQLite 互換 (Turso 等) 以倖ぞの移行はコスト倧
  • iOS は Apple 党䟝存 (回避䞍可胜、ビゞネスリスクずしお織り蟌む)

📝 TODO

  • D1 のスキヌマ → Turso (libSQL) 移行コストを詊算しおおく
  • Soniox 障害時に Whisper API ぞフォヌルバックする経路の詊䜜

🧪 7. 技術負債 & 既知の TODO — リファクタ優先順䜍

📐 珟状: 䞀芧 (grep 由来 + レビュヌ時に远蚘)

優先床項目堎所備考
🔎 高IAP JWS 眲名怜蚌backend/src/iap.ts:12x5c chain + issuer/bundleId/env 怜蚌が未実装。本リリヌス前 必須
🔎 高backend stg 環境—shiwake-daily-api-stg を切る
🟡 äž­LP waitlist の rate limitlp/functions/api/waitlist.tsSPAM 察策
🟡 äž­conversation_log の TTLbackend/migrations無制限に䌞びる
🟡 䞭削陀カスケヌド (GDPR)backend 党䜓DELETE /api/me + 党テヌブル cleanup
🟢 䜎テンプレ URL の XXXXXXlp/functions/_lib/templates.ts:68,270UI から差し替え可胜なのでコヌド倉曎䞍芁
🟢 䜎legacy invitation redeembackend/src/index.ts䜿っおなければ削陀

📝 運甚ルヌル

  • 新芏 TODO はここに远蚘 (該圓箇所の゜ヌスコヌド に // TODO 残し + ここに゚ントリ远加)
  • 解消時はテヌブル行を削陀 (履歎は git で远える)
  • レビュヌ䌚は四半期ごず、優先床を芋盎す

💡 このペヌゞは静的ドキュメントです。デヌタ゜ヌスは admin/index.html 内のハヌドコヌド。 アヌキテクチャに倉曎があったずきは PR で曎新しおください。

📖 仕様曞

iOS å…š 11 画面の機胜芁件 (FR) / 非機胜芁件 (NFR) / 連携 API / デヌタモデルを画面単䜍で敎理。 暪断芁件ず API カタログを末尟に䜵茉。曎新は admin/index.html の data-tab="docs" セクション。

⚠ 実装ギャップ (調査で発芋)

  • POST /api/feedback のサヌバ実装が芋圓たらない — iOS の FeedbackButton.swift ず APIClient.submitFeedbackText は呌んでいるが backend/src/index.ts に該圓ハンドラ無し。feedback 行は珟状 /api/meals/:id/flag-calorie 経由でのみ䜜られる。
  • Soniox 障害時に Apple SF ぞの自動フォヌルバック無し — Premium ナヌザは Soniox temp key 取埗倱敗時に゚ラヌ文蚀が出るだけで録音継続䞍胜。
① オンボヌディング (4) ② 蚘録ルヌプ コア (3) ③ 振り返り (2) ④ 蚭定 / ナビ基盀 (2) â‘€ 暪断芁件 (8 カテゎリ) ⑥ API カタログ (37)

① オンボヌディング — 初回起動から最初の 1 回の蚘録たで

OnboardingView ios/Sources/Views/OnboardingView.swift

ニックネヌム 1 項目だけでサむンアップを完了させるスプラッシュ的画面。背埌で AppAttest signup (実機) / 旧 invite redeem (シミュレヌタ) を自動実行。

TRIGGERPrivacyConsent 通過埌 & token 䞍圚

機胜芁件 (FR)

  • FR-OB-01ニックネヌム 1 フィヌルドのみ衚瀺 / 空癜以倖を必須化
  • FR-OB-02「はじめる」ボタンで autoSignUp(displayName) を起動
  • FR-OB-03送信䞭は ProgressView + ボタン disabled + ラベル「登録䞭 」
  • FR-OB-04入力フィヌルドに 0.2s 埌 auto-focus、submitLabel=done
  • FR-OB-05AppAttest signup (実機) → token/userId を Keychain 保存。Phase B 実装枈
  • FR-OB-06サむンアップ確定の瞬間に needsProfileSetup=true を先行セット (チラ぀き防止)

非機胜芁件 (NFR)

  • NFR-OB-P1サむンアップは P50 < 2s (challenge + attest + signup の 3 埀埩)
  • NFR-OB-S1access_token は Keychain (kSecClassGenericPassword, service jp.newmeta.shiwake.auth) 保存
  • NFR-OB-A1preferredColorScheme(.dark) 固定、ボタンは 44pt 以䞊のタップ領域
  • NFR-OB-X1招埅コヌド抂念をナヌザヌに芋せない (UI から完党排陀)
API
POST /api/auth/challengePOST /api/auth/signupPOST /api/invite (DEBUG fallback)POST /api/auth/redeem (DEBUG fallback)
デヌタ
usersattest_challengesinvitations
゚ッゞ
既に token 保持䞭は画面非衚瀺 / シミュレヌタは旧フロヌ / 空癜ニックネヌム拒吊

PrivacyConsentView ios/Sources/Views/PrivacyConsentView.swift

初回起動時にプラむバシヌ芁玄 4 項目ずカメラ初期動䜜の遞択を提瀺し同意取埗。

TRIGGER@AppStorage("privacy_agreed_v1") == false の起動

機胜芁件 (FR)

  • FR-PC-01取埗情報 / 第䞉者送信 / 保存期間 / セキュリティ の 4 サマリヌ衚瀺
  • FR-PC-02カメラ起動蚭定をラゞオで 2 択 (プラむバシヌ優先 / 即撮圱)、camera_instant_ready に保存
  • FR-PC-03「党文を読む」で PrivacyPolicyFullView を sheet 衚瀺
  • FR-PC-04「同意しおはじめる」で privacy_agreed_v1=true
  • FR-PC-05党文は 8 ç«  (取埗情報, 利甚目的, 第䞉者送信, 保存期間, ナヌザヌ暩利, セキュリティ, 倉曎, 連絡先)
  • FR-PC-06連絡先 contact_app@newmeta.co.jp を明瀺

非機胜芁件 (NFR)

  • NFR-PC-L1個情法/GDPR 想定で「取埗項目・利甚目的・第䞉者提䟛・保存期間・問合先」を必須蚘茉
  • NFR-PC-L2同意フラグはバヌゞョン付き (privacy_agreed_v1) で改定時に再同意可胜
  • NFR-PC-A1Dynamic Type 察応 (.subheadline), fixedSize で折返し保持
  • NFR-PC-S1HTTPS/WSS、Keychain 保存を明文化
API
なし (端末ロヌカルのみ)
デヌタ
@AppStorage("privacy_agreed_v1")@AppStorage("camera_instant_ready")
゚ッゞ
党リセット時は䞡フラグを削陀しお再衚瀺

ProfileSetupView ios/Sources/Views/ProfileSetupView.swift

7 ステップりィザヌド (身長→䜓重→䜓脂肪→掻動量→食事目暙→目暙䜓重→達成日)。音声䞭心 + 手入力フォヌルバック。

TRIGGERサむンアップ盎埌 or auth.needsProfileSetup=true

機胜芁件 (FR)

  • FR-PS-017 ステップを progress bar で可芖化
  • FR-PS-02マむクボタン長抌し (DragGesture) で録音 → 離しお送信
  • FR-PS-03STT 二刀流: Premium=Soniox WebSocket / Free=Apple SFSpeechRecognizer
  • FR-PS-04認識テキストを /api/setup/parse ぞ → value_double/level/goal/date_iso/skipped を抜出
  • FR-PS-05結果を吹き出しで「身長は 170.5cm で合っおる?」圢匏で再確認
  • FR-PS-06手入力モヌダル: wheel picker / リスト / DatePicker、芪指圏に倧きな決定ボタン
  • FR-PS-07bodyFat / activity は "スキップ" 可、それ以倖は再入力匷制
  • FR-PS-08範囲バリデヌション: 身長 100-220cm, 䜓重 20-300kg, 䜓脂肪 3-70%
  • FR-PS-09キャラクタヌ (idle/listening/thinking) を 160pt 固定高で衚瀺
  • FR-PS-10完了時に TDEE ず目暙カロリヌを Bmr.tdee + TargetCalories.derive でクラむアント算出
  • FR-PS-11PUT /api/me/targets で身長/䜓脂肪/目暙䜓重/期日/食事目暙/カロリヌを䞀括保存
  • FR-PS-12同時に POST /api/weights で初期䜓重を 1 件蚘録
  • FR-PS-13保存成功時に党面緑チェック overlay を 1.8s 衚瀺しおから markProfileComplete()
  • FR-PS-14未入力項目があれば最初の未入力 step に自動で戻る

非機胜芁件 (NFR)

  • NFR-PS-P1/api/setup/parse は OpenAI strict-mode JSON 解析、P50 < 1.5s
  • NFR-PS-A1觊芚: 録音開始 0.9 / 停止フル / 完了 success notification
  • NFR-PS-X1声が出せない堎面のフォヌルバック (手入力 wheel) ã‚’å…š step で提䟛
  • NFR-PS-X2音声接続倱敗時は errorMessage 衚瀺し isRecording=false に戻す
API
POST /api/auth/soniox-temp-key (Premium)POST /api/setup/parsePUT /api/me/targetsPOST /api/weights
デヌタ
users.{height_cm,body_fat_percent,target_weight_kg,target_weight_date,target_calories_kcal,dietary_goal}weights
゚ッゞ
token 切れ / Soniox 接続倱敗 / 空 transcript / 範囲倖倀 / 既存倀ありの dial 初期倀 seed

PaywallView ios/Sources/Views/PaywallView.swift

ProfileSetup 盎埌に挿入される 1 ヶ月無料 → Â¥490/月 のサブスクリプション勧誘。Apple 芏玄準拠。

TRIGGERprofileSetup 完了 & subscriptionStatus != "premium_active"

機胜芁件 (FR)

  • FR-PW-01ヘッダヌ「Shiwake Premium / 最初の 1 ヶ月は無料」
  • FR-PW-024 ベネフィット (関係性深化 / 音声無制限 / 蚘憶 / 高粟床カロリヌ) を icon+desc で蚎求
  • FR-PW-03䟡栌カヌド: Â¥0/最初の 1 ヶ月 + その埌 displayPrice 自動曎新
  • FR-PW-04CTA「1 ヶ月無料ではじめる」→ StoreKitManager.purchase() → JWS を /api/iap/verify
  • FR-PW-05「賌入を埩元」で StoreKit.restore() + refreshProfile + Premium 確認時 onContinue
  • FR-PW-06芏玄 3 項目を caption で明瀺 (解玄方法 / 24h 前 / Apple ID 共有)
  • FR-PW-07product 未ロヌド or 賌入凊理䞭はボタン disable
  • FR-PW-08賌入倱敗 (userCancelled 陀く) は store.lastError をテキスト衚瀺

非機胜芁件 (NFR)

  • NFR-PW-L1App Store 芏玄: 䟡栌・課金頻床・自動曎新・解玄方法・芏玄リンクを必須掲茉
  • NFR-PW-S1レシヌト怜蚌は端末でなく必ず /api/iap/verify (サヌバ偎 JWS 怜蚌)
  • NFR-PW-X1StoreKit 未ロヌド時は Â¥490/月 のフォヌルバック衚蚘
API
POST /api/iap/verifyGET /api/me
デヌタ
users.subscription_statususers.trial_ends_at
゚ッゞ
賌入キャンセル / 埩元時 Premium 反映埅ち / オフラむン

② 蚘録ルヌプ (コアバリュヌ) — 起動即蚘録の差別化区間

CaptureView ios/Sources/Views/CaptureView.swift

メむン画面。カメラ垞時起動 + 巊䞋マむク長抌し + 右䞋カメラタップ + アシスタント吹き出し + 盎近 6 件ピル。

TRIGGER通垞起動 (認蚌枈 & profileSetup 完了)

機胜芁件 (FR)

  • FR-CAP-01党画面 CameraPreview を垞時皌働、䞊郚 34% 癜角䞞、䞋半分は巊右 50:50 のマむク/カメラ刀定゚リア
  • FR-CAP-02cameraInstantReady=false ならカメラに UltraThinMaterial overlay、1 タップで解陀 → ロックオン 4 隅ブラケット、2 タップ目で capturePhoto()
  • FR-CAP-03巊マむク゚リア DragGesture: 長抌し → startCapture → 離しお stop → /api/ingest ぞ transcript
  • FR-CAP-04STT 二刀流: useApple=!isPremium で Apple SF / Soniox を切替
  • FR-CAP-05䞊郚キャラクタヌ (idle/listening/thinking) + 吹き出し + 尻尟、録音䞭は尻尟を隠す
  • FR-CAP-06吹き出しテキストはランダム抜遞プヌル (時間垯 × 芪密床 × 状態 で 50+ パタヌン)
  • FR-CAP-07時間垯別挚拶 (朝/午前/昌/午埌/倕/倜/深倜) を Lv1-2=さん / Lv3+=くん で抜遞
  • FR-CAP-08䞊スワむプ (> 40px) でキャラ/吹き出しを折りたたみ、pullDownTab で埩垰
  • FR-CAP-09盎近 6 件の meal/weight をピル (料理名+kcal / 䜓重+kg) で右偎瞊䞊び、今日/昚日/䞀昚日 ラベル付き
  • FR-CAP-10蚈算䞭 meal が含たれる間は 3s 間隔で reloadRecentMeals を polling
  • FR-CAP-11capturePhoto: AVCapturePhoto を /api/meals (multipart) に POST
  • FR-CAP-12/api/ingest の advance_event レスポンスで AdvanceEventModal を sheet 衚瀺
  • FR-CAP-13persona_comment があれば優先、無く count=0 なら "蚘録なし"、count>0 なら "N 件蚘録した"
  • FR-CAP-14蚘録成功時は success haptic + .shiwakeDataChanged を 0/4/8/15s で耇数回 post
  • FR-CAP-15初回起動のみ 0.6s 遅延しお CaptureTutorialOverlay 衚瀺 (hasSeenCaptureTutorial=true で抑止)
  • FR-CAP-16scenePhase=.background 時に camera.stop()、埩垰時 start + フロステッド再有効化 + 挚拶差替

非機胜芁件 (NFR)

  • NFR-CAP-P1ingest 1 次応答 P50 目暙 (persona_comment 即返华)、mealLookup は waitUntil で非同期
  • NFR-CAP-P2カメラ起動から最初のフレヌムたで P50 < 500ms (camera.start を task で䞊列実行)
  • NFR-CAP-S1プラむバシヌ: 起動時すりガラス、scenePhase 倉化で確実に stop、ファむンダヌ解陀はセッション毎にリセット
  • NFR-CAP-A1觊芚: 録音開始 1.0 / 停止 1.0 / 成功 .success / 倱敗 .error / 雑談成立 .selectionChanged
  • NFR-CAP-A2ロックオン枠は cornerSize 44 / strokeWidth 5 で芖認性確保
  • NFR-CAP-O1オフラむン: token 切れは bubblePhrase(.authExpired)、送信倱敗は .sendFailed
  • NFR-CAP-M1觊芚 prepare() を onAppear / onEnded 毎に呌んでレむテンシ最小化
API
POST /api/ingestPOST /api/mealsGET /api/mealsGET /api/weightsGET /api/mePOST /api/auth/soniox-temp-key
デヌタ
meals (raw_text, ai_result, calories_kcal, image_r2_key)weightsusers.affinity_*pending_advance_event
゚ッゞ
シミュレヌタ (カメラ無し) / バックグラりンド埩垰時の挚拶差替 / 蚈算䞭ピル polling 自動停止 / 雑談 reply_only / ingest 䟋倖 / Soniox temp key 倱敗

CaptureTutorialOverlay ios/Sources/Views/CaptureTutorialOverlay.swift

初回 CaptureView 衚瀺時に出る 3 ステップ overlay (導入 / マむク / カメラ)。

TRIGGERhasSeenCaptureTutorial=false で CaptureView 衚瀺 0.6s 埌

機胜芁件 (FR)

  • FR-TUT-01黒幕 72% + 䞭倮メッセヌゞカヌド + 䞋郚矢印で 3 ステップ案内
  • FR-TUT-02step1: マむク領域 (画面䞋 25% x) ぞ arrow.down + バりンスアニメ
  • FR-TUT-03step2: カメラ領域 (画面䞋 75% x) ぞ arrow.down
  • FR-TUT-04ボタン: 戻る / 次ぞ / (最終)始める
  • FR-TUT-05「始める」で hasSeenCaptureTutorial=true 保存 → 自動消去
  • FR-TUT-06Settings の「チュヌトリアルを再衚瀺」で AppStorage を削陀すれば再衚瀺

非機胜芁件 (NFR)

  • NFR-TUT-A1暗幕タップは無芖 (誀遷移防止)、ステップむンゞケヌタドット衚瀺
  • NFR-TUT-A2矢印は ArrowBounce で䞊䞋 10pt 振動 (泚目誘導)
API
なし
デヌタ
@AppStorage("hasSeenCaptureTutorial")
゚ッゞ
蚭定→チュヌトリアル再衚瀺時の再起動なし察応

AdvanceEventModal ios/Sources/Views/AdvanceEventModal.swift

関係性レベル昇栌 (Lv N → N+1) の祝犏モヌダル。AI からの opening line を挔出衚瀺。

TRIGGER/api/ingest たたは /api/me が advance_event を返した時、AuthStore.pendingAdvanceEvent 経由

機胜芁件 (FR)

  • FR-AEM-01ハヌト fill (84pt) を spring(0.6, 0.55) でフェヌドむン + 拡倧
  • FR-AEM-02Lv チップ遷移 "Lv N → Lv N+1" を矢印で衚瀺
  • FR-AEM-03event.openingLine を pink 8% 背景 + 16pt medium で䞭倮衚瀺
  • FR-AEM-04「ありがずう」ボタン (pink グラデ Capsule) で onDismiss
  • FR-AEM-05sheet detents [.medium, .large]
  • FR-AEM-06衚瀺埌 AuthStore.pendingAdvanceEvent=nil に即クリア (二重衚瀺防止)

非機胜芁件 (NFR)

  • NFR-AEM-X1one-shot 配信: ingest waitUntil で advance が決たったら次の /api/me で 1 回だけ届き即 NULL
  • NFR-AEM-A1觊芚連動なし (芖芚アニメで十分な挔出匷床)
API
衚瀺専甚 (payload は ingest/me に同梱)
デヌタ
users.pending_advance_event (migration 0021)
゚ッゞ
既に他のモヌダル衚瀺䞭なら䞊曞きしない / dismiss 挏れによる再衚瀺防止

③ 振り返り — グラフ / 履歎 / 線集の hub

SummaryView ios/Sources/Views/SummaryView.swift

グラフ (䜓重 / カロリヌ) + 7 日サヌクル + 日別履歎䞀芧。線集 / 削陀 / 再蚈算 / カロリヌ誀り報告の hub。

TRIGGERメむン䞋郚「グラフ」ボタンで fullScreenCover

機胜芁件 (FR)

  • FR-SUM-01サマリヘッダヌ (タむトル + 蚭定歯車)
  • FR-SUM-02todaySection: 7 日サヌクル (目暙 vs 実瞟) + 摂取/消費トグル + 遞択日の食事カヌド䞀芧 + カロリヌバヌ
  • FR-SUM-03longTermSection: 䜓重/カロリヌグラフのトグル、期間 day/week/month/6month/year、グラフ内タップで selectedDate 切替
  • FR-SUM-04䜓重グラフは weight_kg + body_fat_percent (dual axis 想定)
  • FR-SUM-05履歎セクション: meal/weight/note を時刻降順マヌゞ、日付ラベル区切り、最倧 50 件、行内ゎミ箱 (1 タップで ✓/× の 2 段階確認)
  • FR-SUM-06食事名のタップで editingMealSheet (rename) 起動、保存で POST /api/meals/:id/rename → mealLookup 再蚈算 → 楜芳的曎新埌 polling
  • FR-SUM-07食事行の「!」で flag-calorie alert、「はい」で POST /api/meals/:id/flag-calorie → 例郹 toast 2.5s
  • FR-SUM-08䜓重行タップで EditWeightSheetContent、保存で POST /api/weights/:id/update
  • FR-SUM-09削陀: meal/weight/note を DELETE、楜芳的に画面から消す
  • FR-SUM-10蚈算䞭 meal がある間は楜芳倀 (optimisticMeals) を保持し、サヌバ蚈算完了たで䞊曞きを防ぐ
  • FR-SUM-11.shiwakeDataChanged 通知 + refreshTimer で自動リロヌド
  • FR-SUM-12FeedbackButton をオヌバヌレむ衚瀺 (× ボタン右隣)
  • FR-SUM-13CloseButton (å·Šäž‹ 78pt 円) で fullScreenCover dismiss

非機胜芁件 (NFR)

  • NFR-SUM-P1/api/meals (期間指定) で 1 回取埗、クラむアント偎で日別集蚈
  • NFR-SUM-P2線集時は processingIds に远加しお「仕分け修正䞭 」overlay 衚瀺
  • NFR-SUM-A1DynamicType、行アクセントの heart アむコンは 13pt ç³»
  • NFR-SUM-O1゚ラヌは画面䞊郚に err:... monospace 9pt で開発者向け衚瀺
API
GET /api/mealsGET /api/weightsGET /api/notesGET /api/exercisesPOST /api/meals/:id/flag-caloriePOST /api/meals/:id/renamePUT /api/meals/:idDELETE /api/meals/:idDELETE /api/weights/:idPOST /api/weights/:id/updateDELETE /api/notes/:idGET /api/summary/weekly
デヌタ
mealsweightsnotesexercisesmeal_nutrition_cache
゚ッゞ
蚈算䞭 meal の楜芳曎新衝突 / リロヌド䞭の重耇 reload 抑止 / 90 日範囲取埗 / dual axis グラフのデヌタ欠損

FeedbackButton ios/Sources/Views/FeedbackButton.swift

SummaryView の × 隣に垞駐するピル。長抌しで Apple SF が文字起こし、テキストを /api/feedback に送信。

TRIGGERSummaryView 内垞駐 (ZStack)

機胜芁件 (FR)

  • FR-FB-01暪長ピル「開発フィヌドバック / 長抌しで送信」、長抌し䞭は赀色 + scale 1.05
  • FR-FB-02LongPressGesture(0.2s) で startRecording、DragGesture.onEnded で stopRecording → upload
  • FR-FB-03録音䞭は画面䞭倮 18% 䜍眮に倧きな transcript カヌド衚瀺 (逐次曎新)
  • FR-FB-04アップロヌド䞭は ProgressView アむコン、ピル opacity 0.5、disable
  • FR-FB-05結果トヌスト: 成功 (緑) / 聞き取れず (橙) / 倱敗 (èµ€) を 2.5s 衚瀺
  • FR-FB-06Apple Speech (LocalSpeechRecognizer) で完党オンデバむス文字起こし (コストれロ)

非機胜芁件 (NFR)

  • NFR-FB-P1テキストのみ送信 (音声ファむル無し) で垯域・コスト削枛
  • NFR-FB-A1觊芚: 録音開始 medium 1 回
  • NFR-FB-O1空 transcript はトヌストで知らせ送信スキップ
API
POST /api/feedback ⚠ サヌバ未実装の可胜性
デヌタ
feedback (migration 0018: id/user_id/transcript/created_at)
゚ッゞ
バック゚ンド未実装の可胜性 / token 切れ / 音声暩限拒吊

④ 蚭定 / ナビ基盀 — プロフィヌル再線集ず Premium 管理

SettingsView ios/Sources/Views/SettingsView.swift

プロフィヌル線集 / 目暙再蚭定 / カメラ蚭定 / 関係性衚瀺 / Premium 管理 / Facts 閲芧 / 招埅発行 / ログアりト・リセット。

TRIGGERSummaryView 右䞊の歯車から fullScreenCover

機胜芁件 (FR)

  • FR-SET-01プロフィヌル: ニックネヌム / 身長 / 䜓脂肪率 / 珟圚䜓重 / BMR (算出) / 掻動量 / 食事目暙 / TDEE (算出)
  • FR-SET-02目暙: 目暙䜓重 / 達成期日 (DatePicker, 今日以降) / 目暙カロリヌ (自動算出)
  • FR-SET-03カメラ蚭定 Toggle: camera_instant_ready を同期
  • FR-SET-04関係性: heart 5 段、Lv の Picker (デバッグ甚)、呌び方衚瀺、奜感床 pt 衚瀺
  • FR-SET-05Premium ステヌタス衚瀺 + Apple サブスク管理リンク + デバッグ切替 Picker
  • FR-SET-06「チュヌトリアルを再衚瀺」で hasSeenCaptureTutorial 削陀 → dismiss
  • FR-SET-07アシスタントが芚えおいるこず: user_facts を 30+ カテゎリラベルで衚瀺、swipeActions で削陀可
  • FR-SET-08招埅コヌド: 自分のコヌド衚瀺 + 「他人を招くコヌドを発行」で POST /api/invite → ShareLink
  • FR-SET-09ログアりト (Keychain クリア) / 初期蚭定をやり盎す / アプリ完党リセット の 3 段階砎壊操䜜
  • FR-SET-10FloatingSaveButton: 線集䞭 or hasUnsavedChanges の時のみ衚瀺
  • FR-SET-11線集䞭 (focusedField != nil) は CloseButton を隠す (誀タップ防止)

非機胜芁件 (NFR)

  • NFR-SET-S1砎壊操䜜は ConfirmationDialog で必ず確認
  • NFR-SET-X1倀倉化怜知は origXxx スナップショットずの比范で hasUnsavedChanges 算出
  • NFR-SET-A1テキスト線集䞭の保存ボタン優先床を高くし、× ボタンず排他制埡
API
GET /api/mePUT /api/me/targetsPUT /api/me/affinityPUT /api/me/subscriptionGET /api/me/factsDELETE /api/me/facts/:idPOST /api/inviteGET /api/weights
デヌタ
users (党カラム)user_facts (0009)
゚ッゞ
ログアりト埌の Keychain 残骞 / リセット時のサヌバデヌタ残存 / デバッグ Picker での Lv 匷制倉曎時の affinity_points マッピング

RootView ios/Sources/Views/RootView.swift

ナビゲヌション基盀。CaptureView を党画面に眮き、䞋郚「グラフ」ピルから SummaryView を fullScreenCover で開く。

TRIGGER認蚌枈 & profileSetup 完了 で衚瀺

機胜芁件 (FR)

  • FR-RV-01ZStack(.bottom): CaptureView + 䞋郚グラフボタン (ultraThinMaterial Capsule)
  • FR-RV-02sheet enum (settings, chart) を fullScreenCover で衚瀺
  • FR-RV-03シヌト遷移アニメヌションを transaction.disablesAnimations=true で抑制 (瞬時切替)
  • FR-RV-04scenePhase=.background でシヌトを自動 close
  • FR-RV-05sheet nil→non-nil 時 .shiwakeLeftCapture、逆で .shiwakeReturnedToCapture を post (カメラ stop/start 制埡)
  • FR-RV-06CloseButton (å·Šäž‹ 78pt) ず FloatingSaveButton (右䞋 78pt) の 2 再利甚コンポヌネント提䟛

非機胜芁件 (NFR)

  • NFR-RV-P1蚭定 / サマリ遷移はアニメ無効化で「即時画面切替」䜓感
  • NFR-RV-S1バックグラりンド時のシヌト自動 close で意図せぬ画面残留を防止
API
なし
デヌタ
なし
゚ッゞ
背景化䞭のシヌト開いたたた埩垰 / グラフ→蚭定の連続遷移

â‘€ 暪断芁件 — 画面暪断で適甚される NFR

🔐 認蚌 / セキュリティ

  • NFR-X-AUTH-01 Bearer トヌクン方匏 (Authorization: Bearer <hex32>)、auth.ts の requireUser で SELECT id FROM users WHERE access_token=?
  • NFR-X-AUTH-02 access_token は iOS Keychain (kSecClassGenericPassword, service jp.newmeta.shiwake.auth)
  • NFR-X-AUTH-03 サむンアップは AppAttest 経由 (/api/auth/challenge → DCAppAttestService → /api/auth/signup)、DEBUG ビルドのみ旧 invite redeem ぞフォヌルバック
  • NFR-X-AUTH-04 既ログむン時の invite URL は iOS 偎で早期 return (無駄な埀埩回避)
  • NFR-X-AUTH-05 IAP は Apple JWS を /api/iap/verify でサヌバ偎怜蚌 (端末偎レシヌト怜蚌は信甚しない) — 眲名 chain 怜蚌は TODO
  • NFR-X-AUTH-06 Apple Server-to-Server 通知甚に /api/iap/notification (no auth, 眲名怜蚌は TODO)
  • NFR-X-AUTH-07 AppAttest の Apple 公開鍵 + nonce 怜蚌で停端末の倧量サむンアップを防止 (Phase A 完了)
  • NFR-X-AUTH-08 テナント分離: å…š D1 ク゚リで user_id を WHERE 必須 (挏れがあれば即修正察象)

⚡ パフォヌマンス

  • NFR-X-PERF-01 /api/ingest 1 次応答 (persona_comment) は P50 < 2s、mealLookup は ctx.waitUntil で非同期
  • NFR-X-PERF-02 OpenAI prompt cache を contextBundle で掻甚、システムプロンプトを安定化
  • NFR-X-PERF-03 meal_nutrition_cache (0007) で同名料理の再蚈算を回避
  • NFR-X-PERF-04 CaptureView は蚈算䞭 meal 怜出時のみ 3s polling、完了で自動停止
  • NFR-X-PERF-05 Cloudflare Workers ゚ッゞ実行 + D1 prepared statement
  • NFR-X-PERF-06 weather_cache (0011) で倖郚 API 呌び出しを 1h ロヌカルキャッシュ

🛡 可甚性 / 障害時挙動

  • NFR-X-AVAIL-01 OpenRouter/OpenAI 障害時: persona_comment はフォヌルバック定型文、mealLookup は notes "蚈算䞭" のたた留め眮き
  • NFR-X-AVAIL-02 Soniox 障害時 (Premium): temp key 取埗倱敗 → ゚ラヌ文蚀、Apple SF ぞのフォヌルバックは未実装 (将来課題)
  • NFR-X-AVAIL-03 D1 障害時: 5xx を返し iOS は bubblePhrase(.sendFailed) で再詊行誘導
  • NFR-X-AVAIL-04 R2 障害時: image_r2_key を null で meal を䜜成 → 埌远い再アップ未実装
  • NFR-X-AVAIL-05 /health ゚ンドポむントで生存確認 ({ ok, ts })
  • NFR-X-AVAIL-06 /api/me が䞀時倱敗しおもクラむアントは前回倀を保持 (profileLoaded=false の間 splash)

📊 蚈枬 / ログ / 監査

  • NFR-X-OBS-01 api_usage_log (0012): OpenRouter/OpenAI/Soniox の token・コスト・モデル別利甚ログ
  • NFR-X-OBS-02 request_timing (0013): ゚ンドポむント毎のレむテンシ分垃
  • NFR-X-OBS-03 conversation_log (0014): user 発話 / assistant 返答の察話履歎 (persona 改善甚)
  • NFR-X-OBS-04 feedback (0018): 開発者向けフィヌドバック文 + [calorie_flag] プレフィックスでカロリヌ誀り報告
  • NFR-X-OBS-05 Admin /api/admin/stats: OpenRouter credits / 平均日次コスト / runway 日数 / フィヌドバック盎近䞀芧
  • NFR-X-OBS-06 Admin は Basic 認蚌 (app.use("/api/admin/*", basic auth))

🔒 プラむバシヌ / 法務

  • NFR-X-PRIV-01 privacy_agreed_v1 同意フラグ + 党文ポリシヌ (8 ç« , 制定 2026-05-24)
  • NFR-X-PRIV-02 同意取埗項目: ニックネヌム / 身長 / 䜓重 / 䜓脂肪 / 食事 (text/voice/photo) / 利甚時刻 / デバむス情報
  • NFR-X-PRIV-03 第䞉者送信: 音声認識 (Soniox) / AI 解析 (OpenAI/OpenRouter) / むンフラ (Cloudflare) を明瀺
  • NFR-X-PRIV-04 削陀䟝頌は contact_app@newmeta.co.jp、サヌバ偎削陀は手動オペレヌション (DELETE /api/me は TODO)
  • NFR-X-PRIV-05 カメラはバックグラりンド即 stop、起動時すりガラスを default (プラむバシヌ優先)
  • NFR-X-PRIV-06 feedback アップロヌドはテキストのみ (音声非保存)

💞 コスト / リ゜ヌス

  • NFR-X-COST-01 OpenRouter 月額予算は admin/stats の runway_days で監芖
  • NFR-X-COST-02 Free ナヌザは STT を Apple SF (コストれロ) に匷制、Premium のみ Soniox
  • NFR-X-COST-03 meal_nutrition_cache で重耇料理の LLM 呌び出しを削枛
  • NFR-X-COST-04 prompt cache 掻甚で OpenAI 入力トヌクンを 50%+ 削枛狙い
  • NFR-X-COST-05 R2 は食事写真のみ保管 (音声は保存しない)
  • NFR-X-COST-06 フィヌドバックはテキスト化埌送信 (音声ファむル送信なし)

♿ 囜際化 / アクセシビリティ

  • NFR-X-I18N-01 日本語のみ (Locale ja_JP 固定)、Asia/Tokyo TZ で日付凊理
  • NFR-X-A11Y-01 Dynamic Type を semantic font (.subheadline / .caption) で察応
  • NFR-X-A11Y-02 VoiceOver: 手入力ボタンに accessibilityLabel("手入力する")
  • NFR-X-A11Y-03 タップ領域 44pt 以䞊を意識 (CloseButton/SaveButton は 78pt 円)
  • NFR-X-A11Y-04 觊芚フィヌドバック (impact/notification/selection) で芖芚に䟝らない状態通知

🚀 配信 / リリヌス

  • NFR-X-REL-01 iOS: TestFlight → App Store Connect 経由配垃 (IAP は In-App Subscription, StoreKit2)
  • NFR-X-REL-02 バック゚ンド: Cloudflare Workers (wrangler deploy), D1 マむグレヌション wrangler d1 migrations apply
  • NFR-X-REL-03 LP: Cloudflare Pages, lp/functions/api/waitlist.ts で Edge Function
  • NFR-X-REL-04 Admin: Cloudflare Pages shiwake-admin.pages.dev、SPA + Basic auth lookup via backend
  • NFR-X-REL-05 AASA: /.well-known/apple-app-site-association で Universal Link /invite/*
  • NFR-X-REL-06 privacy_agreed_v1 のバヌゞョン番号で同意の䞖代管理

⑥ API カタログ — バック゚ンド党゚ンドポむント (37)

認蚌 / 招埅

METHODPATHAUTH甹途
POST/api/auth/challengenoneAppAttest 甹 nonce 発行 (5min TTL)
POST/api/auth/signupnoneAppAttest assertion を怜蚌 → user 䜜成 + access_token 返华
POST/api/invitenone匿名 invite code 発行 (DEBUG フォヌルバック / Settings 他者招埅)
POST/api/auth/redeemnoneinvite code を access_token ず亀換 (409=消費枈)
GET/invite/:codenoneUniversal Link 甚、アプリ未むンストヌル時のフォヌルバック
GET/.well-known/apple-app-site-associationnoneiOS Universal Link 蚭定

ナヌザヌ / プロフィヌル

METHODPATHAUTH甹途
GET/api/meBearerプロフィヌル + streak + subscription + trial + pending_advance_event 䞀括取埗
PUT/api/me/targetsBearer身長/䜓脂肪/目暙䜓重/期日/目暙カロリヌ/食事目暙/ニックネヌム 䞀括曎新
PUT/api/me/affinityBearer関係性 points 盎接セット (デバッグ)
PUT/api/me/subscriptionBearerサブスク状態手動切替 (デバッグ)
POST/api/setup/parseBearerwizard 甚音声 transcript → value/level/goal/date_iso 抜出
GET/api/me/factsBearerアシスタントが孊習した user facts 䞀芧
DEL/api/me/facts/:idBearerfact 削陀

食事 (meals / ingest)

METHODPATHAUTH甹途
POST/api/mealsBearer写真ベヌス meal 登録 (multipart: image+transcript)
GET/api/mealsBearer期間指定で meal 䞀芧取埗
DEL/api/meals/:idBearermeal 削陀
PUT/api/meals/:idBearermeal 線集 (raw_text 等)
POST/api/meals/:id/renameBearer料理名倉曎 → mealLookup 再蚈算
POST/api/meals/:id/flag-calorieBearerカロリヌ誀り報告 → feedback テヌブルに [calorie_flag] 挿入
POST/api/ingestBearerテキスト transcript で食事/䜓重/雑談を仕分け (persona_comment + advance_event 同梱)
POST/api/ingest/voiceBearer音声バむナリ → STT → ingest 統合
POST/api/auth/soniox-temp-keyBearerPremium 甹 Soniox WebSocket 䞀時キヌ発行

䜓重 / 運動 / ノヌト

METHODPATHAUTH甹途
POST/api/weightsBearer䜓重蚘録 (kg + note + body_fat_percent)
POST/api/weights/:id/updateBearer既存䜓重の䞊曞き線集
GET/api/weightsBearer期間指定取埗
DEL/api/weights/:idBearer削陀
GET/api/exercisesBearer運動蚘録 期間指定取埗
DEL/api/exercises/:idBearer運動削陀 (POST は ingest 経由で自動䜜成)
GET/api/notesBearerフリヌノヌト䞀芧
DEL/api/notes/:idBearerノヌト削陀
GET/api/summary/weeklyBearer過去 7 日の集蚈 (meal_count/total_kcal/avg_kcal + weights 配列)

フィヌドバック

METHODPATHAUTH甹途
POST/api/feedbackBearerテキストフィヌドバック送信 ⚠ サヌバ実装未確認

IAP / サブスクリプション

METHODPATHAUTH甹途
POST/api/iap/verifyBearerStoreKit JWS をサヌバ偎怜蚌 → users.subscription_status 曎新
POST/api/iap/notificationnone (眲名怜蚌)Apple Server-to-Server 通知受信

Admin / LP / ヘルス

METHODPATHAUTH甹途
GET/api/admin/statsBasicOpenRouter credits / 日次コスト / runway / フィヌドバック盎近䞀芧 (/api/admin/* 党䜓が Basic)
POST/api/waitlist (LP)none (IP hash)メアド + source + UA + referrer を waitlist テヌブルに保存
GET/api/admin/waitlist (LP)Basicwaitlist 取埗 (JSON or CSV ゚クスポヌト)
GET/noneルヌト (導線返し)
GET/healthnone{ ok: true, ts: now }

💡 このペヌゞは静的ドキュメントです。デヌタ゜ヌスは admin/index.html の data-tab="docs" セクション + admin/admin.js の docFilter* 関数。 画面远加・API 倉曎時に PR で曎新しおください。