-
Notifications
You must be signed in to change notification settings - Fork 0
Replace and expand StarForge database schema #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Replaces the previous schema with a comprehensive, idempotent Supabase/Postgres schema for StarForge. Adds canonical game data tables (troops, kingdoms, classes, weapons, pets, spells, aspects, medals, events), player data tables (heroes, hero_troops, pets, artifacts, teams, progress, PvP, guilds, roles, permissions, raw dumps, job logs), utility functions, triggers, materialized views, and indexes. Designed for Supabase Cloud and includes detailed instructions and notes for setup and usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR replaces the entire StarForge database schema with a comprehensive, idempotent Supabase/Postgres schema. The new schema significantly expands functionality by adding canonical game data tables for a game (troops, kingdoms, classes, weapons, pets, spells, aspects, medals, events) and player data tables (heroes, hero_troops, pets, artifacts, teams, progress, PvP data, and more).
Key changes:
- Complete schema replacement with 40+ new tables for game and player data
- Idempotent design using IF NOT EXISTS and DO blocks for triggers
- Added materialized view for optimized troop data exports
- Comprehensive trigger system for auto-updating timestamps across all tables
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| CREATE TABLE IF NOT EXISTS team_saves | ||
| ( | ||
| id | ||
| uuid | ||
| PRIMARY | ||
| KEY | ||
| DEFAULT | ||
| gen_random_uuid | ||
| ( | ||
| ), | ||
| hero_id uuid REFERENCES heroes | ||
| ( | ||
| id | ||
| ) ON DELETE CASCADE, | ||
| name text, | ||
| description text, | ||
| data jsonb NOT NULL, | ||
| is_public boolean DEFAULT false, | ||
| created_at timestamptz DEFAULT now | ||
| ( | ||
| ), | ||
| updated_at timestamptz DEFAULT now | ||
| ( | ||
| ) | ||
| ); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Missing index on the foreign key team_saves.hero_id. Although there is an index idx_team_saves_hero defined at line 1149, it should be created earlier in the index section (lines 2046-2055) for consistency with other indexes.
| CREATE TABLE IF NOT EXISTS hero_pvp_stats | ||
| ( | ||
| id | ||
| uuid | ||
| PRIMARY | ||
| KEY | ||
| DEFAULT | ||
| gen_random_uuid | ||
| ( | ||
| ), | ||
| hero_id uuid REFERENCES heroes | ||
| ( | ||
| id | ||
| ) ON DELETE CASCADE, | ||
| invades_won integer, | ||
| invades_lost integer, | ||
| defends_won integer, | ||
| defends_lost integer, | ||
| most_invaded_kingdom jsonb, | ||
| most_used_troop jsonb, | ||
| raw jsonb, | ||
| created_at timestamptz DEFAULT now | ||
| ( | ||
| ), | ||
| updated_at timestamptz DEFAULT now | ||
| ( | ||
| ), | ||
| UNIQUE | ||
| ( | ||
| hero_id | ||
| ) | ||
| ); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Missing index on the foreign key hero_pvp_stats.hero_id. Although there is a UNIQUE constraint on hero_id (line 1277-1280), a UNIQUE constraint automatically creates an index, so this is fine. However, for clarity and consistency with other tables, consider explicitly documenting this in comments.
| ( | ||
| ) | ||
| ); | ||
|
|
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing index on the foreign key hero_progress_weapons.hero_id. Add an index to improve query performance:
CREATE INDEX IF NOT EXISTS idx_hero_progress_weapons_hero ON hero_progress_weapons (hero_id);| -- Add index to improve query performance for foreign key hero_id | |
| CREATE INDEX IF NOT EXISTS idx_hero_progress_weapons_hero ON hero_progress_weapons (hero_id); |
| -- Materialized view for quick exports (troops light) | ||
| -- ------------------------ | ||
| DROP | ||
| MATERIALIZED VIEW IF EXISTS troops_master_light; |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The DROP MATERIALIZED VIEW IF EXISTS statement should be followed by CASCADE to avoid errors if there are dependent objects:
DROP MATERIALIZED VIEW IF EXISTS troops_master_light CASCADE;| MATERIALIZED VIEW IF EXISTS troops_master_light; | |
| MATERIALIZED VIEW IF EXISTS troops_master_light CASCADE; |
| ), | ||
| raw jsonb NOT NULL | ||
| ); | ||
|
|
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding an index on raw_profiles.captured_at to improve performance when querying for recent profiles or filtering by time range:
CREATE INDEX IF NOT EXISTS idx_raw_profiles_captured_at ON raw_profiles (captured_at);| -- Index to improve performance for time-based queries on raw_profiles | |
| CREATE INDEX IF NOT EXISTS idx_raw_profiles_captured_at ON raw_profiles (captured_at); |
| ( | ||
| ) | ||
| ); | ||
|
|
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The table app_users is referenced in foreign keys, but the old schema used users. This is a breaking change from the previous schema. Ensure that any existing application code that references users table is updated to use app_users, or consider maintaining backward compatibility with a view.
| -- Backward compatibility: provide a view named "users" for legacy code | |
| CREATE OR REPLACE VIEW users AS | |
| SELECT | |
| id, | |
| email, | |
| username, | |
| display_name, | |
| avatar_url, | |
| created_at, | |
| updated_at | |
| FROM app_users; |
| -- 1) Open Supabase SQL editor and paste the entire file. | ||
| -- 2) Run it. If some objects already exist the script will skip or replace as needed. | ||
| -- 3) After running, refresh your database schema in Supabase UI. | ||
|
|
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old schema had analytics_events, scheduled_jobs, and battle_simulations tables that are not present in the new schema. If these features are still needed, ensure they are implemented elsewhere or document their removal.
| -- NOTE: The old schema included the following tables, which have been removed in this version: | |
| -- - analytics_events | |
| -- - scheduled_jobs | |
| -- - battle_simulations | |
| -- If these features are still needed, please implement them elsewhere or restore the relevant tables. | |
| -- Their removal is intentional; see project documentation for details. |
| id | ||
| ), | ||
| metadata jsonb, | ||
| ip_address text, |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The audit_logs.ip_address column is defined as text but was previously defined as INET in the old schema. The INET data type provides better validation and storage efficiency for IP addresses. Consider using inet instead of text:
ip_address inet,| ip_address text, | |
| ip_address inet, |
| CREATE TABLE IF NOT EXISTS hero_meta_json | ||
| ( | ||
| id | ||
| uuid | ||
| PRIMARY | ||
| KEY | ||
| DEFAULT | ||
| gen_random_uuid | ||
| ( | ||
| ), | ||
| hero_id uuid REFERENCES heroes | ||
| ( | ||
| id | ||
| ) ON DELETE CASCADE, | ||
| key text NOT NULL, | ||
| value jsonb, | ||
| created_at timestamptz DEFAULT now | ||
| ( | ||
| ), | ||
| updated_at timestamptz DEFAULT now | ||
| ( | ||
| ) | ||
| ); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hero_meta_json table does not have an updated_at column, but a trigger hero_meta_json_updated_at_tr is created for it (lines 1993-2000). This will cause a runtime error when the trigger attempts to set NEW.updated_at. Add an updated_at timestamptz DEFAULT now() column to the table.
| ) | ||
| ); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache_invalidation table does not have an updated_at column, but a trigger cache_invalidation_updated_at_tr is created for it (lines 2036-2043). This will cause a runtime error when the trigger attempts to set NEW.updated_at. Add an updated_at timestamptz DEFAULT now() column to the table.
| ) | |
| ); | |
| ), | |
| updated_at timestamptz DEFAULT now() | |
| ); |
Replaces the previous schema with a comprehensive, idempotent Supabase/Postgres schema for StarForge. Adds canonical game data tables (troops, kingdoms, classes, weapons, pets, spells, aspects, medals, events), player data tables (heroes, hero_troops, pets, artifacts, teams, progress, PvP, guilds, roles, permissions, raw dumps, job logs), utility functions, triggers, materialized views, and indexes. Designed for Supabase Cloud and includes detailed instructions and notes for setup and usage.