feat(modules): module topics for student form, admin CRUD with pagination
- db: modules table (name, lessons_count) + entries.module_id (ON DELETE SET NULL), migration + idempotent startup ensure - api: GET /api/modules (public, search + limit/offset, entries_count), POST/PUT/DELETE (admin, audit-logged) - entries: accept/validate module_id on create/update, return module_name, module_id filter - backup/restore: include modules and entries.module_id - student form: required module select, hidden while no modules exist - admin: modules.html + js/modules.js list with pagination, search, create/edit/delete modal - journal: module filter, module select in edit modal, module badge, CSV column
This commit is contained in:
+10
@@ -24,6 +24,13 @@ CREATE TABLE IF NOT EXISTS groups (
|
||||
cover_path VARCHAR(255)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS modules (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(200) NOT NULL UNIQUE,
|
||||
lessons_count INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS students (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(150) NOT NULL UNIQUE,
|
||||
@@ -35,6 +42,7 @@ CREATE TABLE IF NOT EXISTS entries (
|
||||
id SERIAL PRIMARY KEY,
|
||||
student_name VARCHAR(150) NOT NULL,
|
||||
group_id INT NOT NULL REFERENCES groups(id),
|
||||
module_id INT REFERENCES modules(id) ON DELETE SET NULL,
|
||||
description TEXT NOT NULL,
|
||||
description_original TEXT,
|
||||
description_ai TEXT,
|
||||
@@ -52,8 +60,10 @@ ALTER TABLE entries ADD COLUMN IF NOT EXISTS description_ai TEXT;
|
||||
ALTER TABLE entries ADD COLUMN IF NOT EXISTS ai_status VARCHAR(20) NOT NULL DEFAULT 'pending';
|
||||
ALTER TABLE entries ADD COLUMN IF NOT EXISTS ai_checked_at TIMESTAMPTZ;
|
||||
ALTER TABLE entries ADD COLUMN IF NOT EXISTS ai_error TEXT;
|
||||
ALTER TABLE entries ADD COLUMN IF NOT EXISTS module_id INT REFERENCES modules(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_ai_pending ON entries(id) WHERE ai_status = 'pending' AND deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_module_id ON entries(module_id);
|
||||
|
||||
CREATE OR REPLACE FUNCTION notify_entries_changed() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
|
||||
@@ -223,3 +223,13 @@ ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
ALTER TABLE entries ADD COLUMN IF NOT EXISTS photo_original_path VARCHAR(255);
|
||||
ALTER TABLE photo_jobs ADD COLUMN IF NOT EXISTS applied BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS modules (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(200) NOT NULL UNIQUE,
|
||||
lessons_count INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
ALTER TABLE entries ADD COLUMN IF NOT EXISTS module_id INT REFERENCES modules(id) ON DELETE SET NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_module_id ON entries(module_id);
|
||||
|
||||
Reference in New Issue
Block a user