-- Family network: marks a Person as a tree node and stores typed relationships
-- between two persons. The tree page (/stammbaum) only shows persons with
-- family_member = TRUE. Symmetric types (SPOUSE_OF, SIBLING_OF) are stored once;
-- the partial unique index keeps SIBLING_OF pairs from being duplicated in the
-- reverse direction.

ALTER TABLE persons
    ADD COLUMN family_member BOOLEAN NOT NULL DEFAULT FALSE;

CREATE TABLE person_relationships (
    id                 UUID         PRIMARY KEY DEFAULT gen_random_uuid(),
    person_id          UUID         NOT NULL REFERENCES persons(id) ON DELETE CASCADE,
    related_person_id  UUID         NOT NULL REFERENCES persons(id) ON DELETE CASCADE,
    relation_type      VARCHAR(30)  NOT NULL,
    from_year          INTEGER,
    to_year            INTEGER,
    notes              VARCHAR(2000),
    created_at         TIMESTAMPTZ  NOT NULL DEFAULT now(),
    CONSTRAINT no_self_rel CHECK (person_id <> related_person_id),
    CONSTRAINT unique_rel  UNIQUE (person_id, related_person_id, relation_type)
);

CREATE INDEX idx_person_rel_person_id         ON person_relationships(person_id);
CREATE INDEX idx_person_rel_related_person_id ON person_relationships(related_person_id);

-- Symmetric SIBLING_OF: enforce only one row per unordered pair.
CREATE UNIQUE INDEX unique_sibling_pair ON person_relationships (
    LEAST(person_id, related_person_id),
    GREATEST(person_id, related_person_id)
) WHERE relation_type = 'SIBLING_OF';
