SlotKeeper 設計と品質

要件と受入条件

Quint正本から生成。catalogの型検査は、予約整合性の形式証明ではありません。受入条件ごとの実在テストIDは設計生成器が照合し、結果は同じrun(36379917632-1)のcollectorから表示します。

COM-01

幅390pxと1280pxで主要操作ができ、ラベル、入力エラー、キーボード操作、可視フォーカスを備える。ページ全体に不要な横スクロールを出さない

COM-01-AC:passed(3件)

Given 一般利用者が390pxと1280pxの画面でログインしている / When 資源選択・予約作成・詳細・取消・ログアウトをキーボード操作可能な部品で行う / Then 各操作が完了し、ページ全体の横スクロール幅が表示幅以下で、localStorageにtokenを残さない

  • passed vitest::Cognitoのログアウト先 [COM-01-AC]
  • passed playwright::ログインから予約・履歴・取消・ログアウトまで [COM-01-AC] [SLOT-AC01] [SLOT-02-AC] [SLOT-07-AC] [SLOT-AC04]
  • passed playwright::一般利用者に資源管理を表示しない [COM-01-AC] [COM-04-AC]

COM-02

確定済みのデータは再起動後も残る。失敗操作で部分更新を残さない

COM-02-AC:passed(3件)

Given 確定済み予約と途中で失敗する作成要求がある / When migration・seedの再実行と履歴保存中の障害を起こす / Then 確定データは保持され、失敗した要求は予約・履歴・要求キーを残さない

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_rollback_at_event
  • passed tests/test_db_session.py::test_repeatable_read
  • passed tests/tools/test_project_migrate.py::test_migrate_and_seed_repeat
SLOT-AC16:passed(1件)

Given 確定データと開発用seedがある / When 起動・seed・アプリ再起動を繰り返す / Then 確定データを保持し、seedの無条件重複や開発データ消去を起こさない

  • passed tests/tools/test_project_migrate.py::test_migrate_and_seed_repeat

COM-03

入力をサーバー側でも検証する。入力不正は422を基本とし、未認証401、権限不足403、対象なし404、業務・版競合409を区別する

COM-03-AC:passed(13件)

Given 不正入力・未認証・権限不足・存在しない対象・業務競合の要求がある / When 各APIを呼び出す / Then それぞれ422・401・403・404・409を返し、入力値を応答へ反射しない

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_missing_reservation_returns_404
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_request_rejects_unknown_fields
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_router_error_response_maps_exceptions
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_status_codes
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_missing_reservation_returns_404
  • passed tests/app/apis/reservations/list_reservations/test_functions.py::test_router_error_response
  • passed tests/app/apis/resources/create_resource/test_functions.py::test_resource_input
  • passed tests/app/apis/resources/get_resource_schedule/test_functions.py::test_router_error_response
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_missing_resource_returns_404
  • passed tests/app/apis/resources/list_resources/test_functions.py::test_router_error_response
  • passed tests/app/apis/resources/update_resource/test_router.py::test_missing_resource_returns_404
  • passed tests/app/apis/test_deps.py::test_anonymous_and_health
  • passed tests/test_api_error_responses.py::test_api_error_responses_are_selected_per_operation

COM-04

サーバー側で本人と権限を判定する。UIの表示制御だけで権限を守らない

COM-04-AC:passed(11件)

Given 一般利用者のtokenと任意の権限ヘッダーがある / When 管理API・他人の予約の詳細と取消を呼び出す / Then サーバー側で403とし、UI表示に依存せず拒否する

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc001_cancel_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/reservations/get_reservation/test_functions.py::test_rejection_and_router_error_builders
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_owner_and_admin_view_history
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_tc001_get_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/resources/create_resource/test_functions.py::test_only_admin_manages_resources
  • passed tests/app/apis/resources/create_resource/test_router.py::test_user_cannot_create_resource
  • passed tests/app/apis/resources/create_resource/test_router.py::test_tc001_create_resource_router_matches_unit_test_gen
  • passed tests/app/apis/resources/update_resource/test_router.py::test_tc001_update_resource_router_matches_unit_test_gen
  • passed tests/app/apis/test_deps.py::test_anonymous_and_health
  • passed playwright::一般利用者に資源管理を表示しない [COM-01-AC] [COM-04-AC]

COM-05

起動・seed・リセット・全検証をCompose経由で再現できる。seedの乱数と評価用時刻を固定できる

COM-05-AC:passed(1件)

Given Git checkoutとDocker Composeだけがある / When 起動・seed・全検証のCompose commandを繰り返す / Then 依存の準備から検証まで完了し、seedは固定IDで重複しない

  • passed tests/tools/test_project_migrate.py::test_migrate_and_seed_repeat

COM-06

資源編集・予約取消等の同時更新で変更を消失させない。古い版は409とし再取得を案内する

SLOT-AC11:passed(9件)

Given 資源または予約が他の操作で先に更新されている / When 古い版で資源編集・予約取消を送る / Then 409を返し、先に確定した値と履歴を失わない

  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_get_reservation_and_predicates
  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_rejection_builders
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_boundaries
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc002_cancel_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/resources/update_resource/test_functions.py::test_permission_lock_version_and_future
  • passed tests/app/apis/resources/update_resource/test_functions.py::test_update_resource_and_builders
  • passed tests/app/apis/resources/update_resource/test_router.py::test_versions_and_inactive
  • passed tests/app/apis/resources/update_resource/test_router.py::test_update_resource_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/resources/update_resource/test_router.py::test_tc002_update_resource_router_matches_unit_test_gen

COM-07

要求ID、操作、結果、所要時間を構造化ログに残す。認証情報・予約目的・生の例外本文を無条件に記録しない

COM-07-AC:passed(9件)

Given 予約目的とBearer tokenを含む要求がある / When APIを呼び出す / Then 要求ID・operation・status・所要時間を構造化ログに残し、目的とtokenを記録しない

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_reservation_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_reservation_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_get_reservation_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/reservations/list_reservations/test_router.py::test_list_reservations_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/resources/create_resource/test_router.py::test_create_resource_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_get_resource_schedule_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/resources/list_resources/test_router.py::test_list_resources_sample_request_emits_router_error_log_to_stdio
  • passed tests/app/apis/resources/update_resource/test_router.py::test_update_resource_sample_request_emits_router_error_log_to_stdio
  • passed tests/test_operational_logging.py::test_request_log_redacts

COM-08

空、読込み中、入力不正、通信失敗、権限不足、競合、成功をUIで区別し、利用者が次の操作を判断できる

COM-08-AC:passed(1件)

Given 通信失敗・401・403・404・409・422・503と業務コードがある / When 画面の案内文を求める / Then 状態ごとに異なり次の操作を判断できる日本語の案内を返す

  • passed vitest::日本時間の入力と次の操作案内 [COM-08-AC] [RULE-04-AC]

SLOT-01

管理者が資源を登録・編集・無効化できる。無効資源への新規予約は禁止する

SLOT-01-AC:passed(15件)

Given 管理者と一般利用者がいる / When 資源の登録・編集・無効化と一覧取得を行う / Then 管理者だけが変更でき、一覧は名前とIDの固定順でページングされる

  • passed tests/app/apis/resources/create_resource/test_functions.py::test_only_admin_manages_resources
  • passed tests/app/apis/resources/create_resource/test_functions.py::test_save_resource_and_builders
  • passed tests/app/apis/resources/create_resource/test_router.py::test_user_cannot_create_resource
  • passed tests/app/apis/resources/create_resource/test_router.py::test_admin_creates_active_resource
  • passed tests/app/apis/resources/create_resource/test_router.py::test_create_resource_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/resources/create_resource/test_router.py::test_tc001_create_resource_router_matches_unit_test_gen
  • passed tests/app/apis/resources/create_resource/test_router.py::test_tc002_create_resource_router_matches_unit_test_gen
  • passed tests/app/apis/resources/list_resources/test_functions.py::test_resources_are_paged_by_name_and_id
  • passed tests/app/apis/resources/list_resources/test_router.py::test_resource_paging_order
  • passed tests/app/apis/resources/list_resources/test_router.py::test_list_resources_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/resources/list_resources/test_router.py::test_tc001_list_resources_router_matches_unit_test_gen
  • passed tests/app/apis/resources/update_resource/test_functions.py::test_update_resource_and_builders
  • passed tests/app/apis/resources/update_resource/test_router.py::test_update_resource_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/resources/update_resource/test_router.py::test_tc001_update_resource_router_matches_unit_test_gen
  • passed tests/app/apis/resources/update_resource/test_router.py::test_tc004_update_resource_router_matches_unit_test_gen
SLOT-AC05:passed(6件)

Given 無効資源と将来予約のある有効資源がある / When 無効資源への予約と、将来予約のある資源の無効化を行う / Then 両方409で拒否し、データは変化しない

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_rejection_builders_return_conflicts
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc003_create_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/resources/update_resource/test_functions.py::test_permission_lock_version_and_future
  • passed tests/app/apis/resources/update_resource/test_router.py::test_versions_and_inactive
  • passed tests/app/apis/resources/update_resource/test_router.py::test_future_prevents_disable
  • passed tests/app/apis/resources/update_resource/test_router.py::test_tc003_update_resource_router_matches_unit_test_gen

SLOT-02

資源と日付を指定して、その日の予約済み時間帯を確認できる

SLOT-02-AC:passed(6件)

Given 資源に確定予約と取消済み予約がある / When 一般利用者が資源と日付で予約表を取得する / Then 確定済みの時間帯と「予約済み」だけを返し、他人の目的と識別情報を返さない

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/resources/get_resource_schedule/test_functions.py::test_schedule_hides_other_details
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_schedule_hides_other_details
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_get_resource_schedule_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_tc001_get_resource_schedule_router_matches_unit_test_gen
  • passed playwright::ログインから予約・履歴・取消・ログアウトまで [COM-01-AC] [SLOT-AC01] [SLOT-02-AC] [SLOT-07-AC] [SLOT-AC04]

SLOT-03

資源、開始・終了、目的を指定して、自分名義の予約を作成できる

SLOT-AC01:passed(4件)

Given 空き資源がある / When 翌日10:00〜11:00を予約する / Then 1件確定し、予約表と自分の一覧へ反映する

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_adjacent_overlap
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_reservation_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc005_create_reservation_router_matches_unit_test_gen
  • passed playwright::ログインから予約・履歴・取消・ログアウトまで [COM-01-AC] [SLOT-AC01] [SLOT-02-AC] [SLOT-07-AC] [SLOT-AC04]
SLOT-AC06:passed(3件)

Given 過去・現在と同時刻・0分・4時間超・30日超・15分未満の刻み・日跨ぎの入力がある / When 予約時刻を検証する / Then 入力エラーとし、15分・4時間・30日以内の境界は受け付ける

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_reject_invalid_time
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_boundaries
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_rule_violation_is_422

SLOT-04

同一資源の予約済み時間と重なる予約の確定を拒否する

SLOT-AC02:passed(4件)

Given 既存の10:00〜11:00予約がある / When 10:30〜11:30と11:00〜12:00を予約する / Then 前者409、後者成功

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_rejection_builders_return_conflicts
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_adjacent_overlap
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc004_create_reservation_router_matches_unit_test_gen
  • passed tests/test_db_session.py::test_business_errors_are_not_retried
SLOT-AC03:passed(2件)

Given 空き枠に20人がいる / When 直列化せず同時に予約する / Then 1件成功・19件409で重複0件

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_twenty_concurrent
  • passed tests/test_db_session.py::test_transaction_retries_conflicts
SLOT-AC10:passed(2件)

Given 有効資源がある / When 予約作成と資源無効化を同時実行する / Then 無効化と将来予約が両方確定する結果は0件

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_update_resource_control_version_locks_or_404
  • passed tests/app/apis/resources/update_resource/test_router.py::test_create_vs_disable

SLOT-05

本人または管理者が、開始前の予約を取消できる

SLOT-AC04:passed(8件)

Given 利用者Aの開始前予約がある / When B・A・管理者が取消を試みる / Then Bは403、本人と管理者は取消でき、取消履歴が追加される

  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_get_reservation_and_predicates
  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_rejection_builders
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_admin_cancels_other_before_start
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_reservation_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc001_cancel_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc005_cancel_reservation_router_matches_unit_test_gen
  • passed playwright::ログインから予約・履歴・取消・ログアウトまで [COM-01-AC] [SLOT-AC01] [SLOT-02-AC] [SLOT-07-AC] [SLOT-AC04]
SLOT-AC13:passed(5件)

Given 開始時刻ちょうどの予約と取消済み予約がある / When 取消する / Then 409で拒否し、履歴を増やさない

  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_get_reservation_and_predicates
  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_rejection_builders
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_boundaries
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc003_cancel_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc004_cancel_reservation_router_matches_unit_test_gen

SLOT-06

自分の予約を日付・状態で絞り込める

SLOT-AC08:passed(5件)

Given 自分と他人の予約が複数日・複数状態にある / When 日付・状態で絞込み、他人の詳細を取得する / Then 自分の対象だけを返し、他人の目的・履歴は403で漏れない

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/reservations/list_reservations/test_functions.py::test_own_reservations_are_filtered_and_paged
  • passed tests/app/apis/reservations/list_reservations/test_router.py::test_list_filters_only_own
  • passed tests/app/apis/reservations/list_reservations/test_router.py::test_list_reservations_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/reservations/list_reservations/test_router.py::test_tc001_list_reservations_router_matches_unit_test_gen

SLOT-07

作成・取消の履歴を残し、権限のある利用者が詳細画面から確認できる

SLOT-07-AC:passed(7件)

Given 作成後に取消した予約がある / When 本人・管理者・他人が詳細画面で履歴を取得する / Then 本人と管理者は作成・取消の順の履歴を閲覧でき、他人は403

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_admin_cancels_other_before_start
  • passed tests/app/apis/reservations/get_reservation/test_functions.py::test_get_reservation_with_events
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_owner_and_admin_view_history
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_get_reservation_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_tc001_get_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_tc002_get_reservation_router_matches_unit_test_gen
  • passed playwright::ログインから予約・履歴・取消・ログアウトまで [COM-01-AC] [SLOT-AC01] [SLOT-02-AC] [SLOT-07-AC] [SLOT-AC04]

SLOT-08

要求の再送を識別し、予約と履歴を二重に作らない

SLOT-AC07:passed(4件)

Given 成功応答を失った作成要求がある / When 同じキーで再送(同時再送を含む)する / Then 元の予約IDと応答を返し、予約・作成履歴は各1件

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_replay_before_validation
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_same_key_concurrent
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc002_create_reservation_router_matches_unit_test_gen
  • passed tests/test_db_session.py::test_transaction_retries_conflicts
SLOT-AC09:passed(4件)

Given 同じ要求キーの成功記録がある / When 異なる入力を送る / Then 409で元の予約を変更しない

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_normalized_input
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_rejection_builders_return_conflicts
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_replay_before_validation
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc001_create_reservation_router_matches_unit_test_gen
SLOT-AC12:passed(2件)

Given 予約保存後の履歴保存で障害が起きる / When 作成し、その後同じキーで再送する / Then 部分保存を残さず、再送で1件だけ作成する

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_rollback_at_event
  • passed tests/test_db_session.py::test_transaction_limits
SLOT-AC15:passed(4件)

Given 作成済みキーの経過が24時間前後で、予約は取消・開始済みである / When 同じキーで再送する / Then 有効期間内は元の作成結果、期限後は新規要求の規則に従う

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_expired_record_is_not_replayed
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_get_idempotency_record_marks_expiry
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_replay_before_validation
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_replay_after_start

TECH-STACK

Astro静的フロントとFastAPIを使用する

TECH-STACK-AC:passed(3件)

Given Astro画面・FastAPI・PostgreSQLを起動している / When 静的buildとOpenAPI型生成を検査する / Then 静的成果物がbuildでき、フロント型がOpenAPIとdriftしない

  • passed verify:astro
  • passed verify:frontend-build
  • passed verify:openapi-types

TECH-DB

DSQLとPostgreSQLで共通の予約不変条件を守る

TECH-DB-AC:passed(2件)

Given ローカルPostgreSQLの検証DBがある / When 接続の分離レベルと共通SQLの型を検査する / Then Repeatable Readで接続し、SQL正本の束縛引数と結果型が一致する

  • passed tests/test_db_session.py::test_dsql_connection_uses_official_connector
  • passed tests/test_db_session.py::test_repeatable_read

TECH-AUTH

署名、issuer、client、用途、期限を検査する

SLOT-AC14:passed(6件)

Given 不正署名・期限切れ・異なるissuer/client・role改ざん・ID tokenがある / When 業務APIを呼び出す / Then 401/403で拒否し、DBは変化しない

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_invalid_token_leaves_database
  • passed tests/app/apis/test_deps.py::test_bad_claims
  • passed tests/app/apis/test_deps.py::test_bad_signature
  • passed tests/integrations/test_identity_provider.py::test_cognito_access_and_id
  • passed tests/integrations/test_identity_provider.py::test_jwks_client_is_bounded
  • passed tests/integrations/test_identity_provider.py::test_fake_verifier_rejects_unknown_token

TECH-LAMBDA

依存を含むLinux用Lambda ZIPを作成する

TECH-LAMBDA-AC:passed(2件)

Given Compose内でLinux向けに作った配布ZIPがある / When 隔離pathからimportし、API Gatewayイベントを変換する / Then handlerを読み込み、healthは200・未認証の業務APIは401

  • passed tests/test_lambda_handler.py::test_gateway_event
  • passed tests/test_lambda_handler.py::test_distribution_zip

TECH-INFRA

Python CDKで常設サーバーを持たない構成を合成する

TECH-INFRA-AC:passed(6件)

Given AWS認証情報のない環境で環境contextを指定する / When CDKをsynthしassertionとcdk-nagで検査する / Then 非公開S3+OAC、JWT保護route、限定IAM、ログ保持、削除保護、環境別のCORSとcallbackを満たし、常設サーバーを持たない

  • passed tests/infra/test_stack.py::test_serverless_and_authorization
  • passed tests/infra/test_stack.py::test_routes_are_protected
  • passed tests/infra/test_stack.py::test_origin_consistency
  • passed tests/infra/test_stack.py::test_least_privilege_and_private_bucket
  • passed tests/infra/test_stack.py::test_environment_settings
  • passed tests/infra/test_stack.py::test_unknown_environment_rejected

TECH-COMPOSE

GitとDocker Composeだけで起動と全検証を行える

TECH-COMPOSE-AC:passed(4件)

Given ホストにGitとDocker Composeだけがある / When verifyを1コマンドで実行する / Then 依存serviceの準備から結果収集とポータル生成まで行い、失敗時は非0で終了する

  • passed verify:package
  • passed verify:backend
  • passed verify:e2e
  • passed verify:portal-build

TECH-DESIGN

実装から6帳票、DB、CRUD、画面、infraを決定的に生成する

TECH-DESIGN-AC:passed(14件)

Given 実装source・SQL・CDKがある / When 設計を2回クリーン生成し、既存生成物と比較する / Then byte一致し、欠落・変更・余剰・未対応構文・要件traceの欠落を非0で報告する

  • passed tests/tools/test_project_design.py::test_data_capability_is_deterministic
  • passed tests/tools/test_project_design.py::test_drift_reports_manual_edit_and_stale_file
  • passed tests/tools/test_project_design.py::test_write_owned_root_replaces_only_owned_contents
  • passed tests/tools/test_project_design.py::test_repeat_sections_reads_profile_grammar
  • passed tests/tools/test_project_design.py::test_repeat_sections_rejects_unsupported_structure
  • passed tests/tools/test_project_design.py::test_added_route_without_contract_is_rejected
  • passed tests/tools/test_project_design.py::test_crud_rows_split_read_and_write_evidence
  • passed tests/tools/test_project_design.py::test_crud_model_matches_common_projection
  • passed tests/tools/test_project_design.py::test_sql_target_change_changes_crud_projection
  • passed tests/tools/test_project_design.py::test_database_model_marks_logical_references
  • passed tests/tools/test_project_design.py::test_frontend_without_menu_is_unsupported
  • passed tests/tools/test_project_design.py::test_trace_rejects_missing_and_unknown_tests
  • passed tests/tools/test_project_design.py::test_verify_checks_cover_requirement_evidence
  • passed tests/tools/test_project_evidence.py::test_design_search_covers_lazunex_documents
TECH-CRUD-AC:passed(7件)

Given APIのOpenAPI summaryと保存先アクセスの実装がある / When CRUD図を生成する / Then 既存正本から取得したAPI和名を行、保存先を列、CRUD文字列をセルとするマトリクスを決定的に生成し、アクセスなしは空欄にする

  • passed tests/tools/test_project_design.py::test_crud_diagram_uses_openapi_summaries_and_storage_columns
  • passed tests/tools/test_project_design.py::test_crud_diagram_tracks_summary_changes
  • passed tests/tools/test_project_design.py::test_crud_diagram_rejects_missing_summary
  • passed tests/tools/test_project_design.py::test_crud_diagram_orders_axes_and_cells_and_preserves_no_access
  • passed tests/tools/test_project_design.py::test_crud_capability_is_deterministic
  • passed tests/tools/test_project_design.py::test_crud_contract_rejects_rendering_drift
  • passed tests/tools/test_project_design.py::test_crud_contract_rejects_stale_summary_and_invalid_model

TECH-PORTAL

同一revisionとrunの実測結果と設計をPagesへ集約する

TECH-PORTAL-AC:missing(2件)

Given 同一revision・runの検査結果と生成設計がある / When ポータルをbuildしブラウザで検証する / Then 階層・検索・図の拡大・DB探索・深いリンク・390px表示が動作する

  • missing playwright::CRUD図でAPI和名と保存先のマトリクスを読む [TECH-PORTAL-AC]
  • missing playwright::階層検索から設計図とDB探索へ移動する [TECH-PORTAL-AC]

TECH-PERF

指定負荷とデータ量でAPI別の性能を測定する

TECH-PERF-AC:passed(1件)

Given 資源100・利用者200・予約10万件のデータがある / When 20並列で参照80%・作成取消20%の負荷を測定する / Then API別のp50/p95/p99・throughput・エラー率・整合性違反を同一runの証跡に残す

  • passed verify:performance

TECH-QUALITY

型、lint、実DB、ブラウザ、負例検査の失敗を隠さない

TECH-QUALITY-AC:passed(5件)

Given 失敗・skip・未実行・flakyを含む結果がある / When 結果を共通形式へ変換する / Then 非成功状態を成功へ変えず、collector外の結果と別runの混入を拒否する

  • passed tests/tools/test_project_evidence.py::test_result_identity_and_unexecuted
  • passed tests/tools/test_project_evidence.py::test_nonpassing_states_preserved
  • passed tests/tools/test_project_evidence.py::test_result_outside_collector_is_rejected
  • passed tests/tools/test_project_evidence.py::test_foreign_run_rejected
  • passed tests/tools/test_project_evidence.py::test_backend_coverage_below_goal_fails

TECH-PRIVACY

公開allowlistに秘密や生ログを含めない

TECH-PRIVACY-AC:passed(3件)

Given 公開サイトにallowlist外のfileやsymlinkがある / When 公開集合を検査する / Then 公開を拒否し、生ログ・token・DB dumpを含めない

  • passed tests/tools/test_project_evidence.py::test_publication_allowlist
  • passed tests/tools/test_project_evidence.py::test_symlink_not_published
  • passed tests/tools/test_project_evidence.py::test_allowed_site_records_provenance

RULE-01

予約区間は `[開始, 終了)` とします。10:00〜11:00と11:00〜12:00は重複しません。

RULE-01-AC:passed(2件)

Given 10:00〜11:00の予約がある / When 11:00〜12:00を予約する / Then 半開区間として重複せず成功する

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_has_overlapping_reservation_uses_half_open_interval
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_adjacent_overlap

RULE-02

開始・終了は15分刻み、予約時間は15分以上4時間以下です。

RULE-02-AC:passed(3件)

Given 15分刻みでない、15分未満、4時間超の入力がある / When 時刻を検証する / Then 422とし、15分と4時間ちょうどは受け付ける

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_reject_invalid_time
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_boundaries
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_rule_violation_is_422

RULE-03

開始は現在より後、かつ現在から30日以内です。終了は開始と同じ日本時間の日付内にしてください。翌日00:00を終了とする予約も、この初期版では対象外です。

RULE-03-AC:passed(2件)

Given 過去・30日超・日本時間の日跨ぎの入力がある / When 時刻を検証する / Then 422とし、翌日00:00終了も拒否する

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_reject_invalid_time
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_boundaries

RULE-04

保存時刻はUTCと対応付け、表示・入力はAsia/Tokyoとします。現在時刻は差替え可能なClockから取得します。公開APIで任意に現在時刻を上書きできないようにしてください。

RULE-04-AC:passed(3件)

Given 公開APIとClock依存がある / When OpenAPIと日本時間の変換を検査する / Then 現在時刻を上書きする入力はなく、日本時間の日付境界で変換する

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_request_rejects_unknown_fields
  • passed tests/test_api_error_responses.py::test_public_contract_has_no_clock_or_direct_edit
  • passed vitest::日本時間の入力と次の操作案内 [COM-08-AC] [RULE-04-AC]

RULE-05

予約状態は `confirmed → cancelled` です。終了済みかどうかは時刻から判定し、状態として二重管理しません。予約日時の直接編集は提供しません。

RULE-05-AC:passed(1件)

Given 確定予約がある / When 公開APIを検査して取消する / Then 予約日時の直接編集APIはなく、状態はconfirmedからcancelledへだけ遷移する

  • passed tests/test_api_error_responses.py::test_public_contract_has_no_clock_or_direct_edit

RULE-06

取消済み予約は重複判定から除きます。取消の確定と同時に、その枠を再予約できる状態へ戻します。

RULE-06-AC:passed(3件)

Given 確定予約がある / When 取消と同じ枠の再予約を行う / Then 取消済みは重複判定から除かれ、確定予約は最大1件

  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_cancel_updates_and_appends_event
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_and_rebook_concurrent

RULE-07

既定の「将来予約」は `confirmed AND start_at > now` とします。開始済み予約の途中で資源が無効化されても、既存予約の記録は維持します。新規予約は拒否します。

RULE-07-AC:passed(2件)

Given 開始済みの予約がある資源 / When 資源を無効化し将来予約を一覧する / Then 無効化でき既存記録を保持し、将来予約はconfirmedかつ開始前だけ

  • passed tests/app/apis/reservations/list_reservations/test_router.py::test_list_filters_only_own
  • passed tests/app/apis/resources/update_resource/test_router.py::test_disable_after_start_keeps_record

RULE-08

将来予約のある資源を無効化できません。予約作成と無効化が競合しても、無効資源に将来予約を残してはいけません。

RULE-08-AC:passed(4件)

Given 将来予約がある資源、または予約作成と無効化の同時実行 / When 無効化する / Then 無効資源に将来予約を残さない

  • passed tests/app/apis/resources/update_resource/test_functions.py::test_permission_lock_version_and_future
  • passed tests/app/apis/resources/update_resource/test_router.py::test_future_prevents_disable
  • passed tests/app/apis/resources/update_resource/test_router.py::test_create_vs_disable
  • passed tests/app/apis/resources/update_resource/test_router.py::test_tc003_update_resource_router_matches_unit_test_gen

RULE-09

一般利用者には他人の目的・利用者識別情報・履歴を返しません。共有予約表では時間帯と「予約済み」を表示します。管理者は取消業務に必要な情報を閲覧できます。

RULE-09-AC:passed(8件)

Given 他人の予約がある / When 一般利用者が予約表と詳細を取得し、管理者が詳細を取得する / Then 一般利用者へ目的・識別情報・履歴を返さず、管理者は閲覧できる

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_admin_cancels_other_before_start
  • passed tests/app/apis/reservations/get_reservation/test_functions.py::test_get_reservation_with_events
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_owner_and_admin_view_history
  • passed tests/app/apis/reservations/get_reservation/test_router.py::test_tc002_get_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/resources/get_resource_schedule/test_functions.py::test_schedule_hides_other_details
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_schedule_hides_other_details
  • passed tests/app/apis/resources/get_resource_schedule/test_router.py::test_get_resource_schedule_router_returns_sample_shaped_response_with_db

RULE-10

予約作成の要求キーは利用者単位で24時間有効です。同じキー・同じ正規化入力には元の成功応答を返し、異なる入力は409とします。有効期限後は新規要求として通常の重複判定を行います。

RULE-10-AC:passed(4件)

Given 同じ利用者の要求キーがある / When 同じ入力・異なる入力・24時間後に再送する / Then 元の成功応答・409・新規要求として扱う

  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_expired_record_is_not_replayed
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_replay_before_validation
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc001_create_reservation_router_matches_unit_test_gen
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_tc002_create_reservation_router_matches_unit_test_gen

RULE-11

成功済み要求の再送は、元の予約が開始・取消済みになっていても元の作成結果を返します。再送照合より先に現在時刻で新規予約の入力検証をしないでください。

RULE-11-AC:passed(1件)

Given 作成済み予約が取消または開始済みである / When 24時間以内に同じキーで再送する / Then 時刻検証より先に照合し元の作成結果を返す

  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_replay_after_start

RULE-12

予約・履歴・要求キーの成功記録は、同一トランザクションで確定します。取消と取消履歴も一体で確定します。

RULE-12-AC:passed(5件)

Given 作成または取消の途中で障害が起きる / When 操作を確定する / Then 予約・履歴・要求キーを同一transactionで確定またはrollbackする

  • passed tests/app/apis/reservations/cancel_reservation/test_functions.py::test_cancel_updates_and_appends_event
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_reservation_router_returns_sample_shaped_response_with_db
  • passed tests/app/apis/reservations/create_reservation/test_functions.py::test_save_reservation_owner_event_and_record
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_rollback_at_event
  • passed tests/app/apis/reservations/create_reservation/test_router.py::test_create_reservation_router_returns_sample_shaped_response_with_db

RULE-13

取消済み予約への取消は409とします。履歴を追加しません。

RULE-13-AC:passed(3件)

Given 取消済み予約がある / When 取消する / Then 409で履歴を追加しない

  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_privacy_and_cancel
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_cancel_boundaries
  • passed tests/app/apis/reservations/cancel_reservation/test_router.py::test_tc003_cancel_reservation_router_matches_unit_test_gen

RULE-14

資源名は空白除去後1〜100文字、説明は0〜1,000文字、予約目的は1〜200文字とします。一覧はページングし、順序と同順位時のID順を固定します。

RULE-14-AC:passed(7件)

Given 境界長の名前・説明・目的と複数ページの一覧がある / When 入力と一覧を検査する / Then 長さ制約を守り、固定順とID順でページングする

  • passed tests/app/apis/reservations/list_reservations/test_functions.py::test_own_reservations_are_filtered_and_paged
  • passed tests/app/apis/reservations/list_reservations/test_router.py::test_reservation_paging_order
  • passed tests/app/apis/resources/create_resource/test_functions.py::test_resource_input
  • passed tests/app/apis/resources/create_resource/test_functions.py::test_description_limit
  • passed tests/app/apis/resources/create_resource/test_router.py::test_admin_creates_active_resource
  • passed tests/app/apis/resources/list_resources/test_functions.py::test_resources_are_paged_by_name_and_id
  • passed tests/app/apis/resources/list_resources/test_router.py::test_resource_paging_order