diff --git a/docs/superpowers/specs/2026-06-01-mentorship-comms-and-welcome-email-design.md b/docs/superpowers/specs/2026-06-01-mentorship-comms-and-welcome-email-design.md new file mode 100644 index 0000000..2ead627 --- /dev/null +++ b/docs/superpowers/specs/2026-06-01-mentorship-comms-and-welcome-email-design.md @@ -0,0 +1,122 @@ +# Mentorship Communications & Welcome/Reminder Email — Design + +- **Date:** 2026-06-01 +- **Status:** Approved (pending spec review) +- **Author:** Matt + Claude +- **Topic:** Make mentor↔team contact effortless and add a re-sendable, instructional "welcome/reminder" email for mentoring rounds. + +## Context + +MOPC already has a working mentorship feature: + +- **Two-way in-app messaging** exists (`MentorMessage` model; `WorkspaceChat` + `MentorChat` components; `trpc.mentor.sendMessage` / `getMessages` and `trpc.applicant.sendMentorMessage` / `getMentorMessages`). Mentors are auto-notified when applicants write. +- **Contact emails are already visible**: mentors see each team member's email as individual `mailto:` links (`src/app/(mentor)/mentor/projects/[id]/page.tsx`); applicants see their mentor's name+email (`src/app/(applicant)/applicant/mentor/page.tsx`) and teammates' emails (`src/app/(applicant)/applicant/team/page.tsx`). +- **Round-open auto emails already fire**: flipping a `MENTORING` round draft→active sends a coalesced *"you've been assigned to N projects"* email to each mentor (`getMentorBulkAssignmentTemplate` / `sendMentorBulkAssignmentEmail`) and a *"meet your mentors"* intro to each team (`getTeamMentorIntroductionTemplate` / `sendTeamMentorIntroductionEmail`). These are one-time, gated by `MentorAssignment.notificationSentAt` and `MentorAssignment.teamIntroducedAt` (`src/server/services/round-engine.ts`). + +Two gaps remain: + +1. There is **no single "email all team members"** affordance for mentors — only per-person `mailto:` links. +2. The round-open emails **don't explain how to use the mentorship features**, and there is **no way to re-send** them later as a reminder. + +## Goals + +- A mentor can email their whole team in one click (opens their mail client, all members in `To:`). +- The round-open assignment emails are **upgraded in place** to include (a) the relevant contact emails and (b) how-to-use-the-mentorship-features instructions. +- An admin can **re-send** that same email on demand (a "welcome/reminder" blast) to all mentors + teams in a mentoring round, with an optional custom note. +- The admin can **preview** the exact email (mentor + team versions) before sending. + +## Non-goals + +- No new in-app messaging surfaces (the chat already exists). +- No new email-provider infrastructure (reuse `src/lib/email.ts` wrapper, helpers, throttling, `NotificationLog`). +- No mentors-only / teams-only targeting toggle for v1 — the reminder sends to **both** audiences. (Can be added later if needed.) + +## Feature 1 — Mentor "Email all team members" button + +- **Location:** `src/app/(mentor)/mentor/projects/[id]/page.tsx`, in the existing Team Members card, alongside the per-member `mailto:` links. +- **Behavior:** builds `mailto:?subject=...` with **all active team members in `To:`** (per decision), subject pre-filled `MOPC Mentorship — {project title}`. Clicking opens the mentor's default mail app. +- **Edge cases:** filter out blank/missing emails defensively (schema makes `User.email` required+non-null, but be safe); hide the button when the team has zero emailable members. +- **Scope:** pure client-side; no backend changes. + +## Feature 2 — Unified mentorship welcome/reminder email + +### Decision: upgrade in place, don't duplicate + +Rather than send a second email on round-open, the **existing** two templates are enhanced so they carry the instructions + contact emails. The same template code is reused by both trigger paths below. One email per audience; one source of truth. + +### Content — Mentor version (coalesced per mentor, across their projects in the round) + +- Greeting by mentor name. +- Optional custom note (rendered in an info box near the top) — only present on the manual reminder path. +- For **each** assigned project: project title (linked) + the **team members listed with name + email**. +- "How to mentor on MOPC" instructions block: where the workspace chat lives, file sharing, the mentor dashboard. +- CTA → Mentor Dashboard. + +### Content — Team version (per project) + +- Greeting by recipient name. +- Optional custom note (info box) — manual path only. +- The assigned **mentor(s) listed with name + email**. +- The team's **own members listed with email** (per decision: include teammates too). +- "How to work with your mentor" instructions block: where the in-app chat is, how to reach the mentor, what to expect. +- CTA → mentoring page. + +Both reuse `getEmailWrapper()` and existing helpers (`sectionTitle`, `paragraph`, `ctaButton`, `infoBox`, `escapeHtml`) for consistent branding. + +### Trigger path A — auto on round-open (existing flow, upgraded content) + +- `src/server/services/round-engine.ts` draft→active flow keeps its one-time semantics (`notificationSentAt` / `teamIntroducedAt` gating) and coalescing. +- It now passes the additional data the upgraded templates need: team-member name+email for the mentor email, and mentor name+email + teammate emails for the team email. +- No custom note on this path. + +### Trigger path B — manual reminder button (admin, on demand) + +- New `adminProcedure`: `mentor.sendMentorshipWelcome({ roundId, customNote?: string })`. + - Resolves **all current** active assignments for the round (`droppedAt: null`) → groups by mentor → sends mentor emails; resolves all projects with assignments → sends team emails to all members. + - **Ignores** `notificationSentAt` / `teamIntroducedAt` (deliberate re-send). Does **not** mutate those flags. + - Throttled + fire-and-forget like existing bulk sends; writes `NotificationLog` rows + a `DecisionAuditLog`/audit entry. + - Returns counts: `{ mentorCount, teamMemberCount, teamCount }` for the success toast. + +### Preview + +- New query: `mentor.previewMentorshipWelcome({ roundId, customNote?: string })` → `{ mentor: { subject, html }, team: { subject, html } }`. + - Calls the **same** template functions used by the real send. + - Picks a representative recipient: first mentor with assignments + first project/team in the round. If the round has none yet, returns clearly-labeled sample-data output so the layout is still previewable. +- Rendered in the send dialog inside a sandboxed `