MOPC-App/docs/claude-architecture-redesign/08-round-mentoring.md

23 KiB
Raw Permalink Blame History

Round: Mentoring (Finalist Collaboration Layer)

1. Purpose & Position in Flow

The MENTORING round is not a judging stage — it is a collaboration layer that activates between Jury 2 finalist selection and the Live Finals. It provides finalist teams who requested mentoring with a private workspace to refine their submissions with guidance from an assigned mentor.

Aspect Detail
Position Round 6 (after Jury 2, before Live Finals)
Participants Finalist teams + assigned mentors
Duration Configurable (typically 2-4 weeks)
Output Better-prepared finalist submissions; some mentoring files promoted to official submissions

Who Gets Mentoring

  • Only projects that have Project.wantsMentorship = true AND have advanced to finalist status (ProjectRoundState PASSED in the Jury 2 round)
  • Admin can override: assign mentoring to projects that didn't request it, or skip projects that did

2. Data Model

Round Record

Round {
  id: "round-mentoring"
  competitionId: "comp-2026"
  name: "Finalist Mentoring"
  roundType: MENTORING
  status: ROUND_DRAFT → ROUND_ACTIVE → ROUND_CLOSED
  sortOrder: 5
  windowOpenAt: "2026-06-01"       // Mentoring period start
  windowCloseAt: "2026-06-30"      // Mentoring period end
  juryGroupId: null                 // No jury for mentoring
  submissionWindowId: null          // Mentoring doesn't collect formal submissions
  configJson: { ...MentoringConfig }
}

MentoringConfig

type MentoringConfig = {
  // Who gets mentoring
  eligibility: "all_advancing" | "requested_only"
  //   all_advancing: Every finalist gets a mentor
  //   requested_only: Only projects with wantsMentorship=true

  // Workspace features
  chatEnabled: boolean              // Bidirectional messaging (default: true)
  fileUploadEnabled: boolean        // Mentor + team can upload files (default: true)
  fileCommentsEnabled: boolean      // Threaded comments on files (default: true)
  filePromotionEnabled: boolean     // Promote workspace file to official submission (default: true)

  // Promotion target
  promotionTargetWindowId: string | null
  //   Which SubmissionWindow promoted files go to
  //   Usually the most recent window (Round 2 docs)
  //   If null, promotion creates files without a window (admin must assign)

  // Auto-assignment
  autoAssignMentors: boolean        // Use AI/algorithm to assign (default: false)
  maxProjectsPerMentor: number      // Mentor workload cap (default: 3)

  // Notifications
  notifyTeamsOnOpen: boolean        // Email teams when mentoring opens (default: true)
  notifyMentorsOnAssign: boolean    // Email mentors when assigned (default: true)
  reminderBeforeClose: number[]     // Days before close to remind (default: [7, 3, 1])
}
Model Purpose
MentorAssignment Links mentor to project (existing, enhanced)
MentorMessage Chat messages between mentor and team (existing)
MentorNote Mentor's private notes (existing)
MentorFile NEW — Files uploaded in workspace
MentorFileComment NEW — Threaded comments on files
ProjectFile Target for file promotion
SubmissionFileRequirement Requirement slot that promoted file fills

3. Mentor Assignment

3.1 Assignment Methods

Method Description
MANUAL Admin picks mentor for each project
AI_SUGGESTED AI recommends matches, admin approves
AI_AUTO AI auto-assigns, admin can override
ALGORITHM Round-robin or expertise-matching algorithm

3.2 Assignment Criteria

The existing mentor-matching.ts service evaluates:

  • Expertise overlap — mentor's tags vs project's tags/category
  • Country/region diversity — avoid same-country bias
  • Workload balance — distribute evenly across mentors
  • Language — match if language preferences exist

3.3 Assignment Flow

1. MENTORING round opens (status → ROUND_ACTIVE)
2. System identifies eligible projects:
   - All finalists (if eligibility = "all_advancing")
   - Only finalists with wantsMentorship (if "requested_only")
3. For each eligible project without a mentor:
   a. If autoAssignMentors: Run AI/algorithm assignment
   b. Else: Flag as "needs mentor" in admin dashboard
4. Admin reviews assignments, can:
   - Accept suggestions
   - Reassign mentors
   - Skip projects (no mentoring needed)
5. Assigned mentors receive email notification
6. Workspace becomes active for mentor+team

3.4 Workspace Activation

When a mentor is assigned and the MENTORING round is ROUND_ACTIVE:

// MentorAssignment is updated:
{
  workspaceEnabled: true,
  workspaceOpenAt: round.windowOpenAt,
  workspaceCloseAt: round.windowCloseAt,
}

The workspace is accessible from:

  • Mentor dashboard → "My Projects" → select project → Workspace tab
  • Applicant dashboard → "Mentor" section → Workspace tab
  • Admin → can view any workspace at any time

4. Workspace Features

4.1 Messaging (Chat)

Bidirectional chat between mentor and team members:

┌────────────────────────────────────────────────┐
│ Mentor Workspace — OceanClean AI               │
│ ──────────────────────────────────────────── │
│ [💬 Chat] [📁 Files] [📋 Milestones]          │
│                                                │
│ ┌────────────────────────────────────────┐     │
│ │ Dr. Martin (Mentor)       Apr 5, 10:30│     │
│ │ Welcome! I've reviewed your business   │     │
│ │ plan. Let's work on the financial      │     │
│ │ projections section.                   │     │
│ │                                        │     │
│ │ Sarah (Team Lead)         Apr 5, 14:15│     │
│ │ Thank you! We've uploaded a revised    │     │
│ │ version. See the Files tab.            │     │
│ │                                        │     │
│ │ Dr. Martin (Mentor)       Apr 6, 09:00│     │
│ │ Great improvement! I've left comments  │     │
│ │ on the file. One more round should do. │     │
│ └────────────────────────────────────────┘     │
│                                                │
│ [Type a message...              ] [Send]       │
└────────────────────────────────────────────────┘

Implementation:

  • Uses existing MentorMessage model
  • Messages auto-marked as read when the chat is viewed
  • Real-time updates via polling (every 10s) or WebSocket if available
  • Both mentor and any team member can send messages

4.2 File Upload & Comments

The core new feature: a private file space with threaded discussion.

┌────────────────────────────────────────────────┐
│ [💬 Chat] [📁 Files] [📋 Milestones]          │
│                                                │
│ ┌── Workspace Files ───────────────────────┐   │
│ │                                          │   │
│ │ 📄 Business Plan v2.pdf                  │   │
│ │    Uploaded by Sarah (Team) · Apr 5      │   │
│ │    💬 3 comments                         │   │
│ │    [Download] [Comment] [Promote →]      │   │
│ │                                          │   │
│ │ 📄 Financial Model.xlsx                  │   │
│ │    Uploaded by Dr. Martin (Mentor) · Apr 6│  │
│ │    💬 1 comment                          │   │
│ │    [Download] [Comment]                  │   │
│ │                                          │   │
│ │ 📄 Pitch Deck Draft.pptx                │   │
│ │    Uploaded by Sarah (Team) · Apr 8      │   │
│ │    ✅ Promoted → "Presentation" slot     │   │
│ │    [Download] [View Comments]            │   │
│ │                                          │   │
│ └──────────────────────────────────────────┘   │
│                                                │
│ [📤 Upload File]                               │
└────────────────────────────────────────────────┘

File Upload Flow:

  1. User (mentor or team member) clicks "Upload File"
  2. Client calls mentor.getWorkspaceUploadUrl(mentorAssignmentId, fileName, mimeType)
  3. Server generates MinIO pre-signed PUT URL
  4. Client uploads directly to MinIO
  5. Client calls mentor.saveWorkspaceFile(mentorAssignmentId, fileName, mimeType, size, bucket, objectKey, description)
  6. Server creates MentorFile record

File Comments:

┌── Comments on: Business Plan v2.pdf ──────────┐
│                                                │
│ Dr. Martin (Mentor) · Apr 5, 16:00            │
│ Section 3.2 needs stronger market analysis.    │
│ Consider adding competitor comparisons.        │
│   └─ Sarah (Team) · Apr 5, 18:30             │
│      Good point — we'll add a competitive      │
│      landscape section. See updated version.   │
│                                                │
│ Dr. Martin (Mentor) · Apr 6, 10:00            │
│ Revenue projections look much better now.      │
│ Ready for promotion to official submission?    │
│   └─ Sarah (Team) · Apr 6, 11:00             │
│      Yes, let's promote it!                    │
│                                                │
│ [Add comment...                    ] [Post]    │
└────────────────────────────────────────────────┘

Implementation:

  • MentorFileComment with parentCommentId for threading
  • Both mentor and team members can comment
  • Admin can view all comments
  • Comments are timestamped and attributed

4.3 File Promotion to Official Submission

The key feature: converting a private mentoring file into an official submission document.

Promotion Flow:

1. Team member (or admin) clicks "Promote →" on a workspace file
2. Dialog appears:
   ┌────────────────────────────────────────┐
   │ Promote File to Official Submission    │
   │                                        │
   │ File: Business Plan v2.pdf             │
   │                                        │
   │ Target submission window:              │
   │ [Round 2 Docs ▾]                       │
   │                                        │
   │ Replaces requirement:                  │
   │ [Business Plan ▾]                      │
   │                                        │
   │ ⚠ This will replace the current       │
   │ "Business Plan" file for this project. │
   │                                        │
   │ [Cancel]  [Promote & Replace]          │
   └────────────────────────────────────────┘

3. On confirmation:
   a. System creates a new ProjectFile record:
      - projectId: project's ID
      - submissionWindowId: selected window
      - requirementId: selected requirement slot
      - fileName, mimeType, size: copied from MentorFile
      - bucket, objectKey: SAME as MentorFile (no file duplication)
      - version: incremented from previous file in slot
   b. Previous file in that slot gets `replacedById` set to new file
   c. MentorFile updated:
      - isPromoted: true
      - promotedToFileId: new ProjectFile ID
      - promotedAt: now
      - promotedByUserId: actor ID
   d. Audit log entry created:
      - action: "MENTOR_FILE_PROMOTED"
      - details: { mentorFileId, projectFileId, submissionWindowId, requirementId, replacedFileId }

Key Rules:

  • Only files in active mentoring workspaces can be promoted
  • Promotion replaces the existing file for that requirement slot (per user's decision)
  • The MinIO object is not duplicated — both MentorFile and ProjectFile point to the same objectKey
  • Once promoted, the MentorFile shows a "Promoted" badge and the promote button is disabled
  • Admin can un-promote (revert) if needed, which deletes the ProjectFile and resets MentorFile flags
  • Promotion is audited with full provenance chain

Who Can Promote:

  • Team lead (Project.submittedByUserId or TeamMember.role = LEAD)
  • Admin (always)
  • Mentor (only if MentoringConfig.mentorCanPromote is true — default false for safety)

4.4 Privacy Model

Visibility Matrix:
┌──────────────────┬────────┬──────────┬───────┬──────┐
│ Content          │ Mentor │ Team     │ Admin │ Jury │
├──────────────────┼────────┼──────────┼───────┼──────┤
│ Chat messages    │ ✅     │ ✅       │ ✅    │ ❌   │
│ Workspace files  │ ✅     │ ✅       │ ✅    │ ❌   │
│ File comments    │ ✅     │ ✅       │ ✅    │ ❌   │
│ Mentor notes     │ ✅     │ ❌       │ ✅*   │ ❌   │
│ Promoted files   │ ✅     │ ✅       │ ✅    │ ✅** │
└──────────────────┴────────┴──────────┴───────┴──────┘

* Only if MentorNote.isVisibleToAdmin = true
** Promoted files become official submissions visible to jury

5. Mentor Dashboard

┌──────────────────────────────────────────────────────────┐
│ Mentor Dashboard                                         │
│ ─────────────────────────────────────────────────────── │
│                                                          │
│ Mentoring Period: June 1  June 30                       │
│ ⏱ 18 days remaining                                     │
│                                                          │
│ ┌─────────┐ ┌─────────┐ ┌──────────┐                   │
│ │ 3       │ │ 12      │ │ 5        │                    │
│ │ Teams   │ │ Messages│ │ Files    │                    │
│ └─────────┘ └─────────┘ └──────────┘                    │
│                                                          │
│ My Assigned Teams                                        │
│ ┌────────────────────────────────────────────────────┐  │
│ │ OceanClean AI (Startup)                            │  │
│ │ 💬 2 unread messages · 📁 3 files · Last: Apr 6    │  │
│ │ [Open Workspace]                                   │  │
│ ├────────────────────────────────────────────────────┤  │
│ │ Blue Carbon Hub (Concept)                          │  │
│ │ 💬 0 unread · 📁 1 file · Last: Apr 4              │  │
│ │ [Open Workspace]                                   │  │
│ ├────────────────────────────────────────────────────┤  │
│ │ SeaWatch Monitor (Startup)                         │  │
│ │ ⚠ No activity yet                                  │  │
│ │ [Open Workspace]                                   │  │
│ └────────────────────────────────────────────────────┘  │
│                                                          │
│ Milestones                                               │
│ ┌────────────────────────────────────────────────────┐  │
│ │ ☑ Initial review (3/3 teams)                       │  │
│ │ ☐ Business plan feedback (1/3 teams)               │  │
│ │ ☐ Pitch deck review (0/3 teams)                    │  │
│ └────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────┘

6. Applicant Experience

On the applicant dashboard, a "Mentoring" section appears when mentoring is active:

┌────────────────────────────────────────────────┐
│ Your Mentor: Dr. Martin Duval                  │
│ Expertise: Marine Biology, Sustainability       │
│                                                │
│ Mentoring Period: June 1  June 30             │
│ ⏱ 18 days remaining                           │
│                                                │
│ [💬 Messages (2 unread)]                       │
│ [📁 Workspace Files (3)]                       │
│ [📋 Milestones]                                │
└────────────────────────────────────────────────┘

Clicking "Workspace Files" opens the same workspace view as the mentor (with appropriate permissions).


7. Admin Experience

Admin can:

  • Assign/reassign mentors via bulk or individual assignment
  • View any workspace (read-only or with full edit access)
  • Promote files on behalf of teams
  • Track activity — dashboard showing mentor engagement:
    • Messages sent per mentor
    • Files uploaded
    • Milestones completed
    • Last activity timestamp
  • Extend/close mentoring window per team or globally
  • Export workspace data for audit purposes

8. API — New and Modified Procedures

New Procedures (mentor-workspace router)

Procedure Auth Purpose
mentorWorkspace.getUploadUrl Mentor or Team Get MinIO pre-signed URL for workspace upload
mentorWorkspace.saveFile Mentor or Team Create MentorFile record after upload
mentorWorkspace.listFiles Mentor, Team, Admin List workspace files with comment counts
mentorWorkspace.deleteFile Uploader or Admin Delete workspace file
mentorWorkspace.getFileDownloadUrl Mentor, Team, Admin Get MinIO pre-signed URL for download
mentorWorkspace.addComment Mentor, Team, Admin Add comment to file (with optional parentCommentId)
mentorWorkspace.listComments Mentor, Team, Admin Get threaded comments for a file
mentorWorkspace.deleteComment Author or Admin Delete a comment
mentorWorkspace.promoteFile Team Lead or Admin Promote workspace file to official submission
mentorWorkspace.unpromoteFile Admin only Revert a promotion
mentorWorkspace.getWorkspaceStatus Any participant Get workspace summary (file count, message count, etc.)

Modified Existing Procedures

Procedure Change
mentor.getMyProjects Include workspace status (file count, unread messages)
mentor.getProjectDetail Include MentorFile[] with comment counts
applicant.getMyDashboard Include mentor workspace summary if mentoring active
file.listByProjectForRound Promoted files visible to jury (via ProjectFile record)

9. Service: mentor-workspace.ts

Key Functions

// Upload handling
async function getWorkspaceUploadUrl(
  mentorAssignmentId: string,
  fileName: string,
  mimeType: string,
  actorId: string,
  prisma: PrismaClient
): Promise<{ uploadUrl: string; objectKey: string }>

// Save file metadata after upload
async function saveWorkspaceFile(
  mentorAssignmentId: string,
  uploadedByUserId: string,
  file: { fileName, mimeType, size, bucket, objectKey },
  description: string | null,
  prisma: PrismaClient
): Promise<MentorFile>

// Promote file to official submission
async function promoteFileToSubmission(
  mentorFileId: string,
  submissionWindowId: string,
  requirementId: string | null,
  actorId: string,
  prisma: PrismaClient
): Promise<{ mentorFile: MentorFile; projectFile: ProjectFile }>
// Steps:
//   1. Validate mentorFile exists, is not already promoted, workspace is active
//   2. If requirementId: find existing ProjectFile for that requirement, set replacedById
//   3. Create new ProjectFile (reusing same bucket/objectKey — no MinIO duplication)
//   4. Update MentorFile: isPromoted=true, promotedToFileId, promotedAt, promotedByUserId
//   5. Audit log with full provenance

// Revert promotion
async function unpromoteFile(
  mentorFileId: string,
  actorId: string,
  prisma: PrismaClient
): Promise<void>
// Steps:
//   1. Find the ProjectFile created by promotion
//   2. If it replaced a previous file, restore that file's replacedById=null
//   3. Delete the promoted ProjectFile
//   4. Reset MentorFile flags
//   5. Audit log

10. Edge Cases

Scenario Handling
Team doesn't want mentoring but admin assigns anyway Assignment created; team sees mentor in dashboard
Mentor goes inactive during period Admin can reassign; previous workspace preserved
File promoted then mentor period closes Promoted file remains as official submission
Team tries to promote file for a requirement that doesn't exist Error — must select valid requirement or leave requirementId null
Two files promoted to the same requirement slot Second promotion replaces first (versioning)
Mentoring file is larger than requirement maxSizeMB Warning shown but promotion allowed (admin override implicit)
Workspace closed but team needs one more upload Admin can extend via round window or grant grace
Promoted file deleted from workspace ProjectFile remains (separate record); audit shows provenance