90ac0b81d1
Add full V2 architecture: identity, content, studio (.NET 10) and file, render, notification, gateway (Go) services with vendored deps, plus DB migrations, event/API contracts, and an init-db script. Wire the Next.js frontend to the gateway: server-side JWT auth routes (login/register/refresh/logout/me), gateway fetch helper, and session/ cookie/jwt helpers under src/lib. Containerize the stack via docker-compose.v2.yml and per-service Dockerfiles. Base images resolve through a Nexus mirror (Docker Hub) and MCR directly; npm/NuGet pull from Nexus groups. Self-host fonts via next/font/local to avoid Google Fonts (geo-blocked). Add CI workflow and ignore .env.v2, *.stackdump, and .NET bin/obj. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
161 lines
7.6 KiB
SQL
161 lines
7.6 KiB
SQL
-- =====================================================================
|
|
-- CONTENT SCHEMA — Part 4: Characters & Preset Stories
|
|
-- =====================================================================
|
|
|
|
SET search_path TO content, public;
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- scene_characters — character elements per scene
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE scene_characters (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
scene_id UUID NOT NULL REFERENCES scenes(id) ON DELETE CASCADE,
|
|
key TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
icon TEXT,
|
|
sort INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (scene_id, key)
|
|
);
|
|
|
|
CREATE INDEX idx_scene_chars_scene ON scene_characters(scene_id);
|
|
|
|
CREATE TRIGGER tg_scene_chars_updated_at
|
|
BEFORE UPDATE ON scene_characters FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- scene_character_controllers — animation properties of a character
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE scene_character_controllers (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
scene_character_id UUID NOT NULL REFERENCES scene_characters(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
key TEXT NOT NULL,
|
|
default_value TEXT,
|
|
sort INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_scene_char_ctrl_char ON scene_character_controllers(scene_character_id);
|
|
|
|
CREATE TRIGGER tg_scene_char_ctrl_updated_at
|
|
BEFORE UPDATE ON scene_character_controllers FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- scene_controller_options — discrete value options per controller
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE scene_controller_options (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
controller_id UUID NOT NULL REFERENCES scene_character_controllers(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
icon TEXT,
|
|
value TEXT NOT NULL,
|
|
sort INT NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX idx_scene_ctrl_opt_ctrl ON scene_controller_options(controller_id);
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- project_character_controllers — project-wide character animation defs
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE project_character_controllers (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
key TEXT NOT NULL,
|
|
sort INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (project_id, key)
|
|
);
|
|
|
|
CREATE INDEX idx_proj_char_ctrl_project ON project_character_controllers(project_id);
|
|
|
|
CREATE TRIGGER tg_proj_char_ctrl_updated_at
|
|
BEFORE UPDATE ON project_character_controllers FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- project_character_controller_options
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE project_character_controller_options (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
controller_id UUID NOT NULL REFERENCES project_character_controllers(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
icon TEXT,
|
|
value TEXT NOT NULL,
|
|
sort INT NOT NULL DEFAULT 0
|
|
);
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- project_character_presets — named bundles of controller values
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE project_character_presets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
key UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
name TEXT NOT NULL,
|
|
icon TEXT,
|
|
sort INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_char_presets_project ON project_character_presets(project_id);
|
|
|
|
CREATE TRIGGER tg_char_presets_updated_at
|
|
BEFORE UPDATE ON project_character_presets FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- preset_character_controllers — controller values inside a preset
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE preset_character_controllers (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
character_preset_id UUID NOT NULL REFERENCES project_character_presets(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
key TEXT NOT NULL,
|
|
value TEXT NOT NULL,
|
|
sort INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_preset_char_ctrl_preset ON preset_character_controllers(character_preset_id);
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- preset_stories — pre-made scene combinations
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE preset_stories (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
demo TEXT,
|
|
music_id UUID REFERENCES music_tracks(id),
|
|
scenes_spa TEXT, -- legacy serialized SPA (kept for migration)
|
|
sort INT NOT NULL DEFAULT 0,
|
|
is_published BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX idx_preset_stories_project ON preset_stories(project_id) WHERE deleted_at IS NULL;
|
|
|
|
CREATE TRIGGER tg_preset_stories_updated_at
|
|
BEFORE UPDATE ON preset_stories FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- preset_scenes — which scenes appear in a preset story and order
|
|
-- ---------------------------------------------------------------------
|
|
CREATE TABLE preset_scenes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
preset_story_id UUID NOT NULL REFERENCES preset_stories(id) ON DELETE CASCADE,
|
|
scene_id UUID NOT NULL REFERENCES scenes(id) ON DELETE CASCADE,
|
|
sort INT NOT NULL DEFAULT 0,
|
|
default_duration_sec NUMERIC(8,2),
|
|
UNIQUE (preset_story_id, sort)
|
|
);
|
|
|
|
CREATE INDEX idx_preset_scenes_story ON preset_scenes(preset_story_id, sort);
|