Skip to the content.

Access Patterns

resource-planner の DynamoDB 単一テーブルに対するクエリパターン一覧。 前提: app 層は常に Auth.js session から teamId を取得し、PK を TEAM#{teamId} で固定する。

Note: 現時点で app 側の DB アクセスコードは未着手。本表は将来 CRUD を実装する際の 設計仕様。実装が入ったら “API” / “Source” 列に handler / repository への行番号リンクを 追記する (TODO)。

一覧

# Use case API (将来予定) KeyCondition Filter / Condition 備考
1 組織内全データ取得 (タイムライン初期表示) load(teamId) (SvelteKit +page.server.ts) pk = TEAM#{teamId} (Query) なし Resource / Project / Assignment が 1 query で混在取得。app 層で SK プレフィックスを見て振り分ける
2 リソース一覧 listResources(teamId) pk = TEAM#{teamId} AND begins_with(sk, "RES#") なし 組織内の人を全件
3 案件一覧 listProjects(teamId) pk = TEAM#{teamId} AND begins_with(sk, "PRJ#") なし 組織内の案件を全件
4 期間内アサイン取得 listAssignments(teamId, from, to) pk = TEAM#{teamId} AND sk BETWEEN "ASN#{from}" AND "ASN#{to}~" endDateExclusive > :from (FilterExpression、半開区間の重なり判定) ~ (チルダ、ASCII 7E) は ASCII 上で # より大きいので range 終端の sentinel として有効。endDateExclusive > :from は半開区間の重なり条件 (ADR 0004)

SK プレフィックスの境界

Entity SK 先頭プレフィックス
Resource RES#
Project PRJ#
Assignment ASN#

R < P ではなく P < R のため、辞書順は ASN# < PRJ# < RES# の順。begins_with で 個別取得するときは順序を意識する必要は無いが、将来 BETWEEN "PRJ#" AND "RES#" のような 複合範囲を組む場合はこの順序を考慮する。

CRUD オペレーション (将来実装)

# Use case API Operation ConditionExpression
5 リソース作成 createResource(teamId, name) PutItem attribute_not_exists(sk) で同一 SK の上書き防止
6 案件作成 createProject(teamId, name, color) PutItem attribute_not_exists(sk)
7 アサイン作成 createAssignment(teamId, resourceId, projectId, startDate, endDateExclusive) PutItem attribute_not_exists(sk)。フォーム入力 (inclusive endDate) → assignmentCreateSchema.transform()endDateExclusive で repository に渡る (ADR 0004)
8 アサイン削除 deleteAssignment(teamId, sk) DeleteItem なし (idempotent)
9 リソース削除 + カスケード deleteResource(teamId, resourceId) TransactWriteItems (Resource 1 件 + 関連 Assignment 複数) app 層で先に listAssignments(...) で対象 SK を集める

Anti-patterns / Known concerns

A1. クロステナント混入防止

PK を 必ず server-side で組み立てる。session の teamId 以外を信用しない。 HTTP body / query で teamId を受け取って PK にするのは禁止 (権限昇格の経路になる)。

A2. Scan は使わない

Single Table Design の利点は全 query が PK 固定で完結すること。Scan は組織分離を破壊する ため (別 org のデータを引きうる) 採用しない。集計が必要なら GSI を新設する。

A3. Assignment の FK 整合性

DynamoDB は FK 制約が無い。Resource / Project を削除しても Assignment は残骸として残る。 app 層で TransactWriteItems または step-by-step delete を実装 して整合性を担保する (use case #9 参照)。

A4. Assignment の SK ユニーク性

SK は ASN#{start_date}#{assignment_id} の複合。assignment_id (UUID) が末尾にあるため 同一 start_date の同時アサインも問題なく作成可能。attribute_not_exists(sk) の防御は UUID 衝突に対する念のための保険。