Skip to content

Commit d4de164

Browse files
committed
Merge Bravo Text to Speech EOD
# Conflicts: # docs_build/dev/reports/codex_changed_files.txt # docs_build/dev/reports/codex_review.diff
2 parents effd7c0 + d8beea5 commit d4de164

36 files changed

Lines changed: 3320 additions & 2051 deletions

assets/toolbox/text-to-speech/js/index.js

Lines changed: 329 additions & 123 deletions
Large diffs are not rendered by default.

docs_build/database/ddl/messages.sql

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-- Target DEV database: gamefoundry_dev
55
-- Scope: executable grouped table DDL for active server API migration.
66
-- Authoritative key values are generated by the server/API layer unless a later DEV-only seed exception explicitly applies.
7-
-- Owned tables: messages_categories, messages_emotion_profiles, messages_tts_profiles, messages_records, messages_segments
7+
-- Owned tables: messages_categories, messages_emotion_profiles, messages_tts_profiles, messages_tts_profile_emotion_settings, messages_records, messages_segments, messages_event_actions
88
CREATE TABLE IF NOT EXISTS messages_categories (
99
key text PRIMARY KEY,
1010
"name" text NOT NULL UNIQUE,
@@ -31,30 +31,48 @@ CREATE TABLE IF NOT EXISTS messages_emotion_profiles (
3131
"updatedBy" text NOT NULL REFERENCES users(key)
3232
);
3333

34-
CREATE TABLE IF NOT EXISTS messages_records (
34+
CREATE TABLE IF NOT EXISTS messages_tts_profiles (
3535
key text PRIMARY KEY,
36-
"name" text NOT NULL,
37-
"categoryKey" text NOT NULL REFERENCES messages_categories(key),
38-
"emotionProfileKey" text NOT NULL REFERENCES messages_emotion_profiles(key),
39-
"messageText" text NOT NULL,
40-
"notes" text NOT NULL DEFAULT '',
36+
"name" text NOT NULL UNIQUE,
37+
"description" text NOT NULL DEFAULT '',
38+
"providerKey" text NOT NULL,
39+
"voiceName" text NOT NULL DEFAULT '',
40+
"language" text NOT NULL,
41+
"volume" numeric NOT NULL DEFAULT 1,
42+
"pitch" numeric NOT NULL DEFAULT 1,
43+
"rate" numeric NOT NULL DEFAULT 1,
4144
"active" boolean NOT NULL DEFAULT true,
4245
"createdAt" timestamptz NOT NULL DEFAULT now(),
4346
"updatedAt" timestamptz NOT NULL DEFAULT now(),
4447
"createdBy" text NOT NULL REFERENCES users(key),
4548
"updatedBy" text NOT NULL REFERENCES users(key)
4649
);
4750

48-
CREATE TABLE IF NOT EXISTS messages_tts_profiles (
51+
CREATE TABLE IF NOT EXISTS messages_tts_profile_emotion_settings (
4952
key text PRIMARY KEY,
50-
"name" text NOT NULL UNIQUE,
51-
"description" text NOT NULL DEFAULT '',
52-
"providerKey" text NOT NULL,
53-
"voiceName" text NOT NULL DEFAULT '',
54-
"language" text NOT NULL,
53+
"ttsProfileKey" text NOT NULL REFERENCES messages_tts_profiles(key),
54+
"emotionProfileKey" text NOT NULL REFERENCES messages_emotion_profiles(key),
5555
"volume" numeric NOT NULL DEFAULT 1,
5656
"pitch" numeric NOT NULL DEFAULT 1,
5757
"rate" numeric NOT NULL DEFAULT 1,
58+
"displayOrder" integer NOT NULL DEFAULT 0,
59+
"ssmlLikePreset" text NOT NULL DEFAULT 'normal',
60+
"active" boolean NOT NULL DEFAULT true,
61+
"createdAt" timestamptz NOT NULL DEFAULT now(),
62+
"updatedAt" timestamptz NOT NULL DEFAULT now(),
63+
"createdBy" text NOT NULL REFERENCES users(key),
64+
"updatedBy" text NOT NULL REFERENCES users(key),
65+
UNIQUE ("ttsProfileKey", "emotionProfileKey")
66+
);
67+
68+
CREATE TABLE IF NOT EXISTS messages_records (
69+
key text PRIMARY KEY,
70+
"name" text NOT NULL,
71+
"categoryKey" text NOT NULL REFERENCES messages_categories(key),
72+
"emotionProfileKey" text NOT NULL REFERENCES messages_emotion_profiles(key),
73+
"voiceProfileKey" text NOT NULL REFERENCES messages_tts_profiles(key),
74+
"messageText" text NOT NULL,
75+
"notes" text NOT NULL DEFAULT '',
5876
"active" boolean NOT NULL DEFAULT true,
5977
"createdAt" timestamptz NOT NULL DEFAULT now(),
6078
"updatedAt" timestamptz NOT NULL DEFAULT now(),
@@ -66,6 +84,7 @@ CREATE TABLE IF NOT EXISTS messages_segments (
6684
key text PRIMARY KEY,
6785
"messageKey" text NOT NULL REFERENCES messages_records(key),
6886
"emotionProfileKey" text NOT NULL REFERENCES messages_emotion_profiles(key),
87+
"voiceProfileKey" text NOT NULL REFERENCES messages_tts_profiles(key),
6988
"segmentText" text NOT NULL,
7089
"displayOrder" integer NOT NULL,
7190
"active" boolean NOT NULL DEFAULT true,
@@ -75,15 +94,38 @@ CREATE TABLE IF NOT EXISTS messages_segments (
7594
"updatedBy" text NOT NULL REFERENCES users(key)
7695
);
7796

97+
CREATE TABLE IF NOT EXISTS messages_event_actions (
98+
key text PRIMARY KEY,
99+
"name" text NOT NULL,
100+
"actionType" text NOT NULL,
101+
"messageKey" text REFERENCES messages_records(key),
102+
"active" boolean NOT NULL DEFAULT true,
103+
"createdAt" timestamptz NOT NULL DEFAULT now(),
104+
"updatedAt" timestamptz NOT NULL DEFAULT now(),
105+
"createdBy" text NOT NULL REFERENCES users(key),
106+
"updatedBy" text NOT NULL REFERENCES users(key)
107+
);
108+
78109
CREATE INDEX IF NOT EXISTS idx_messages_records_categorykey ON messages_records ("categoryKey");
79110
CREATE INDEX IF NOT EXISTS idx_messages_records_emotionprofilekey ON messages_records ("emotionProfileKey");
111+
CREATE INDEX IF NOT EXISTS idx_messages_records_voiceprofilekey ON messages_records ("voiceProfileKey");
80112
CREATE INDEX IF NOT EXISTS idx_messages_records_createdby ON messages_records ("createdBy");
81113
CREATE INDEX IF NOT EXISTS idx_messages_records_updatedby ON messages_records ("updatedBy");
82114
CREATE INDEX IF NOT EXISTS idx_messages_segments_messagekey ON messages_segments ("messageKey");
83115
CREATE INDEX IF NOT EXISTS idx_messages_segments_emotionprofilekey ON messages_segments ("emotionProfileKey");
116+
CREATE INDEX IF NOT EXISTS idx_messages_segments_voiceprofilekey ON messages_segments ("voiceProfileKey");
84117
CREATE INDEX IF NOT EXISTS idx_messages_segments_order ON messages_segments ("messageKey", "displayOrder");
85118
CREATE INDEX IF NOT EXISTS idx_messages_segments_createdby ON messages_segments ("createdBy");
86119
CREATE INDEX IF NOT EXISTS idx_messages_segments_updatedby ON messages_segments ("updatedBy");
120+
CREATE INDEX IF NOT EXISTS idx_messages_event_actions_actiontype ON messages_event_actions ("actionType");
121+
CREATE INDEX IF NOT EXISTS idx_messages_event_actions_messagekey ON messages_event_actions ("messageKey");
122+
CREATE INDEX IF NOT EXISTS idx_messages_event_actions_createdby ON messages_event_actions ("createdBy");
123+
CREATE INDEX IF NOT EXISTS idx_messages_event_actions_updatedby ON messages_event_actions ("updatedBy");
87124
CREATE INDEX IF NOT EXISTS idx_messages_tts_profiles_providerkey ON messages_tts_profiles ("providerKey");
88125
CREATE INDEX IF NOT EXISTS idx_messages_tts_profiles_createdby ON messages_tts_profiles ("createdBy");
89126
CREATE INDEX IF NOT EXISTS idx_messages_tts_profiles_updatedby ON messages_tts_profiles ("updatedBy");
127+
CREATE INDEX IF NOT EXISTS idx_messages_tts_profile_emotion_settings_ttsprofilekey ON messages_tts_profile_emotion_settings ("ttsProfileKey");
128+
CREATE INDEX IF NOT EXISTS idx_messages_tts_profile_emotion_settings_emotionprofilekey ON messages_tts_profile_emotion_settings ("emotionProfileKey");
129+
CREATE INDEX IF NOT EXISTS idx_messages_tts_profile_emotion_settings_order ON messages_tts_profile_emotion_settings ("ttsProfileKey", "displayOrder");
130+
CREATE INDEX IF NOT EXISTS idx_messages_tts_profile_emotion_settings_createdby ON messages_tts_profile_emotion_settings ("createdBy");
131+
CREATE INDEX IF NOT EXISTS idx_messages_tts_profile_emotion_settings_updatedby ON messages_tts_profile_emotion_settings ("updatedBy");
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"group": "Idea Board",
3+
"groupKey": "idea-board",
4+
"owner": "docs_build/database/seed/guest",
5+
"readOnly": true,
6+
"writableByGuest": false,
7+
"signInRedirect": "account/sign-in.html",
8+
"tables": {},
9+
"samplePackages": [
10+
{
11+
"key": "guest-idea-board-starter",
12+
"audience": "guest",
13+
"createdBy": "01K2GFSJ0Y0000000000000054",
14+
"groupKey": "idea-board",
15+
"label": "Guest Idea Board starter",
16+
"loadablePath": "toolbox/idea-board/index.html",
17+
"readOnly": true,
18+
"sampleKind": "toolSeed",
19+
"signInRedirect": "account/sign-in.html",
20+
"source": "docs_build/database/seed/guest/idea-board.json",
21+
"toolKey": "idea-board",
22+
"toolName": "Idea Board",
23+
"writableByGuest": false
24+
}
25+
]
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"group": "Message Studio",
3+
"groupKey": "messages",
4+
"owner": "docs_build/database/seed/guest",
5+
"readOnly": true,
6+
"writableByGuest": false,
7+
"signInRedirect": "account/sign-in.html",
8+
"tables": {},
9+
"samplePackages": [
10+
{
11+
"key": "guest-messages-starter",
12+
"audience": "guest",
13+
"createdBy": "01K2GFSJ0Y0000000000000054",
14+
"groupKey": "messages",
15+
"label": "Guest Message Studio starter",
16+
"loadablePath": "toolbox/messages/index.html",
17+
"readOnly": true,
18+
"sampleKind": "toolSeed",
19+
"signInRedirect": "account/sign-in.html",
20+
"source": "docs_build/database/seed/guest/messages.json",
21+
"toolKey": "messages",
22+
"toolName": "Message Studio",
23+
"writableByGuest": false
24+
}
25+
]
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"group": "Text To Speech",
3+
"groupKey": "text-to-speech",
4+
"owner": "docs_build/database/seed/guest",
5+
"readOnly": true,
6+
"writableByGuest": false,
7+
"signInRedirect": "account/sign-in.html",
8+
"tables": {},
9+
"samplePackages": [
10+
{
11+
"key": "guest-text-to-speech-starter",
12+
"audience": "guest",
13+
"createdBy": "01K2GFSJ0Y0000000000000054",
14+
"groupKey": "text-to-speech",
15+
"label": "Guest Text To Speech starter",
16+
"loadablePath": "toolbox/text-to-speech/index.html",
17+
"readOnly": true,
18+
"sampleKind": "toolSeed",
19+
"signInRedirect": "account/sign-in.html",
20+
"source": "docs_build/database/seed/guest/text-to-speech.json",
21+
"toolKey": "text-to-speech",
22+
"toolName": "Text To Speech",
23+
"writableByGuest": false
24+
}
25+
]
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"group": "Game Crew",
3+
"groupKey": "users",
4+
"owner": "docs_build/database/seed/guest",
5+
"readOnly": true,
6+
"writableByGuest": false,
7+
"signInRedirect": "account/sign-in.html",
8+
"tables": {},
9+
"samplePackages": [
10+
{
11+
"key": "guest-users-starter",
12+
"audience": "guest",
13+
"createdBy": "01K2GFSJ0Y0000000000000054",
14+
"groupKey": "users",
15+
"label": "Guest Game Crew starter",
16+
"loadablePath": "toolbox/game-crew/index.html",
17+
"readOnly": true,
18+
"sampleKind": "toolSeed",
19+
"signInRedirect": "account/sign-in.html",
20+
"source": "docs_build/database/seed/guest/users.json",
21+
"toolKey": "users",
22+
"toolName": "Game Crew",
23+
"writableByGuest": false
24+
}
25+
]
26+
}

docs_build/database/seed/messages.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,9 @@
2424
"Sad",
2525
"Mysterious"
2626
],
27-
"messages_tts_profiles": [
28-
"Browser Speech Default",
29-
"Narration Preview"
30-
],
27+
"messages_tts_profiles": [],
3128
"messages_records": [],
3229
"messages_segments": []
3330
},
34-
"note": "Seed names are applied by the server-side Messages Postgres service. Browser pages must not seed authoritative records."
31+
"note": "Seed names are applied by the server-side Messages Postgres service. Browser pages must not seed authoritative records. Retired TTS parent profiles Default Balanced Profile, Hero, Merchant, Neutral, and Robot are pruned server-side and must not be reintroduced as seed records. Empty TTS parent profiles without child emotion settings are also pruned instead of repaired with fallback children."
3532
}

docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ Rules:
145145
- Each PR must be committed, pushed, and opened as a draft PR.
146146
- Each PR starts at PR Open after the branch and PR identity are named.
147147
- Each PR plans and builds on the same source branch after PR Open.
148-
- Each PR reaches Closed only after main-return, clean-worktree, local/origin `0/0`, no-untracked-files, required-report, required-ZIP, backlog, applicable tool-state, and retained-branch-disposition gates pass.
148+
- During assigned team-day work, sequential PRs must remain on the assigned team branch until EOD or an owner-approved merge checkpoint.
149+
- Returning to `main` between sequential team PRs is prohibited.
150+
- Each PR reaches Closed only after clean-worktree, local/origin sync for the active source branch, no-untracked-files, required-report, required-ZIP, backlog, applicable tool-state, retained-branch-disposition gates, and the applicable EOD/main-verification gate pass.
149151
- A team must not begin another PR until its previous PR is Closed unless OWNER documented an explicit stacked PR chain.
150152
- Do not commit directly to main.
151153
- Do not merge without explicit owner approval.
@@ -174,6 +176,7 @@ Rules:
174176
- Each PR may be committed and pushed during active work.
175177
- Each PR may be opened as a draft PR during active work.
176178
- Each PR must move through PR Open, Plan, Build, Validation, Approved, Merged, Main Verified, and Closed in order.
179+
- For assigned team-day work, Main Verified occurs only at EOD or an owner-approved merge checkpoint; it is not permission to return to `main` between sequential PRs.
177180
- Plan, Build, validation, reports, ZIP packaging, and closeout must stay tied to the same PR identity and source branch.
178181
- Source branches are retained by default after merge and closeout.
179182
- A team must not begin another PR until its previous PR is Closed unless OWNER documented an explicit stacked PR chain.
@@ -188,6 +191,7 @@ Rules:
188191
Conflict note:
189192
- Older wording that says each PR must create its own branch remains preserved.
190193
- This all-team clarification allows an approved existing team, OWNER, or scoped PR branch when the owner assigns that dependency model.
194+
- The Day Work / EOD Merge Rule below overrides older main-return wording during assigned team-day sequences.
191195
- If a branch model is unclear, owner approval is required before continuing.
192196

193197
## Day Work / EOD Merge Rule
@@ -198,7 +202,11 @@ During active work:
198202
- Pushes are allowed and expected.
199203
- Draft PRs are allowed and expected.
200204
- Direct commits to main are prohibited.
205+
- Codex must stay on the assigned team branch until EOD or an owner-approved merge checkpoint.
206+
- Returning to `main` between sequential PRs in the same assigned team-day workstream is prohibited.
201207
- Merges to main are prohibited unless explicitly approved by the owner.
208+
- Any staged changes, unstaged changes, unmerged state, or direct commit on `main` during team work is a governance failure.
209+
- If that failure occurs, Codex must hard-stop, move the scoped work to the active team branch, restore `main` to a clean state, document the correction, and continue only from the team branch.
202210

203211
At end of day:
204212
- Owner reviews ready PRs.

0 commit comments

Comments
 (0)