Skip to content

docs(spec)+impl: 既存usersテーブル記述補正 + ADR-0006 派生スコープ(users 列追加 + JPA + 匿名化 service)(N8) #90

Description

@win2cot

背景

設計書では「既存 users は別 DB にあり ReadOnly 参照のみ」と書いたが、実際は V1.0.0_01__create_tables.sql で本システム DB 内に同一スキーマを作成している。

加えて、2026-05-24 マージの ADR-0006(Keycloak User Storage SPI、PR #220 派生) で確定したスコープとして、users テーブルの schema 追加 + JPA エンティティ更新 + 匿名化 domain service の skeleton を本 Issue で同時実施する(ADR-0006 §6 実装メモ 順序 2 に対応)。

なお 2026-05-24 N1〜N8 見直しを受け、Flyway migration の方針は #248(設計規約 §3.1 「初期版直接追記の例外運用」)に統一(2026-05-25 main merge 済)。本 Issue「やること B」もこのルールに準拠する。

やること

A. docs 補正(従来 N8 のスコープ)

  1. 基本設計書 §4.2.1 / 要件定義書 §5.3 の表記を更新
    • 例: 「本システム DB 内に保有する新規 users テーブル(将来的に既存 ID 基盤へのデータ移行余地を残す)」
    • ADR-0006 §1 コンテキスト(本システム内で先に設計された users を指す、外部システム DB を指さない)と整合させる
  2. シーケンス図 sequence-01-oidc-login.mmd 内の表記も更新

B. ADR-0006 派生: users テーブル schema 追加(初期版直接追記、#248 ルール準拠)

設計規約 §3.1 「初期版直接追記の例外運用(dev 初回デプロイ前、Sprint 1 完了まで)」 に従い、新規 migration ファイルを作成せず、既存 webapi/src/main/resources/db/migration/V1.0.0_01__create_tables.sqlusers テーブル定義に以下 2 列を直接追記する:

  • version BIGINT NOT NULL DEFAULT 0(JPA @Version 用、楽観排他)
  • deleted_at DATETIME NULL(論理削除日時、ADR-0006 §3.4 論理削除 + 匿名化運用)

既存 FK 制約(tasks.owner_id 等の ON DELETE RESTRICT)および UNIQUE 制約(uq_users_oidc_subemail)はすべて維持する。

ADR-0006 §3.4 リファレンス側の修正: #248 PR(merge 済)で既に「V1.0.0 直接追記方針」へ整合済のため、本 Issue では ADR 修正は不要。

C. ADR-0006 派生: JPA エンティティ更新

webapi/src/main/java/xyz/dgz48/tasks/webapi/user/User.java:

  • @Version 注釈付き Long version field 追加
  • @Nullable LocalDateTime deletedAt field 追加
  • 上記 2 field の getter / setter / コンストラクタ整合

重要: 設計規約 §3.1 「Schema 変更と JPA Entity の同 PR ルール」(#248 で恒久ルール化、merge 済)に従い、B(V1.0.0 への schema 追記)と本セクション C(User.java 更新)は 1 PR で同時 commitする。

D. ADR-0006 派生: 匿名化 domain service skeleton

xyz.dgz48.tasks.webapi.user 配下に UserAnonymizationDomainService(命名は実装時調整可)を新規追加:

  • SPI(Sprint 1 Infra)と本システム API(将来の解約・退会 API)の両方から呼び出せる public method を提供(例: anonymize(User user))
  • ADR-0006 §3.4 の 8 ステップ匿名化処理を 1 transaction で実行:
    1. deleted_at = NOW()
    2. email = '__deleted__' || users.id || '@deleted.invalid'
    3. oidc_sub = '__deleted__' || users.id
    4. full_name = '__deleted__'
    5. full_name_kana = '__deleted__'
    6. department_name = NULL
    7. version@Version で自動 increment
    8. audit_logsaction = 'ANONYMIZE'entity_type = 'users'entity_id = users.id を記録

Sprint 0 段階では skeleton(method 定義 + 上記 1〜7 の DB UPDATE 部分)。step 8 の audit_logs 連携は #144(監査列 Auditing 機構整備)と併走 するため、本 Issue では method 内に TODO コメント + #144 への参照を残す。

配置: 本 Issue 着手時に #86(N4、feature 内クリーンアーキ 4 層雛形)が merge 済なら、xyz.dgz48.tasks.webapi.user.domain.UserAnonymizationDomainService として配置する。#86 未 merge なら一時的に xyz.dgz48.tasks.webapi.user 直下に配置し、#86 完了後に移動する(その移動コストは小さい)。

受入条件

  • (A) 基本設計書 §4.2.1 / 要件定義書 §5.3 / sequence-01-oidc-login.mmd 更新
  • (B) V1.0.0_01__create_tables.sql の users テーブル定義に version / deleted_at 列を直接追記、Testcontainers MySQL 8.4 で Flyway repair 不要(初期版改訂のみで履歴テーブル未生成、設計規約 §3.1 準拠)で migrate 成功
  • (C) User.java@Version Long version + @Nullable LocalDateTime deletedAt 追加、(B)と同 PR で同時 commit(設計規約 §3.1 同 PR ルール準拠)
  • (D) UserAnonymizationDomainService(または相当)を配置、基本 unit test(8 ステップのうち 1〜7 の DB UPDATE 部分)green、step 8 audit_logs 連携は TODO コメント + 監査列(created_at / updated_at / created_by / updated_by)の Auditing 機構整備 #144 参照を残す
  • ADR-0006 §6 実装メモ順序 2 を満たす
  • ./gradlew :webapi:check green、UT カバレッジ 80%+

参照

関連

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/backendJava / Spring バックエンド実装変更area/dbFlyway マイグレーション / スキーマ / DDL 変更area/docsdocs/ 配下のドキュメント(設計書・規約・ADR 等)変更priority/p2Medium。完了が望ましいが柔軟に判断可

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions