Initial commit
This commit is contained in:
142
docs/critical_tables_schema.sql
Normal file
142
docs/critical_tables_schema.sql
Normal file
@@ -0,0 +1,142 @@
|
||||
-- PostgreSQL-oriented schema for Rolemaster critical tables.
|
||||
-- It is intentionally hybrid: relational axes + raw text + parsed JSON.
|
||||
|
||||
create table critical_table (
|
||||
id bigint generated always as identity primary key,
|
||||
slug text not null unique,
|
||||
display_name text not null,
|
||||
family text not null check (family in ('standard', 'variant_column', 'grouped_variant')),
|
||||
source_pdf text not null,
|
||||
source_page integer not null default 1,
|
||||
extraction_method text not null check (extraction_method in ('text', 'ocr', 'manual')),
|
||||
notes text,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
create table critical_group (
|
||||
id bigint generated always as identity primary key,
|
||||
critical_table_id bigint not null references critical_table(id) on delete cascade,
|
||||
group_key text not null,
|
||||
label text not null,
|
||||
sort_order integer not null,
|
||||
unique (critical_table_id, group_key)
|
||||
);
|
||||
|
||||
create table critical_column (
|
||||
id bigint generated always as identity primary key,
|
||||
critical_table_id bigint not null references critical_table(id) on delete cascade,
|
||||
column_key text not null,
|
||||
label text not null,
|
||||
role text not null default 'severity' check (role in ('severity', 'variant', 'other')),
|
||||
sort_order integer not null,
|
||||
unique (critical_table_id, column_key)
|
||||
);
|
||||
|
||||
create table critical_roll_band (
|
||||
id bigint generated always as identity primary key,
|
||||
critical_table_id bigint not null references critical_table(id) on delete cascade,
|
||||
label text not null,
|
||||
min_roll integer not null,
|
||||
max_roll integer,
|
||||
sort_order integer not null,
|
||||
check (max_roll is null or max_roll >= min_roll),
|
||||
unique (critical_table_id, label)
|
||||
);
|
||||
|
||||
create index critical_roll_band_lookup_idx
|
||||
on critical_roll_band (critical_table_id, min_roll, max_roll);
|
||||
|
||||
create table critical_result (
|
||||
id bigint generated always as identity primary key,
|
||||
critical_table_id bigint not null references critical_table(id) on delete cascade,
|
||||
critical_group_id bigint references critical_group(id) on delete cascade,
|
||||
critical_column_id bigint not null references critical_column(id) on delete cascade,
|
||||
critical_roll_band_id bigint not null references critical_roll_band(id) on delete cascade,
|
||||
raw_cell_text text not null,
|
||||
description_text text,
|
||||
raw_affix_text text,
|
||||
parsed_json jsonb not null default '{}'::jsonb,
|
||||
parse_status text not null default 'raw' check (parse_status in ('raw', 'partial', 'parsed', 'verified')),
|
||||
source_bbox jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
create unique index critical_result_lookup_uidx
|
||||
on critical_result (
|
||||
critical_table_id,
|
||||
coalesce(critical_group_id, 0),
|
||||
critical_column_id,
|
||||
critical_roll_band_id
|
||||
);
|
||||
|
||||
create table critical_branch (
|
||||
id bigint generated always as identity primary key,
|
||||
critical_result_id bigint not null references critical_result(id) on delete cascade,
|
||||
branch_kind text not null default 'conditional' check (branch_kind in ('conditional', 'note', 'override')),
|
||||
condition_key text,
|
||||
condition_text text not null,
|
||||
condition_json jsonb not null default '{}'::jsonb,
|
||||
raw_text text not null,
|
||||
description_text text,
|
||||
raw_affix_text text,
|
||||
parsed_json jsonb not null default '{}'::jsonb,
|
||||
sort_order integer not null default 1
|
||||
);
|
||||
|
||||
create table critical_effect (
|
||||
id bigint generated always as identity primary key,
|
||||
critical_result_id bigint references critical_result(id) on delete cascade,
|
||||
critical_branch_id bigint references critical_branch(id) on delete cascade,
|
||||
effect_code text not null,
|
||||
target text,
|
||||
value_integer integer,
|
||||
value_decimal numeric(10, 2),
|
||||
duration_rounds integer,
|
||||
per_round integer,
|
||||
modifier integer,
|
||||
body_part text,
|
||||
is_permanent boolean not null default false,
|
||||
source_type text not null default 'symbol' check (source_type in ('symbol', 'prose', 'manual')),
|
||||
source_text text,
|
||||
check ((critical_result_id is not null) <> (critical_branch_id is not null))
|
||||
);
|
||||
|
||||
create index critical_effect_lookup_idx
|
||||
on critical_effect (effect_code, target);
|
||||
|
||||
create index critical_effect_result_idx
|
||||
on critical_effect (critical_result_id);
|
||||
|
||||
create index critical_effect_branch_idx
|
||||
on critical_effect (critical_branch_id);
|
||||
|
||||
create index critical_result_parsed_json_gin
|
||||
on critical_result using gin (parsed_json);
|
||||
|
||||
create index critical_branch_parsed_json_gin
|
||||
on critical_branch using gin (parsed_json);
|
||||
|
||||
-- Example lookup pattern:
|
||||
--
|
||||
-- select
|
||||
-- t.slug as critical_type,
|
||||
-- t.display_name as table_name,
|
||||
-- g.group_key,
|
||||
-- c.column_key,
|
||||
-- rb.label as roll_band,
|
||||
-- rb.min_roll,
|
||||
-- rb.max_roll,
|
||||
-- r.description_text,
|
||||
-- r.raw_affix_text,
|
||||
-- r.raw_cell_text,
|
||||
-- r.parsed_json
|
||||
-- from critical_result r
|
||||
-- join critical_table t on t.id = r.critical_table_id
|
||||
-- left join critical_group g on g.id = r.critical_group_id
|
||||
-- join critical_column c on c.id = r.critical_column_id
|
||||
-- join critical_roll_band rb on rb.id = r.critical_roll_band_id
|
||||
-- where t.slug = 'slash'
|
||||
-- and c.column_key = 'C'
|
||||
-- and 38 >= rb.min_roll
|
||||
-- and (rb.max_roll is null or 38 <= rb.max_roll);
|
||||
|
||||
Reference in New Issue
Block a user