feat(isac): add specialization data management
This commit is contained in:
+146
-2
@@ -277,7 +277,7 @@ INSERT OR IGNORE INTO role_permissions(role_id,permission_id) VALUES('role-moder
|
||||
CREATE TABLE IF NOT EXISTS oauth_states (state_hash TEXT PRIMARY KEY, provider TEXT NOT NULL, mode TEXT NOT NULL, user_id TEXT REFERENCES users(id) ON DELETE CASCADE, expires_at TEXT NOT NULL, created_at TEXT NOT NULL);
|
||||
CREATE TABLE IF NOT EXISTS data_change_proposals (
|
||||
id TEXT PRIMARY KEY,
|
||||
module TEXT NOT NULL CHECK(module IN ('configuration','attributes','talents','brands','gear','weapons','weaponmods','protocols','skillchips')),
|
||||
module TEXT NOT NULL CHECK(module IN ('configuration','attributes','talents','brands','gear','weapons','weaponmods','gearmods','protocols','skillchips','specializations')),
|
||||
action TEXT NOT NULL,
|
||||
entity_id TEXT,
|
||||
draft_entity_id TEXT,
|
||||
@@ -322,6 +322,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS users_login_username_nocase_idx ON users(login
|
||||
CREATE TABLE IF NOT EXISTS stat_attributes (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
type TEXT NOT NULL CHECK(type IN ('Offensive', 'Defensive')),
|
||||
category TEXT NOT NULL CHECK(category IN ('Weapon', 'Skill', 'Character')),
|
||||
calculation_type TEXT NOT NULL CHECK(calculation_type IN ('Additive', 'Multiplicative')),
|
||||
@@ -776,8 +777,151 @@ CREATE TABLE IF NOT EXISTS gear_mod_secondary_quality_values (
|
||||
FOREIGN KEY(gear_mod_id,stat_attribute_id) REFERENCES gear_mod_secondary_options(gear_mod_id,stat_attribute_id) ON DELETE CASCADE,
|
||||
CHECK(max_value>=min_value)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS specialization_progression_config (
|
||||
id TEXT PRIMARY KEY CHECK(id='default'),
|
||||
xp_points INTEGER NOT NULL CHECK(xp_points>=0),
|
||||
shd_cache_points INTEGER NOT NULL CHECK(shd_cache_points>=0),
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
INSERT OR IGNORE INTO specialization_progression_config(id,xp_points,shd_cache_points,updated_at)
|
||||
VALUES('default',30,19,'2026-07-26T00:00:00.000Z');
|
||||
CREATE TABLE IF NOT EXISTS specialization_rank_cost_profiles (
|
||||
rank INTEGER PRIMARY KEY CHECK(rank BETWEEN 1 AND 3),
|
||||
point_cost INTEGER NOT NULL CHECK(point_cost>0),
|
||||
credit_cost INTEGER NOT NULL CHECK(credit_cost>=0),
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
INSERT OR IGNORE INTO specialization_rank_cost_profiles(rank,point_cost,credit_cost,updated_at)
|
||||
VALUES(1,1,2333,'2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO specialization_rank_cost_profiles(rank,point_cost,credit_cost,updated_at)
|
||||
VALUES(2,2,10000,'2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO specialization_rank_cost_profiles(rank,point_cost,credit_cost,updated_at)
|
||||
VALUES(3,3,90000,'2026-07-26T00:00:00.000Z');
|
||||
CREATE TABLE IF NOT EXISTS upgrade_resources (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
resource_type TEXT NOT NULL CHECK(resource_type IN ('Currency','Component','Progression')),
|
||||
quality TEXT CHECK(quality IS NULL OR quality IN ('Standard','Specialized','Superior','High-end')),
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK(active IN (0,1)),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS upgrade_resources_name_nocase_idx ON upgrade_resources(name COLLATE NOCASE);
|
||||
INSERT OR IGNORE INTO upgrade_resources(id,name,resource_type,quality,created_at,updated_at)
|
||||
VALUES('resource-credits','Credits','Currency',NULL,'2026-07-26T00:00:00.000Z','2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO upgrade_resources(id,name,resource_type,quality,created_at,updated_at)
|
||||
VALUES('resource-electronics-alpha','Electronics Alpha Component','Component','Specialized','2026-07-26T00:00:00.000Z','2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO upgrade_resources(id,name,resource_type,quality,created_at,updated_at)
|
||||
VALUES('resource-electronics-beta','Electronics Beta Component','Component','Specialized','2026-07-26T00:00:00.000Z','2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO upgrade_resources(id,name,resource_type,quality,created_at,updated_at)
|
||||
VALUES('resource-electronics-gamma','Electronics Gamma Component','Component','Specialized','2026-07-26T00:00:00.000Z','2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO upgrade_resources(id,name,resource_type,quality,created_at,updated_at)
|
||||
VALUES('resource-electronics-omega','Electronics Omega Component','Component','High-end','2026-07-26T00:00:00.000Z','2026-07-26T00:00:00.000Z');
|
||||
INSERT OR IGNORE INTO upgrade_resources(id,name,resource_type,quality,created_at,updated_at)
|
||||
VALUES('resource-shd-tech-cache','SHD Tech Cache','Progression','Superior','2026-07-26T00:00:00.000Z','2026-07-26T00:00:00.000Z');
|
||||
CREATE TABLE IF NOT EXISTS specializations (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK(active IN (0,1)),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS specializations_name_nocase_idx ON specializations(name COLLATE NOCASE);
|
||||
CREATE TABLE IF NOT EXISTS specialization_focuses (
|
||||
id TEXT PRIMARY KEY,
|
||||
specialization_id TEXT NOT NULL REFERENCES specializations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
primary_attribute TEXT NOT NULL CHECK(primary_attribute IN ('Firepower','Toughness','Engineering')),
|
||||
display_order INTEGER NOT NULL DEFAULT 0 CHECK(display_order>=0),
|
||||
builder_ready INTEGER NOT NULL DEFAULT 0 CHECK(builder_ready IN (0,1)),
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK(active IN (0,1)),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(specialization_id,name)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS specialization_focuses_specialization_idx ON specialization_focuses(specialization_id,display_order,name);
|
||||
CREATE TABLE IF NOT EXISTS specialization_abilities (
|
||||
id TEXT PRIMARY KEY,
|
||||
specialization_id TEXT NOT NULL REFERENCES specializations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
duration_seconds REAL CHECK(duration_seconds IS NULL OR duration_seconds>0),
|
||||
cooldown_seconds REAL CHECK(cooldown_seconds IS NULL OR cooldown_seconds>0),
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK(active IN (0,1)),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(specialization_id,name)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS specialization_abilities_specialization_idx ON specialization_abilities(specialization_id,name);
|
||||
CREATE TABLE IF NOT EXISTS specialization_ability_effects (
|
||||
id TEXT PRIMARY KEY,
|
||||
ability_id TEXT NOT NULL REFERENCES specialization_abilities(id) ON DELETE CASCADE,
|
||||
effect_order INTEGER NOT NULL CHECK(effect_order>=1),
|
||||
stat_attribute_id TEXT REFERENCES stat_attributes(id),
|
||||
label TEXT NOT NULL,
|
||||
value REAL,
|
||||
unit TEXT,
|
||||
UNIQUE(ability_id,effect_order)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS specialization_focus_abilities (
|
||||
focus_id TEXT NOT NULL REFERENCES specialization_focuses(id) ON DELETE CASCADE,
|
||||
ability_slot INTEGER NOT NULL CHECK(ability_slot BETWEEN 1 AND 3),
|
||||
ability_id TEXT NOT NULL REFERENCES specialization_abilities(id),
|
||||
PRIMARY KEY(focus_id,ability_slot),
|
||||
UNIQUE(focus_id,ability_id)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS specialization_tree_nodes (
|
||||
id TEXT PRIMARY KEY,
|
||||
focus_id TEXT NOT NULL REFERENCES specialization_focuses(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description_template TEXT NOT NULL,
|
||||
row_number INTEGER NOT NULL CHECK(row_number>=1),
|
||||
column_number INTEGER NOT NULL CHECK(column_number>=1),
|
||||
max_rank INTEGER NOT NULL CHECK(max_rank BETWEEN 1 AND 3),
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK(active IN (0,1)),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(focus_id,row_number,column_number),
|
||||
UNIQUE(focus_id,name)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS specialization_tree_nodes_focus_idx ON specialization_tree_nodes(focus_id,row_number,column_number);
|
||||
CREATE TABLE IF NOT EXISTS specialization_tree_node_ranks (
|
||||
node_id TEXT NOT NULL REFERENCES specialization_tree_nodes(id) ON DELETE CASCADE,
|
||||
rank INTEGER NOT NULL CHECK(rank BETWEEN 1 AND 3),
|
||||
description TEXT NOT NULL,
|
||||
PRIMARY KEY(node_id,rank)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS specialization_tree_rank_effects (
|
||||
id TEXT PRIMARY KEY,
|
||||
node_id TEXT NOT NULL,
|
||||
rank INTEGER NOT NULL,
|
||||
effect_order INTEGER NOT NULL CHECK(effect_order>=1),
|
||||
effect_type TEXT NOT NULL CHECK(effect_type IN ('Attribute','Ability','Custom')),
|
||||
stat_attribute_id TEXT REFERENCES stat_attributes(id),
|
||||
ability_id TEXT REFERENCES specialization_abilities(id),
|
||||
label TEXT NOT NULL,
|
||||
value REAL,
|
||||
unit TEXT,
|
||||
FOREIGN KEY(node_id,rank) REFERENCES specialization_tree_node_ranks(node_id,rank) ON DELETE CASCADE,
|
||||
UNIQUE(node_id,rank,effect_order),
|
||||
CHECK(
|
||||
(effect_type='Attribute' AND stat_attribute_id IS NOT NULL)
|
||||
OR (effect_type='Ability' AND ability_id IS NOT NULL)
|
||||
OR effect_type='Custom'
|
||||
)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS specialization_tree_rank_costs (
|
||||
node_id TEXT NOT NULL,
|
||||
rank INTEGER NOT NULL,
|
||||
resource_id TEXT NOT NULL REFERENCES upgrade_resources(id),
|
||||
quantity INTEGER NOT NULL CHECK(quantity>0),
|
||||
PRIMARY KEY(node_id,rank,resource_id),
|
||||
FOREIGN KEY(node_id,rank) REFERENCES specialization_tree_node_ranks(node_id,rank) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS game_data_icons (
|
||||
entity_type TEXT NOT NULL CHECK(entity_type IN ('talent', 'brand_set', 'os_protocol', 'skill_chip')),
|
||||
entity_type TEXT NOT NULL CHECK(entity_type IN ('talent', 'brand_set', 'os_protocol', 'skill_chip', 'specialization', 'specialization_ability', 'specialization_node')),
|
||||
entity_id TEXT NOT NULL,
|
||||
storage_key TEXT NOT NULL UNIQUE,
|
||||
byte_size INTEGER NOT NULL CHECK(byte_size > 0),
|
||||
|
||||
Reference in New Issue
Block a user