chore: merge Rust backend into monorepo
git-subtree-dir: server git-subtree-mainline:fb6a84d75fgit-subtree-split:8a88706ff9
This commit is contained in:
45
server/migrations/0001_initial_schema.sql
Normal file
45
server/migrations/0001_initial_schema.sql
Normal file
@@ -0,0 +1,45 @@
|
||||
CREATE TABLE student_profiles (
|
||||
id UUID PRIMARY KEY,
|
||||
owner_id UUID NOT NULL,
|
||||
name VARCHAR(20) NOT NULL CHECK (char_length(btrim(name)) BETWEEN 1 AND 20),
|
||||
grade VARCHAR(40) NOT NULL CHECK (char_length(btrim(grade)) > 0),
|
||||
subject VARCHAR(40) NOT NULL CHECK (char_length(btrim(subject)) > 0),
|
||||
academic_year SMALLINT NOT NULL CHECK (academic_year BETWEEN 2000 AND 2200),
|
||||
term VARCHAR(1) NOT NULL CHECK (term IN ('春', '暑', '秋', '寒')),
|
||||
guardian_title VARCHAR(24) NOT NULL CHECK (char_length(btrim(guardian_title)) BETWEEN 1 AND 24),
|
||||
start_time CHAR(5) NOT NULL,
|
||||
end_time CHAR(5) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX student_profiles_owner_updated_idx
|
||||
ON student_profiles (owner_id, updated_at DESC);
|
||||
|
||||
CREATE INDEX student_profiles_owner_grade_subject_idx
|
||||
ON student_profiles (owner_id, grade, subject);
|
||||
|
||||
CREATE TABLE student_profile_defaults (
|
||||
owner_id UUID PRIMARY KEY,
|
||||
grade VARCHAR(40) NOT NULL CHECK (char_length(btrim(grade)) > 0),
|
||||
subject VARCHAR(40) NOT NULL CHECK (char_length(btrim(subject)) > 0),
|
||||
lesson_duration_minutes SMALLINT NOT NULL
|
||||
CHECK (lesson_duration_minutes BETWEEN 15 AND 360 AND lesson_duration_minutes % 15 = 0),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE feedback_records (
|
||||
id UUID PRIMARY KEY,
|
||||
owner_id UUID NOT NULL,
|
||||
profile_id UUID REFERENCES student_profiles(id) ON DELETE SET NULL,
|
||||
feedback_date DATE NOT NULL,
|
||||
content TEXT NOT NULL CHECK (char_length(btrim(content)) > 0),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX feedback_records_owner_date_idx
|
||||
ON feedback_records (owner_id, feedback_date DESC, updated_at DESC);
|
||||
|
||||
CREATE INDEX feedback_records_owner_profile_idx
|
||||
ON feedback_records (owner_id, profile_id);
|
||||
57
server/migrations/0002_voice_feedback_sessions.sql
Normal file
57
server/migrations/0002_voice_feedback_sessions.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
CREATE TABLE feedback_sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
owner_id UUID NOT NULL,
|
||||
profile_id UUID REFERENCES student_profiles(id) ON DELETE CASCADE,
|
||||
feedback_date DATE NOT NULL,
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'active'
|
||||
CHECK (status IN ('active', 'finalized')),
|
||||
finalized_record_id UUID REFERENCES feedback_records(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX feedback_sessions_owner_status_idx
|
||||
ON feedback_sessions (owner_id, status, updated_at DESC);
|
||||
|
||||
CREATE UNIQUE INDEX feedback_sessions_one_active_idx
|
||||
ON feedback_sessions (owner_id, COALESCE(profile_id, '00000000-0000-0000-0000-000000000000'::UUID))
|
||||
WHERE status = 'active';
|
||||
|
||||
CREATE TABLE lesson_sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
feedback_session_id UUID NOT NULL REFERENCES feedback_sessions(id) ON DELETE CASCADE,
|
||||
sequence INTEGER NOT NULL CHECK (sequence > 0),
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'recording'
|
||||
CHECK (status IN ('recording', 'processing', 'ready', 'failed')),
|
||||
duration_ms INTEGER NOT NULL DEFAULT 0 CHECK (duration_ms >= 0),
|
||||
applied_directly BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
included_in_generation BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
ended_at TIMESTAMPTZ,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (feedback_session_id, sequence)
|
||||
);
|
||||
|
||||
CREATE INDEX lesson_sessions_feedback_session_idx
|
||||
ON lesson_sessions (feedback_session_id, sequence);
|
||||
|
||||
CREATE TABLE audio_segments (
|
||||
id UUID PRIMARY KEY,
|
||||
lesson_session_id UUID NOT NULL REFERENCES lesson_sessions(id) ON DELETE CASCADE,
|
||||
sequence INTEGER NOT NULL CHECK (sequence > 0),
|
||||
duration_ms INTEGER NOT NULL CHECK (duration_ms > 0),
|
||||
audio_format VARCHAR(8) NOT NULL,
|
||||
audio_path TEXT NOT NULL,
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'processing'
|
||||
CHECK (status IN ('processing', 'ready', 'failed')),
|
||||
transcript TEXT,
|
||||
error_message TEXT,
|
||||
provider_request_id VARCHAR(100),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (lesson_session_id, sequence)
|
||||
);
|
||||
|
||||
CREATE INDEX audio_segments_lesson_session_idx
|
||||
ON audio_segments (lesson_session_id, sequence);
|
||||
8
server/migrations/0003_async_transcription_jobs.sql
Normal file
8
server/migrations/0003_async_transcription_jobs.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE audio_segments
|
||||
ADD COLUMN transcription_attempts INTEGER NOT NULL DEFAULT 0
|
||||
CHECK (transcription_attempts >= 0),
|
||||
ADD COLUMN processing_started_at TIMESTAMPTZ;
|
||||
|
||||
CREATE INDEX audio_segments_processing_queue_idx
|
||||
ON audio_segments (created_at, id)
|
||||
WHERE status = 'processing';
|
||||
Reference in New Issue
Block a user