fix: test_api_key.py の9件が失敗(api-key-login 未実装・sync/upsert 契約不一致) #35
Labels
No labels
h1-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
joe/o2#35
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
概要
tests/test_api_key.pyの 9 件が main で失敗している。本 Issue は回帰テストを緑に戻すための記録。本問題は作業ブランチfix/hollow-implementationsの変更とは無関係(main HEAD 単体でも同様に失敗することを確認済み)。失敗内容
A.
/api/auth/api-key-loginが存在しない(4件)tests/test_api_key.py:385,396,415,435がPOST /api/auth/api-key-loginを呼ぶが 404src/o2/api/に当該ルートの定義が無い(rg -n 'api-key-login' src/o2でヒット無し)access_token/token_type == "bearer"/expires_in == 3600を期待docs/superpowers/specs/2026-09-16-api-token-design.mdに存在(v50 APIトークン機構、パターンA)B.
/api/sync/upsertのレスポンス形状がテストと不一致(5件)src/o2/api/sync.py:147のUpsertBatchResponseはcustomers_inserted/products_insertedを返すcustomers_created/customers_updated/products_created/journals_createdを期待(tests/test_api_key.py:455-573)UpsertBatchRequest(sync.py:141)にjournalsフィールドが無い/api/sync/upsertを「顧客・商品マスタのバッチ upsert」と記載しており、仕訳(journals)を含むかを契約として明確化する必要がある影響
/api/sync/upsertクライアントと契約が食い違うと連携が破綻するPOST /api/auth/api-key-login)が未実装のまま issue #28 が進行している対応方針(要判断)
POST /api/auth/api-key-loginを実装する(token を検証し JWT を発行、期限切れ/無効/無効化を 401)/api/sync/upsertのレスポンスキーをテスト(=h1-c2 側の期待)に合わせる。後方互換のため旧キーを併記するか、破壊的変更として h1-c2 を追随させるjournalsを upsert 対象に含めるかを契約として決定し、実装・ドキュメント・テストを一致させる受け入れ条件
tests/test_api_key.pyが全て緑/api/sync/upsertの契約(キー・対応エンティティ)がコード・テスト・AGENTS.md で一致している証拠
tests/test_api_key.py:385-574src/o2/api/sync.py:121-247docs/superpowers/specs/2026-09-16-api-token-design.md関連
docs/AUDIT_HOLLOW_IMPLEMENTATIONS_2026-09-16.md再現確認済み(既存不具合)
main HEAD(本ブランチの変更なし)でも同様に失敗することを確認しました。本 Issue の内容は正確です。
rg -n 'api-key-login' src/o2→ ヒット無し(エンドポイント未実装を確認)src/o2/api/sync.pyはcustomers_insertedを返すが、テストはcustomers_created/journals_createdを期待UpsertBatchRequestにjournalsフィールドが無い本ブランチのフルテストでも同じ 9 件のみが失敗しています(
6282 passed, 1 xpassed, 9 failed)。対応は別途必要です。対応完了
tests/test_api_key.pyの 9 件の失敗を解消し、コアスイートを全緑(6293 passed / 0 failed) に戻しました。対応内容
A.
POST /api/auth/api-key-loginの実装{access_token, token_type:"bearer", expires_in:3600}を返却effective_role_for_api_key)purpose="api_key"+api_key_idを JWT に付与。_get_current_userは毎リクエストでキーの有効性と所有者一致を再検証(失効が即時反映)purposeがapi_key以外(mfa等)は従来どおり拒否。通常トークンの経路は挙動不変B.
/api/sync/upsertの契約統一upsert_batchを削除。後発sync_upsertが正典)customers_created系(新契約)とcustomers_inserted系(h1-c2 の Dart クライアントが読む互換別名)を同一レスポンスで両方返却journalsupsert を有効化。科目未解決時は空・不均衡な仕訳を作らずtype="journal_line"を返すfrom o2.api import get_tenant_id(存在しない)を撤去しresolve_write_tenantに修正ProductUpsertItem.tax_categoryの不正な既定値"TAXABLE_10"を修正(ValueError の原因)変更ファイル
src/o2/services/jwt_service.py/api_key_service.py/permission_checker.pysrc/o2/api/auth.py/schemas.py/sync.pytests/test_api_key.py(権限強制・MFA拒否テストを追加。既存アサーションは不変)テスト結果
成果物
529cc8982cf7a2(push 済)5e3431bまで含め origin/main に反映次のステップ / 残課題
/api/dashboard/api-keysの管理API(一覧/生成/更新/削除/toggle/reissue/QR)は未実装 → #36 で起票customers_insertedは互換別名として維持。将来的にcustomers_createdへの統一を検討(h1-c2 側の追随が必要)