docs(phase5c): enrollment communications documentation + Google Workspace runbook
- PHASE5C_ENROLLMENT_COMMUNICATIONS.md: the full design doc. - RUNBOOK_GOOGLE_WORKSPACE_EMAIL.md: every REQUIRES GOOGLE WORKSPACE ADMIN ACTION step (mailbox, service account, domain-wide delegation scoped to gmail.send only, SPF/DKIM/DMARC), environment variables, testing procedure, production secret handling, rotation, revocation, troubleshooting, quotas. - RUNBOOK_STUDENT_ACTIVATION.md: day-to-day operation of the pipeline from /admin. - WEBSITE_ENROLLMENT_INTEGRATION.md: explicit website-vs-RootNode responsibility boundary, the new contact_email field, and closes the 'RootNode doesn't send activation email yet' known limitation this doc previously documented. - RUNBOOK_SELF_PACED_ENROLLMENT.md, RUNBOOK_STUDENT_ACCOUNT_LIFECYCLE.md: point at the new automatic-email behavior and the Resend activation control. - REMOTE_AND_SELF_PACED_ARCHITECTURE.md, ENGINEERING_SOP.md: close the enrollment- communication gap; new ENGINEERING_SOP §16. - PRODUCTION_VALIDATION_CHECKLIST.md, README.md, platform/README.md: cross-references and a Phase 5C production-validation section.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# Runbook: Student Activation Pipeline
|
||||
|
||||
Covers the day-to-day operation of the enrollment → activation → login pipeline from `/admin`.
|
||||
See `docs/PHASE5C_ENROLLMENT_COMMUNICATIONS.md` for the underlying design and
|
||||
`docs/RUNBOOK_GOOGLE_WORKSPACE_EMAIL.md` for the email delivery mechanism itself.
|
||||
|
||||
## What happens automatically
|
||||
|
||||
Every time a student account gains a new enrollment — whether the website's checkout triggered
|
||||
it (`POST /api/integrations/enrollments`) or an instructor enrolled them manually from
|
||||
`/admin` → Programs — RootNode decides and sends the right email on its own:
|
||||
|
||||
- **Never activated before** → an activation email, with a one-time link to set their password.
|
||||
- **Already has real credentials** → an enrollment confirmation email pointing them back to
|
||||
sign in — no link/token involved.
|
||||
|
||||
Nothing needs to be triggered by hand for the normal case. The controls below are for when the
|
||||
normal case didn't work.
|
||||
|
||||
## Checking delivery status
|
||||
|
||||
**Per student**: Students → \[student\] → the "Notifications" card shows every notification ever
|
||||
sent to (or attempted for) that student, with type/status/attempt count. `sent` means it
|
||||
actually reached the provider successfully; `failed` means it gave up (see below); `queued`/
|
||||
`sending` means it's still in flight — check back in a few seconds, delivery happens through a
|
||||
background worker, not the same request that triggered it.
|
||||
|
||||
**Everywhere**: `/admin` → Notifications (owner/admin only) — the same information across every
|
||||
student, most recent first.
|
||||
|
||||
## If a student never got their activation email
|
||||
|
||||
1. Check Students → \[student\] → Notifications. If it shows `failed`, note the error — a
|
||||
`no_recipient_address` failure means the student truly has no email or contact address on
|
||||
file and can only be activated by an instructor manually relaying a link (see below); other
|
||||
error codes usually mean a delivery-infrastructure issue worth checking
|
||||
`docs/RUNBOOK_GOOGLE_WORKSPACE_EMAIL.md`'s troubleshooting table for.
|
||||
2. Students → \[student\] → Credentials → **Resend activation**. This invalidates whatever link
|
||||
was outstanding and sends a fresh one — safe to click as many times as needed; only the most
|
||||
recent link is ever valid, so there's never a "which link do I use" confusion for the student.
|
||||
3. If the student genuinely has no deliverable address at all (a younger student with a
|
||||
login-only account and no guardian contact email on file), convert/create them without email
|
||||
in the first place (see `docs/RUNBOOK_STUDENT_ACCOUNT_LIFECYCLE.md`) and relay the one-time
|
||||
activation link shown in the admin UI directly (print it, read it aloud) — this manual path
|
||||
still works exactly as it did before Phase 5C added automatic email.
|
||||
|
||||
## If a student says they didn't get an enrollment confirmation
|
||||
|
||||
Check Students → \[student\] → Notifications for the `enrollment_confirmation` row. If it's
|
||||
`sent`, the email genuinely went out — check their spam folder, or confirm the address on file
|
||||
(Students → \[student\]) is actually correct. If none exists for a given enrollment,
|
||||
Programs → \[program\] → Enrollments → find the enrollment → (student detail page also works)
|
||||
and use **Send enrollment confirmation** to trigger one explicitly.
|
||||
|
||||
## Password reset
|
||||
|
||||
Students should use "Forgot password" on the login screen themselves wherever possible — it's
|
||||
delivered the same way as everything else here and the flow is self-service end to end.
|
||||
|
||||
If a student can't complete self-service reset (e.g. they no longer have access to the email a
|
||||
guardian originally provided and it needs an instructor to re-trigger with a corrected address),
|
||||
Students → \[student\] → Credentials → **Send password reset** issues a fresh reset link and
|
||||
revokes all of that student's existing sessions immediately. In production, the instructor
|
||||
never sees the token itself — the response is a confirmation that an email was queued, not the
|
||||
link. If automatic delivery still can't reach the student, use `docs/RUNBOOK_STUDENT_ACCOUNT_
|
||||
LIFECYCLE.md`'s manual-relay procedure, which is unaffected by any of this.
|
||||
|
||||
## What "resend" does NOT do
|
||||
|
||||
Resending activation does not touch the student's enrollment status, progress, achievements, or
|
||||
attempt history — it only affects the credential/token side of their account. It's always safe.
|
||||
Reference in New Issue
Block a user