Platform review round 2: audit logging migration, nav unification, DB indexes, and UI polish

- Migrate ~41 inline audit log calls to shared logAudit() utility across all routers
- Add transaction-aware prisma parameter to logAudit() for atomic operations
- Unify jury/mentor/observer navigation into shared RoleNav component
- Add composite DB indexes (Evaluation, GracePeriod, AuditLog) for query performance
- Fix profile page: consolidate dual save buttons, proper useEffect initialization
- Enhance auth error page with MOPC branding and navigation
- Improve observer dashboard with prominent read-only badge
- Fix DI-3: fetch projects before bulk status update for accurate notifications
- Remove unused aiBoost field from smart-assignment scoring
- Add shared image-upload utility and structured logger module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 21:09:06 +01:00
parent 8d0979e649
commit 002a9dbfc3
34 changed files with 1688 additions and 1782 deletions

View File

@@ -250,6 +250,7 @@ model User {
// Award overrides
awardEligibilityOverrides AwardEligibility[] @relation("AwardEligibilityOverriddenBy")
awardWinnerOverrides SpecialAward[] @relation("AwardOverriddenBy")
// In-app notifications
notifications InAppNotification[] @relation("UserNotifications")
@@ -565,7 +566,9 @@ model Evaluation {
binaryDecision Boolean? // Yes/No for semi-finalist
feedbackText String? @db.Text
// Versioning
// Versioning (currently unused - evaluations are updated in-place.
// TODO: Implement proper versioning by creating new rows on re-submission
// if version history is needed for audit purposes)
version Int @default(1)
// Timestamps
@@ -580,6 +583,7 @@ model Evaluation {
@@index([status])
@@index([submittedAt])
@@index([formId])
@@index([status, formId])
}
// =============================================================================
@@ -608,6 +612,7 @@ model GracePeriod {
@@index([extendedUntil])
@@index([grantedById])
@@index([projectId])
@@index([roundId, userId, extendedUntil])
}
// =============================================================================
@@ -659,6 +664,7 @@ model AuditLog {
@@index([action])
@@index([entityType, entityId])
@@index([timestamp])
@@index([entityType, entityId, timestamp])
}
// =============================================================================
@@ -1211,7 +1217,7 @@ model SpecialAward {
// Winner
winnerProjectId String?
winnerOverridden Boolean @default(false)
winnerOverriddenBy String?
winnerOverriddenBy String? // FK to User who overrode the winner
sortOrder Int @default(0)
@@ -1221,6 +1227,7 @@ model SpecialAward {
// Relations
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
winnerProject Project? @relation("AwardWinner", fields: [winnerProjectId], references: [id], onDelete: SetNull)
overriddenByUser User? @relation("AwardOverriddenBy", fields: [winnerOverriddenBy], references: [id], onDelete: SetNull)
eligibilities AwardEligibility[]
jurors AwardJuror[]
votes AwardVote[]