erDiagram
EMPLOYEE ||--o{ BOOK_REQUEST : requests
DEPARTMENT ||--o{ BOOK_REQUEST : belongs_to_at_request_time
BOOK_REQUEST ||--|{ BOOK_REQUEST_ITEM : includes
EMPLOYEE ||--o{ BOOK_REQUEST_ITEM : uses
BOOK_REQUEST {
string request_id
date request_date
string account_category
string status
string rejection_reason
}
BOOK_REQUEST_ITEM {
string request_item_id
int line_no
string title
string purchase_type
int quantity
decimal unit_price
string storage_location
}
erDiagram
employees ||--o{ book_requests : applicant_employee_id
departments ||--o{ book_requests : applicant_department_id
book_requests ||--|{ book_request_items : request_id
employees ||--o{ book_request_items : user_employee_id
book_requests {
uuid request_id PK
varchar request_no UK
uuid applicant_employee_id FK
uuid applicant_department_id FK "申請時点スナップショット参照"
date request_date
varchar account_category "新聞図書費/研修費/福利厚生費"
varchar status "PENDING/APPROVED/REJECTED"
text rejection_reason "REJECTED時必須"
int version_no
timestamp created_at
timestamp updated_at
}
book_request_items {
uuid request_item_id PK
uuid request_id FK
int line_no
uuid user_employee_id FK
varchar title
varchar purchase_type "PAPER/EBOOK"
int quantity
numeric unit_price
varchar storage_location
varchar office_location
timestamp created_at
timestamp updated_at
}
- 申請共通情報(申請者、勘定科目、承認状態)はヘッダ
book_requestsに集約。 - 書籍ごとの情報(使用者、タイトル、保管場所、購入種別)は明細
book_request_itemsに分離し、1申請多明細を実現。 - 明細識別は
request_item_idを主キーとしつつ、表示順・業務整合のためrequest_id + line_noを一意制約にする。
book_requests.applicant_department_idに申請時点の部門IDを保存する(履歴由来のスナップショット)。- これにより、申請後に社員が異動しても申請書上の部門情報は変化しない。
statusは列挙値制約(PENDING/APPROVED/REJECTED)で排他的に管理。status=REJECTEDの場合のみrejection_reason必須、status!=REJECTEDの場合は空を強制(CHECK制約 + APIバリデーション)。
- 現時点では明細の
office_locationとstorage_locationを保持し、将来はbook_assets(現物台帳)を追加して購入明細から採番連携する。 - 台帳側で棚卸状態、貸出状態、廃棄状態を持つ設計に拡張し、申請データとは疎結合に保つ。