Add jury assignment transfer, cap redistribution, and learning hub overhaul
All checks were successful
Build and Push Docker Image / build (push) Successful in 12m19s

- Add getTransferCandidates/transferAssignments procedures for targeted
  assignment moves between jurors with TOCTOU guards and audit logging
- Add getOverCapPreview/redistributeOverCap for auto-redistributing
  assignments when a juror's cap is lowered below their current load
- Add TransferAssignmentsDialog (2-step: select projects, pick destinations)
- Extend InlineMemberCap with over-cap detection and redistribute banner
- Extend getReassignmentHistory to show ASSIGNMENT_TRANSFER and CAP_REDISTRIBUTE events
- Learning hub: replace ResourceType/CohortLevel enums with accessJson JSONB,
  add coverImageKey, resource detail pages for jury/mentor, shared renderer
- Migration: 20260221200000_learning_hub_overhaul

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 18:50:29 +01:00
parent f42b452899
commit ee2f10e080
16 changed files with 2643 additions and 945 deletions

View File

@@ -0,0 +1,16 @@
-- Learning Hub Overhaul: Remove ResourceType/CohortLevel enums, add accessJson + coverImageKey
-- Drop columns that reference the enums
ALTER TABLE "LearningResource" DROP COLUMN "resourceType";
ALTER TABLE "LearningResource" DROP COLUMN "cohortLevel";
-- Drop the cohortLevel index
DROP INDEX IF EXISTS "LearningResource_cohortLevel_idx";
-- Add new columns
ALTER TABLE "LearningResource" ADD COLUMN "accessJson" JSONB;
ALTER TABLE "LearningResource" ADD COLUMN "coverImageKey" TEXT;
-- Drop the enum types
DROP TYPE IF EXISTS "ResourceType";
DROP TYPE IF EXISTS "CohortLevel";

View File

@@ -115,19 +115,6 @@ enum NotificationChannel {
NONE
}
enum ResourceType {
PDF
VIDEO
DOCUMENT
LINK
OTHER
}
enum CohortLevel {
ALL
SEMIFINALIST
FINALIST
}
enum PartnerVisibility {
ADMIN_ONLY
@@ -1010,13 +997,12 @@ model NotificationEmailSetting {
// =============================================================================
model LearningResource {
id String @id @default(cuid())
id String @id @default(cuid())
programId String? // null = global resource
title String
description String? @db.Text
contentJson Json? @db.JsonB // BlockNote document structure
resourceType ResourceType
cohortLevel CohortLevel @default(ALL)
description String? @db.Text
contentJson Json? @db.JsonB // BlockNote document structure
accessJson Json? @db.JsonB // Fine-grained access rules
// File storage (for uploaded resources)
fileName String?
@@ -1025,6 +1011,9 @@ model LearningResource {
bucket String?
objectKey String?
// Cover image (stored in MinIO)
coverImageKey String?
// External link
externalUrl String?
@@ -1041,7 +1030,6 @@ model LearningResource {
accessLogs ResourceAccess[]
@@index([programId])
@@index([cohortLevel])
@@index([isPublished])
@@index([sortOrder])
}