traPtitech / traPtitech/Checkin

会員・会計の中核ドメインデータモデル(集約境界・キー・PII と会計の分離)を設計する

Open
#27 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
3d 5h
Merged PRs (30d)
7

Description

横断前提の追加(#39): 決済プロバイダは非依存を原則とする(特定プロバイダに依存せず切り替えられる)。プロバイダ固有の識別子(顧客 ID 等)は会員集約の属性として持ち、同定の単一ソースは内部 ID とする。

背景

packages/db/src/schema.ts には現在 6 つのテーブルがある。2026-09-19 に次のコマンドで数えた。

grep -oE "mysqlTable\('[a-z_]+'" packages/db/src/schema.ts | sed "s/mysqlTable('//;s/'//"

出力は userssessionsemail_verificationsstripe_eventspayoutsmembership_slots である。テーブルを宣言しているファイルはこの 1 つだけで(git grep -l 'mysqlTable(' の出力が packages/db/src/schema.ts の 1 行)、packages/db/drizzle.config.tsschema もこのファイルを指している。users は疎通確認用のプレースホルダではなく、内部 UUID を主キーに持ち、mail_hashtraq_idstripe_customer_idstripe_connected_account_id を属性として持つ対応表である。membership_slots には (user_id, activity_year, half) の UNIQUE 制約がある(grep -n "unique('membership_slots" packages/db/src/schema.ts の出力が membership_slots_user_year_half_uq の 1 行)。

なぜ今決めるか

永続化スキーマは変更コストが最大で、会員・金銭データが乗った後の正規化・キー変更は全行の移行を伴い高くつく。上に挙げた 6 つのテーブルは既に足されており、このモデルを決めないまま #18/#21 が各々さらにテーブルを足すと、集約境界とキー設計がバラバラに固まる。#22 は会員状態モデルのギャップを列挙するだけで、モデルそのものを設計する担当がいない。

論点・選択肢

  • 集約境界とキー: member(内部 UUID)を正本とし、traq_id / Stripe customer_id / メールハッシュはその属性にする。凍結アカウント(セッション無しの再入部、#22)では未検証の traQ ID を同定子にできないため、内部 ID を traq_id と分離しておく。
  • 期(term)を第一級エンティティにするか、日付判定だけで済ませるか。membership_period(誰がどの期に会員か)の履歴を持つか。
  • ロール/管理者を別テーブルにするか、is_admin フラグ(#18)のままか。
  • PII(氏名・customer_id・メールハッシュ)と不変な会計記録をスキーマ上分離し、退部・削除要求で PII を消しても会計記録は残せる形にする。
  • 「1 会員・1 期あたり入部費 1 回」を (member, term) の DB ユニーク制約で強制する(アプリの read-check-write は同時リクエストで競合し二重請求が通るため、制約で担保する)。

受け入れ条件

  • 中核エンティティの集約境界・キー・PII/会計分離・重複防止制約が決まり、schema.ts に現在あるテーブルについて何を残し・何を変え・何を足すかが決まって、schema.ts がその形になっている。
  • 情報不足で詰められない部分(在籍状態の細目・退部フロー等、フロント/運用要求依存)は暫定と明示され、最小の可逆な骨格に隔離されている。

関連

#18(traq_id/customer_id/メールハッシュのマッピング)・#21(台帳エントリ)・#22(要求ギャップ)の前提(親)。お金の記録アーキテクチャの決定と接続する。

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading packages/db/src/schema.ts and packages/db/drizzle.config.ts, then review the related issues #18, #21, and #22 for the requirements behind the existing six tables. Define the aggregate boundaries, keys, PII/accounting separation, and duplicate-prevention constraint, and update schema.ts so the retained, changed, and added tables match the agreed minimal reversible model.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, typescript
Domain
backend-api-design, database
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.