fix: NOT NULL on tutor_courses FKs, status CHECK, time format CHECK, add indexes

This commit is contained in:
2026-04-28 01:19:59 +02:00
parent d6f9d593ed
commit 24acc54ceb
2 changed files with 17 additions and 7 deletions

View File

@@ -12,8 +12,8 @@ CREATE TABLE tutors (
);
CREATE TABLE tutor_courses (
tutor_id INTEGER REFERENCES tutors(id),
course_id INTEGER REFERENCES courses(id),
tutor_id INTEGER NOT NULL REFERENCES tutors(id),
course_id INTEGER NOT NULL REFERENCES courses(id),
PRIMARY KEY (tutor_id, course_id)
);
@@ -42,9 +42,9 @@ CREATE TABLE slots (
session_id INTEGER NOT NULL REFERENCES sessions(id),
room_id INTEGER REFERENCES rooms(id),
tutor_id INTEGER NOT NULL REFERENCES tutors(id),
start_time TEXT NOT NULL,
end_time TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'closed',
start_time TEXT NOT NULL CHECK (start_time GLOB '??:??'),
end_time TEXT NOT NULL CHECK (end_time GLOB '??:??'),
status TEXT NOT NULL DEFAULT 'closed' CHECK (status IN ('closed','open','locked')),
code TEXT UNIQUE
);
@@ -67,3 +67,13 @@ CREATE TABLE notes (
updated_at TEXT NOT NULL CHECK (updated_at GLOB '????-??-??T??:??:??*'),
UNIQUE(slot_id, student_id, tutor_id)
);
-- Indexes on high-frequency FK columns (SQLite does not auto-index FKs)
CREATE INDEX idx_students_course ON students(course_id);
CREATE INDEX idx_sessions_course ON sessions(course_id);
CREATE INDEX idx_slots_session ON slots(session_id);
CREATE INDEX idx_slots_tutor ON slots(tutor_id);
CREATE INDEX idx_attendances_slot ON attendances(slot_id);
CREATE INDEX idx_attendances_student ON attendances(student_id);
CREATE INDEX idx_notes_slot ON notes(slot_id);
CREATE INDEX idx_notes_student ON notes(student_id);

View File

@@ -2,7 +2,7 @@ use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
pub async fn init() -> Result<SqlitePool, sqlx::Error> {
let url = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "sqlite:attendance.db".into());
.unwrap_or_else(|_| "sqlite:/data/attendance.db".into());
let pool = SqlitePoolOptions::new()
.after_connect(|conn, _| Box::pin(async move {
sqlx::query("PRAGMA foreign_keys = ON")
@@ -20,7 +20,7 @@ mod tests {
// NOTE: #[sqlx::test] injects its own pool, bypassing after_connect.
// We test FK enforcement behaviorally: insert a row with a bad FK and assert it fails.
// after_connect is manually invoked in the test setup below.
// The PRAGMA is manually issued at the top of this test body.
#[sqlx::test(migrations = "./migrations")]
async fn foreign_keys_enforced(pool: SqlitePool) {
// Enable FK for this test connection (mirrors what after_connect does in production)