# 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 ```typescript 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: ```typescript // 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 ```typescript // 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 // 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 // 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 |