feat: Implement price list import feature with preview and apply options feat: Create price rules management page with CRUD operations feat: Develop quotes management page with itemized quotes and status tracking feat: Introduce organization registration page for new users feat: Build suppliers management page with detailed supplier information feat: Create users management page for inviting and managing roles chore: Add TypeScript configuration for improved type checking chore: Set up Vite configuration for development server and API proxy chore: Add Vite environment type definitions for better TypeScript support
95 lines
3.5 KiB
SQL
95 lines
3.5 KiB
SQL
create table if not exists users (
|
|
id uuid primary key,
|
|
email text not null unique,
|
|
display_name_ciphertext bytea,
|
|
display_name_nonce bytea,
|
|
display_name_key_id text,
|
|
password_hash text,
|
|
is_active boolean not null default true,
|
|
must_change_password boolean not null default false,
|
|
initial_password_expires_at timestamptz,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
last_login_at timestamptz,
|
|
constraint users_email_lowercase check (email = lower(email)),
|
|
constraint users_display_name_encryption_complete check (
|
|
(
|
|
display_name_ciphertext is null
|
|
and display_name_nonce is null
|
|
and display_name_key_id is null
|
|
)
|
|
or (
|
|
display_name_ciphertext is not null
|
|
and display_name_nonce is not null
|
|
and display_name_key_id is not null
|
|
)
|
|
)
|
|
);
|
|
|
|
create table if not exists organizations (
|
|
id uuid primary key,
|
|
display_name_ciphertext bytea,
|
|
display_name_nonce bytea,
|
|
display_name_key_id text,
|
|
schema_name text unique,
|
|
status text not null default 'pending_approval',
|
|
registration_email text not null,
|
|
setup_completed_at timestamptz,
|
|
approved_by_user_id uuid references users(id),
|
|
approved_at timestamptz,
|
|
rejected_by_user_id uuid references users(id),
|
|
rejected_at timestamptz,
|
|
rejection_reason text,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
constraint organizations_status_valid check (
|
|
status in ('pending_approval', 'approved', 'active', 'rejected', 'suspended')
|
|
),
|
|
constraint organizations_registration_email_lowercase check (registration_email = lower(registration_email)),
|
|
constraint organizations_schema_name_valid check (
|
|
schema_name is null or schema_name ~ '^company_[a-z0-9_]+$'
|
|
),
|
|
constraint organizations_display_name_encryption_complete check (
|
|
(
|
|
display_name_ciphertext is null
|
|
and display_name_nonce is null
|
|
and display_name_key_id is null
|
|
)
|
|
or (
|
|
display_name_ciphertext is not null
|
|
and display_name_nonce is not null
|
|
and display_name_key_id is not null
|
|
)
|
|
)
|
|
);
|
|
|
|
create table if not exists user_organizations (
|
|
user_id uuid not null references users(id) on delete cascade,
|
|
organization_id uuid not null references organizations(id) on delete cascade,
|
|
status text not null default 'pending_invitation',
|
|
invited_by_user_id uuid references users(id),
|
|
invited_at timestamptz,
|
|
accepted_at timestamptz,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
primary key (user_id, organization_id),
|
|
constraint user_organizations_status_valid check (
|
|
status in ('pending_invitation', 'active', 'disabled')
|
|
)
|
|
);
|
|
|
|
create table if not exists organization_domains (
|
|
id uuid primary key,
|
|
organization_id uuid not null references organizations(id) on delete cascade,
|
|
domain text not null unique,
|
|
is_primary boolean not null default false,
|
|
created_at timestamptz not null default now(),
|
|
constraint organization_domains_domain_lowercase check (domain = lower(domain))
|
|
);
|
|
|
|
create index if not exists idx_user_organizations_organization_id
|
|
on user_organizations (organization_id);
|
|
|
|
create index if not exists idx_organizations_status
|
|
on organizations (status);
|