-- v1.1.8 User Management — data-plane app users.
--
-- Distinct from `admin_users` (control-plane operators). These are the
-- end-users of apps built on PiCloud — created and managed by user
-- scripts via the `users::*` SDK, surfaced to the dashboard via
-- `/api/v1/admin/apps/{id}/users/*`.
--
-- Identity tuple is `(app_id, id)`; uniqueness is enforced on
-- `(app_id, lower(email))` so the same email can exist across two apps
-- but not twice within one app. Email case is preserved in storage and
-- normalized only at the index / lookup boundary.
--
-- Password hash is Argon2id PHC (same algorithm as `admin_users` — the
-- script-end-user trust shape and the operator-account trust shape
-- happen to coincide on the hashing primitive even though everything
-- else about the two tables is independent).

CREATE TABLE app_users (
    id                 UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    app_id             UUID NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
    email              TEXT NOT NULL,
    password_hash      TEXT NOT NULL,
    display_name       TEXT,
    email_verified_at  TIMESTAMPTZ,
    last_login_at      TIMESTAMPTZ,
    created_at         TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE UNIQUE INDEX idx_app_users_app_email_lower ON app_users (app_id, lower(email));
CREATE INDEX idx_app_users_app ON app_users (app_id);
