Files
jrshikoku/docs/refactor-audit/08-testing-observability.md
harukin-expo-dev-env 974c162a9e refactor: migrate from Sentry to custom telemetry for observability
- Replaced Sentry breadcrumbs and context setting with a custom telemetry implementation across various components including Apps, WebView, CarouselBox, and ndView.
- Introduced a new telemetry module to encapsulate observability logic and provide a unified API for logging events, messages, and exceptions.
- Updated documentation to reflect changes in observability architecture, consolidating Sentry initialization and telemetry usage.
- Enhanced error handling and logging in data fetching and application lifecycle management.
2026-09-01 01:11:13 +09:00

7.6 KiB
Raw Permalink Blame History

Testing / TypeScript / Observability監査

1. 現在の検証状態

項目 結果
TypeScript npx tsc --noEmit 成功
noUnused試行 --noUnusedLocals --noUnusedParametersは未使用警告多数で終了コード2
Expo Doctor 20 checks中19成功、1失敗(patch mismatch
Expo install check npx expo install --checkを実行。Doctorと同じ25件で終了1、package/lock変更なし
Expo public config 成功
Web export 成功(/tmp/jrshikoku-audit-exportへ出力)
unit/hook/component test test/spec/__tests__なし
integration/API test なし
native test 自動/実機smokeなし。新規buildは未実行だが、直近7.2 EAS Build成功は確認
E2E/smoke なし
lint script なし
CI .github/ / .eas/workflows/なし
EAS live state read-only CLIでbuild/channel/updateを確認。Expo MCPは内部エラー

package.jsonのscriptsはcompile-web-script、start、android、ios、eject、postinstall、pushWeb、checkDiagramのみで、testlinttypecheckverifydoctorbuildはない。ejectは現行CNG/SDK 55と整合しないstale script候補である。

2. テスト可能性の評価

Unit(すぐ可能)

  • timeUtilstrainTimeFiltering、駅ID/路線変換、列車番号変換、運休判定。
  • getTrainType、delay label、Voicepeak text/key、station ordering。
  • parser/type guard、source priority、stale/TTL、dedupe。

Hook / repository

  • useCurrentTrainのR2→GAS fallback、最新responseのみ反映、mock abort。
  • useTrainDelayDataの初回一回、retry、HTTP/parse error。
  • useAllTrainDiagramのcache、polling、AppState。
  • 通知設定・storage migration。

Component / integration

  • station diagramがAPI取得後に再計算されること。
  • deep link / notificationからnested routeへ到達すること。
  • WebView message、recording import、download bridge。
  • tab切替、Android back、modal dismiss、rotation。

Native / smoke / E2E

  • FeliCa scan、Widget同期、Live Activity/Foreground Service、permission拒否。
  • Development Buildでの起動、OTA runtime compatibility、push token登録。
  • 主要ユーザーフローの少数smoke(起動→station→train→追従、operation、setting、FeliCa)。

3. 最低限自動化すべきテスト

優先順位は次の通り。

  1. 時刻: 24:xx、04:00、JST、日付跨ぎ、delay加算。
  2. 駅識別: 同名駅、M12、枝番、路線文脈必須。
  3. 列車位置parser: R2/GAS/mockのmalformed、duplicate、stale response。
  4. ダイヤparser: 休発/休着、臨時運転日、serviceDate。
  5. API client: status、timeout、abort、retry、JSON/HTML、schema mismatch。
  6. deep link: cold start / warm start / notificationとの競合。
  7. storage: favorite、theme、source setting、cache TTL/migration。
  8. Native capability: mockable JS contract tests + 少数の実機smoke。

4. TypeScript所見

tscが成功することは、外部JSONの安全性を意味しない。現在位置など一部はtype guardがあるが、Unyohub/Elesite、遅延、GAS、WebView message、navigation stateにany/assertion/dynamic recordが残る。

改善方針:

  • callerのinterfaceではなく、response parserの戻り値を信頼する。
  • unknownで受け、必須キー、文字列/数値、許容enum、配列要素を検証する。
  • malformed itemを捨てる場合は件数とsourceを観測し、全体失敗との違いを明示する。
  • sourcefetchedAtschemaVersionserviceDateをデータ envelopeへ入れる。
  • Zod等は、parser数・bundle cost・実データの変化頻度を見て導入判断する。今回インストールしない。
  • tsconfig.jsonのpaths/plugins記述は、現状tscが通るものの、baseUrlを含む意図を明文化して別PRで整理する。

5. Error handling

良い点

  • Sentry初期化、navigation/lifecycle breadcrumb、network context、WebView watchdogがある。
  • observedFetchはHTTP/timeout/parse形式を区別しようとしている。
  • app lifecycle crash sentinelで前回異常終了の兆候を残す。

欠落

  • rootの明示的ErrorBoundary / user-safe fallbackがない。Sentry.wrapだけでは画面復旧UIを提供しない。
  • logger.errorは基本consoleで、Sentryへ送る保証がない。
  • raw fetch、WebView内fetch、Native fetchが観測層を迂回する。
  • 通知登録エラーが空実装に近く、失敗理由をUIへ返さない。
  • NotificationSettingsはPOSTのresponse.okを確認せず成功alertへ進み得る。
  • UpdateAsyncfetchUpdateAsyncがouter catchへawait/returnされない。Expo Updates既定の起動時checkも有効なため、custom check/reload方針と重複する。

6. Sentry / privacy

lib/observability/sentry.tsをApp.tsxから初期化してSentryを有効にし、production trace 5%、Replay、Feedback、sendDefaultPii:trueを設定する。beforeSendはdata_fetch response headの短縮が中心で、token/URL query/response payloadの意味ベースredactionは十分ではない。一方、observedFetchはfailure kind、endpoint tag、contextをSentryへ送る既存基盤を持つため、新規観測基盤を作るより適用範囲とredactionを揃えるべきである。

要確認・対応:

  • privacy policyにSentry、PII、Replay、Feedback、保存期間、同意、削除依頼を追記または実装設定を変更する。
  • WebView navigation breadcrumbのURL queryをredactする。
  • Push Token、Voicepeak token、Sentry credentialをconsole/breadcrumb/exception messageへ出さない。Push Tokenを権限user IDへ直接流用しない。
  • Clipboardへのtokenコピーは、隠れgestureではなく利用目的と警告を示す明示操作だけにする。
  • response headはHTML/JSONに個人情報やtokenが混ざる可能性があるため、host/pathだけを原則とする。
  • release、distribution、runtimeVersion、EAS Update IDをSentry eventへtag付けする。
  • source map uploadとrelease healthの実態をEAS/Sentryで確認する。

7. 「取得失敗」の原因特定可能性

経路 endpoint status timeout parser source/age Sentry
current R2 あり あり あり 部分的 部分的 あり
current GAS fallback あり caller依存 caller依存 部分的 不十分 一部
delay raw fetch あり なし なし なし なし なし/限定
Unyohub/Elesite あり なし なし なし cache ageなし console中心
WebView page URL WebView errorのみ page依存 script依存 page内不明 breadcrumb/watchdog
Android service/widget 独自URL native実装依存 あり/独自 permissive UIへ不明 RN外

結論として、主要経路では一部追跡できるが、ユーザー報告から一意に原因を特定できる状態ではない。

8. 推奨テスト段階

Stage 0a: tsc + Web export + doctor/install-checkのbaselineを固定(現状失敗はartifact化)
Stage 0b: SDK 55 patch整合後にdoctor/install-checkをblocking化
Stage 1: pure domain/parser unit tests
Stage 2: repository/hook tests (fake timer/Abort/fixture)
Stage 3: navigation/deep-link/component integration
Stage 4: Development Build native smoke
Stage 5: release channel/OTA/store smoke

各PRで全Native buildを必須にする必要はない。JS/domain/API変更はStage 0〜2、Navigation/WebView変更はStage 3、module/config/plugin変更はStage 4、release config変更はStage 5を要求する。