102 lines
3.9 KiB
JavaScript
102 lines
3.9 KiB
JavaScript
import { createPool, waitForDatabase } from './db.mjs'
|
|
|
|
const pool = createPool()
|
|
|
|
try {
|
|
await waitForDatabase(pool)
|
|
await pool.query('begin')
|
|
await pool.query(`
|
|
create extension if not exists pgcrypto;
|
|
|
|
create table if not exists app_users (
|
|
id uuid primary key default gen_random_uuid(),
|
|
auth_issuer text not null,
|
|
auth_subject text not null,
|
|
username text,
|
|
password_hash text,
|
|
password_salt text,
|
|
display_name text not null default 'Healer',
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (auth_issuer, auth_subject)
|
|
);
|
|
|
|
alter table app_users add column if not exists username text;
|
|
alter table app_users add column if not exists password_hash text;
|
|
alter table app_users add column if not exists password_salt text;
|
|
|
|
create unique index if not exists app_users_username_lower_idx
|
|
on app_users (lower(username))
|
|
where username is not null;
|
|
|
|
create table if not exists sessions (
|
|
id uuid primary key default gen_random_uuid(),
|
|
user_id uuid not null references app_users(id) on delete cascade,
|
|
token_hash text not null unique,
|
|
expires_at timestamptz not null,
|
|
created_ip text not null,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
|
|
create table if not exists save_slots (
|
|
id uuid primary key default gen_random_uuid(),
|
|
user_id uuid not null references app_users(id) on delete cascade,
|
|
slot_key text not null default 'default',
|
|
save_json jsonb not null,
|
|
save_version integer not null default 1,
|
|
client_updated_at timestamptz,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (user_id, slot_key)
|
|
);
|
|
|
|
create table if not exists action_mechanic_configs (
|
|
id uuid primary key default gen_random_uuid(),
|
|
user_id uuid references app_users(id) on delete cascade,
|
|
config_key text not null default 'default',
|
|
config_json jsonb not null,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (user_id, config_key)
|
|
);
|
|
|
|
create table if not exists pvp_queue (
|
|
id uuid primary key default gen_random_uuid(),
|
|
user_id uuid not null references app_users(id) on delete cascade,
|
|
mode text not null default 'action-healer',
|
|
rating integer not null default 1000,
|
|
status text not null default 'queued',
|
|
queued_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (user_id, mode, status)
|
|
);
|
|
|
|
create table if not exists pvp_matches (
|
|
id uuid primary key default gen_random_uuid(),
|
|
mode text not null default 'action-healer',
|
|
status text not null default 'pending',
|
|
player_one_id uuid not null references app_users(id) on delete cascade,
|
|
player_two_id uuid references app_users(id) on delete cascade,
|
|
match_state jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
completed_at timestamptz
|
|
);
|
|
|
|
create index if not exists save_slots_user_id_idx on save_slots(user_id);
|
|
create index if not exists sessions_token_hash_idx on sessions(token_hash);
|
|
create index if not exists sessions_expires_at_idx on sessions(expires_at);
|
|
create index if not exists pvp_queue_mode_status_idx on pvp_queue(mode, status, queued_at);
|
|
create index if not exists pvp_matches_player_one_idx on pvp_matches(player_one_id);
|
|
create index if not exists pvp_matches_player_two_idx on pvp_matches(player_two_id);
|
|
`)
|
|
await pool.query('commit')
|
|
console.log('Database initialized.')
|
|
} catch (error) {
|
|
await pool.query('rollback').catch(() => {})
|
|
console.error(error)
|
|
process.exitCode = 1
|
|
} finally {
|
|
await pool.end()
|
|
}
|