-- 0001_init.sql — SD-0001 §6.3 data model. Forward-only and fail-stop (INV-7):
-- do NOT edit this file once it has merged/applied; add a new numbered migration.

-- account — a person's identity on the platform. Email is the canonical key (INV-2);
-- the address is stored already-normalized (lowercased) by the service layer, so a
-- plain unique index enforces one-account-per-email. Data minimization (OHM): email
-- and nothing else (§6.3).
CREATE TABLE account (
    id          BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    email       TEXT        NOT NULL,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX account_email_key ON account (email);  -- INV-2

-- auth_code — one-time codes, handled like secrets (INV-3): only the hash is stored;
-- keyed by email (the code is issued before the account may exist — sign-up and
-- log-in converge, PUC-3).
CREATE TABLE auth_code (
    id           BIGINT       GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    email        TEXT         NOT NULL,
    code_hash    TEXT         NOT NULL,
    expires_at   TIMESTAMPTZ  NOT NULL,
    attempts     INTEGER      NOT NULL DEFAULT 0,
    consumed_at  TIMESTAMPTZ,
    created_at   TIMESTAMPTZ  NOT NULL DEFAULT now()
);
CREATE INDEX auth_code_email_idx ON auth_code (email);

-- storefront — a merchant's business presence. Name is always populated (a blank
-- entry gets a generated default at the service layer, §6.3); "unnamed" is never NULL.
CREATE TABLE storefront (
    id          BIGINT       GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name        TEXT         NOT NULL,
    created_at  TIMESTAMPTZ  NOT NULL DEFAULT now()
);

-- storefront_membership — account <-> storefront ownership. INV-4: deliberately a
-- many-to-many shape (composite PK, no UNIQUE(account_id)) so many-storefronts-per-
-- account stays open; the one-storefront rule is a deletable service-layer guard, not
-- a schema law. INV-5: every storefront-scoped row carries its storefront_id. `role`
-- is a single-value enum today; it is the seam the staff/permissions model attaches to.
CREATE TABLE storefront_membership (
    account_id     BIGINT       NOT NULL REFERENCES account (id),
    storefront_id  BIGINT       NOT NULL REFERENCES storefront (id),
    role           TEXT         NOT NULL DEFAULT 'owner' CHECK (role IN ('owner')),
    created_at     TIMESTAMPTZ  NOT NULL DEFAULT now(),
    PRIMARY KEY (account_id, storefront_id)
);
