-- Achievements: the playthrough case-state. Boolean facts earned by a player, each
-- remembering the story node that awarded it. This is the NARRATIVE scope the phone
-- gate, node-enable requirements, and gates read; level-local flags (025) promote up
-- into it when a level node's achievement fires. A fact is true once (PK on player +
-- key); the awarding node is provenance and is nullable (New Game / manual grants).

CREATE TABLE osint.achievements (
  playthrough_id     UUID NOT NULL REFERENCES osint.playthroughs(id) ON DELETE CASCADE,
  flag_key           TEXT NOT NULL CHECK (flag_key ~ '^[a-z][a-z0-9_.-]{0,63}$'),
  awarded_by_node_id UUID REFERENCES osint.story_nodes(id) ON DELETE SET NULL,
  earned_at          TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  PRIMARY KEY (playthrough_id, flag_key)
);
CREATE INDEX achievements_playthrough_idx ON osint.achievements (playthrough_id);

COMMENT ON TABLE osint.achievements IS 'Boolean achievements earned by a player (playthrough), each remembering the awarding story node. The narrative case-state that gates the phone, node-enable requirements, and story gates.';
