Some checks failed
Deploy Development / deploy (push) Successful in 38s
Test Suite / pytest-backend (push) Failing after 7s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Co-authored-by: Cursor <cursoragent@cursor.com>
82 lines
2.9 KiB
SQL
82 lines
2.9 KiB
SQL
-- AP0.2: Auth, Identity, Tenant & Actor Foundation
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
display_name VARCHAR(255) NOT NULL,
|
|
portal_role VARCHAR(32) NOT NULL DEFAULT 'user'
|
|
CHECK (portal_role IN ('user', 'admin')),
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE tenants (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
slug VARCHAR(64) NOT NULL UNIQUE,
|
|
name VARCHAR(255) NOT NULL,
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE tenant_memberships (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
tenant_role VARCHAR(32) NOT NULL DEFAULT 'member'
|
|
CHECK (tenant_role IN ('owner', 'admin', 'member')),
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (tenant_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX idx_tenant_memberships_user ON tenant_memberships(user_id);
|
|
|
|
CREATE TABLE actors (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
actor_type VARCHAR(32) NOT NULL
|
|
CHECK (actor_type IN ('human', 'agent', 'working_group', 'external_system')),
|
|
name VARCHAR(255) NOT NULL,
|
|
user_id UUID NULL REFERENCES users(id) ON DELETE SET NULL,
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CHECK (
|
|
(actor_type = 'human' AND user_id IS NOT NULL)
|
|
OR (actor_type <> 'human' AND user_id IS NULL)
|
|
)
|
|
);
|
|
|
|
CREATE UNIQUE INDEX idx_actors_human_user_tenant
|
|
ON actors(tenant_id, user_id)
|
|
WHERE actor_type = 'human';
|
|
|
|
CREATE INDEX idx_actors_tenant ON actors(tenant_id);
|
|
|
|
CREATE TABLE sessions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
token VARCHAR(128) NOT NULL UNIQUE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
active_tenant_id UUID NULL REFERENCES tenants(id) ON DELETE SET NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_sessions_token ON sessions(token);
|
|
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
|
|
|
|
CREATE TABLE audit_log (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
action VARCHAR(64) NOT NULL,
|
|
user_id UUID NULL REFERENCES users(id) ON DELETE SET NULL,
|
|
tenant_id UUID NULL REFERENCES tenants(id) ON DELETE SET NULL,
|
|
details JSONB NOT NULL DEFAULT '{}',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_audit_log_created ON audit_log(created_at DESC);
|