23 KiB
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 = trueAND 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])
}
Related Models
| 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
MentorMessagemodel - 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:
- User (mentor or team member) clicks "Upload File"
- Client calls
mentor.getWorkspaceUploadUrl(mentorAssignmentId, fileName, mimeType) - Server generates MinIO pre-signed PUT URL
- Client uploads directly to MinIO
- Client calls
mentor.saveWorkspaceFile(mentorAssignmentId, fileName, mimeType, size, bucket, objectKey, description) - Server creates
MentorFilerecord
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:
MentorFileCommentwithparentCommentIdfor 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.mentorCanPromoteis 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 |