Add Phase 7: grade history and session-plan item linking
- New tables: lesson_plan_item_grade_history (append-only), lesson_session_plan_item - Grading an item updates current_grade_value and creates immutable history record - Grading a not_started item auto-transitions it to in_progress - Linking items to a session also auto-transitions not_started items - Link operation is idempotent — re-linking same items produces no duplicates - Endpoints: POST/GET /lesson-plan-items/:id/grades, GET /lesson-plan-items/:id/grade-history - Endpoints: POST/GET /lesson-sessions/:id/plan-items - 8 new integration tests
This commit is contained in:
19
packages/backend/src/db/migrations/0035_grade_history.sql
Normal file
19
packages/backend/src/db/migrations/0035_grade_history.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- Phase 7: Grade history and session-plan item linking
|
||||
|
||||
CREATE TABLE "lesson_plan_item_grade_history" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"lesson_plan_item_id" uuid NOT NULL REFERENCES "lesson_plan_item"("id"),
|
||||
"grading_scale_id" uuid REFERENCES "grading_scale"("id"),
|
||||
"grade_value" varchar(50) NOT NULL,
|
||||
"graded_by" uuid REFERENCES "user"("id"),
|
||||
"session_id" uuid REFERENCES "lesson_session"("id"),
|
||||
"notes" text,
|
||||
"created_at" timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE "lesson_session_plan_item" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"session_id" uuid NOT NULL REFERENCES "lesson_session"("id"),
|
||||
"lesson_plan_item_id" uuid NOT NULL REFERENCES "lesson_plan_item"("id"),
|
||||
"created_at" timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
@@ -246,6 +246,13 @@
|
||||
"when": 1774940000000,
|
||||
"tag": "0034_blocked_dates",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 35,
|
||||
"version": "7",
|
||||
"when": 1774950000000,
|
||||
"tag": "0035_grade_history",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -218,6 +218,30 @@ export const lessonPlanItems = pgTable('lesson_plan_item', {
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
})
|
||||
|
||||
export const lessonPlanItemGradeHistory = pgTable('lesson_plan_item_grade_history', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
lessonPlanItemId: uuid('lesson_plan_item_id')
|
||||
.notNull()
|
||||
.references(() => lessonPlanItems.id),
|
||||
gradingScaleId: uuid('grading_scale_id').references(() => gradingScales.id),
|
||||
gradeValue: varchar('grade_value', { length: 50 }).notNull(),
|
||||
gradedBy: uuid('graded_by').references(() => users.id),
|
||||
sessionId: uuid('session_id').references(() => lessonSessions.id),
|
||||
notes: text('notes'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
})
|
||||
|
||||
export const lessonSessionPlanItems = pgTable('lesson_session_plan_item', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
sessionId: uuid('session_id')
|
||||
.notNull()
|
||||
.references(() => lessonSessions.id),
|
||||
lessonPlanItemId: uuid('lesson_plan_item_id')
|
||||
.notNull()
|
||||
.references(() => lessonPlanItems.id),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
})
|
||||
|
||||
// --- Type exports ---
|
||||
|
||||
export type Instructor = typeof instructors.$inferSelect
|
||||
@@ -244,3 +268,7 @@ export type LessonPlanSection = typeof lessonPlanSections.$inferSelect
|
||||
export type LessonPlanSectionInsert = typeof lessonPlanSections.$inferInsert
|
||||
export type LessonPlanItem = typeof lessonPlanItems.$inferSelect
|
||||
export type LessonPlanItemInsert = typeof lessonPlanItems.$inferInsert
|
||||
export type LessonPlanItemGradeHistory = typeof lessonPlanItemGradeHistory.$inferSelect
|
||||
export type LessonPlanItemGradeHistoryInsert = typeof lessonPlanItemGradeHistory.$inferInsert
|
||||
export type LessonSessionPlanItem = typeof lessonSessionPlanItems.$inferSelect
|
||||
export type LessonSessionPlanItemInsert = typeof lessonSessionPlanItems.$inferInsert
|
||||
|
||||
Reference in New Issue
Block a user