fix(data): protect portfolio publication invariant
This commit is contained in:
@@ -79,6 +79,8 @@ CHECK (NOT is_public OR (
|
||||
|
||||
Application validation additionally requires at least one linked completed session and at least one linked GM before publishing because those requirements span child tables.
|
||||
|
||||
Database triggers on `portfolio_game_sessions` and `portfolio_game_masters` protect the same invariant after link removal. After a link is deleted, the trigger locks the parent card, checks both required link sets, and sets `is_public = false` with a fresh `updated_at` when either set is empty. It deliberately preserves `published_at` as the timestamp of the first publication. The link foreign keys retain `ON DELETE CASCADE`; when the card itself or its owning club is deleted, the trigger update is a harmless no-op for the disappearing parent row.
|
||||
|
||||
### `portfolio_game_sessions`
|
||||
|
||||
| Column | Type | Constraints | Description |
|
||||
@@ -125,7 +127,7 @@ UNIQUE (portfolio_game_id, author_player_id)
|
||||
```
|
||||
|
||||
- Partial public index on `(portfolio_game_id, created_at DESC)` where `moderation_status = 'Approved'` and `publication_consent_at IS NOT NULL`.
|
||||
- Partial moderation index on `(created_at)` where `moderation_status = 'Pending'`.
|
||||
- Partial moderation index on `(portfolio_game_id, created_at DESC)` where `moderation_status = 'Pending'`.
|
||||
|
||||
---
|
||||
|
||||
@@ -339,7 +341,7 @@ Follow TDD for production changes.
|
||||
|
||||
### Schema And Contracts
|
||||
|
||||
- Migration source-contract tests assert the four new tables, constraints, and indexes.
|
||||
- Migration source-contract tests assert the four new tables, format constraint, publication guard, case-insensitive slug uniqueness, group and GM-profile indexes, card-oriented pending-review index, and the link-removal trigger protection.
|
||||
- Public DTO reflection/source tests assert that private identifiers and physical storage paths are absent.
|
||||
- Existing showcase tests continue to assert the future-session catalog boundary.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user