feat(club): ownership-backed squad manager assignment
Add a generic, durable squad->manager assignment (migration 0023
squad_managers) so a manager persists across squad save, reload, and
server restart, backed by authoritative Core owned_cards.
- squad_managers(squad_id PK, owned_card_id, updated_at) with ON DELETE
CASCADE on both FKs: quick-selling the manager auto-clears the
assignment (no resurrection); one manager per squad (no duplicates).
- club::{get,set,clear}_squad_manager validate club ownership of both the
squad and the card, and re-check ownership on read (defends against a
stale row left by a market transfer).
- GET/PUT /club/manager routes expose the assignment; FIFA wire meaning
stays in the adapter.
Tests: persistence across reload+restart (headline), reassignment
replace/no-duplicate, clear/no-resurrection, cascade on quick-sell,
foreign-card rejection.
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
-- Squad manager assignment: an owned item assigned as a squad's manager.
|
||||
--
|
||||
-- Generic, game-neutral canonical state. Core does not know what a "manager"
|
||||
-- means to any game; it only records that one owned item (`owned_card_id`) is
|
||||
-- assigned to a squad in the manager role. The FIFA 17 adapter owns the wire
|
||||
-- meaning (itemType "manager", contract, chemistry) exactly as it owns player
|
||||
-- item shaping — Core just persists the ownership-backed assignment durably and
|
||||
-- atomically, so a manager survives squad save / reload / server restart.
|
||||
--
|
||||
-- One manager per squad: `squad_id` is the primary key, so a re-assignment
|
||||
-- REPLACEs rather than accumulating (no duplicate-manager rows).
|
||||
--
|
||||
-- `owned_card_id` references `owned_cards(id)` with ON DELETE CASCADE: quick
|
||||
-- selling / discarding the manager card (a DELETE on owned_cards) removes the
|
||||
-- assignment automatically, so a sold manager is never resurrected on the next
|
||||
-- squad read. Reads additionally re-check the manager still belongs to the club
|
||||
-- (see `club::get_squad_manager`), defending against a stale row left by a
|
||||
-- market transfer (which UPDATEs owner rather than deleting).
|
||||
CREATE TABLE IF NOT EXISTS squad_managers (
|
||||
squad_id TEXT PRIMARY KEY NOT NULL REFERENCES squads(id) ON DELETE CASCADE,
|
||||
owned_card_id TEXT NOT NULL REFERENCES owned_cards(id) ON DELETE CASCADE,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_squad_managers_owned ON squad_managers(owned_card_id);
|
||||
Reference in New Issue
Block a user