01 — Product Overview (CRM Module)
- 1. Purpose
- 2. Business goals
- 3. User goals (top level; per-role detail in 02_User_Personas.md)
- 4. Stakeholders
- 5. Why this exists
- 6. Platform dependencies (backend)
- 7. Success metrics (module)
- 8. Module edge cases
- 9. Module assumptions
- 10. Glossary (module)
StudyLyon CRM — lead capture, follow-up, conversion and admissions pipeline for multi-tenant institutions. Backend is the source of truth (
src/modules/crm/); shared platform context lives in 00-shared/01_Product_Overview.md.
1. Purpose
The CRM module turns school inquiries into enrolled students. It covers the entire inbound funnel:
- Lead capture — name, contact, source (
website | referral | walk_in | phone | campaign | other,lead.schema.ts:15-22) and an optional academic placement (grade/section/academicYear/class). - Nurture — status pipeline (
new → contacted → qualified → converted | closed,lead.schema.ts:7-13), follow-up records with scheduled/completed timestamps, and staff assignment (assignedTo,lead.schema.ts:79-80). - Conversion — promote a qualified lead to a User + Student record in one
action, recording
convertedAt/convertedToStudentId(crm.service.ts:118-176). - Campaigns — marketing campaigns that generate leads, with status, type,
dates, and metrics (
campaign.schema.ts:23-56). - Admissions — the formal application pipeline (
draft → submitted → documents_pending → interview_scheduled → under_review → approved | rejected | waitlisted → converted,admission.schema.ts:7-17) with document uploads, interviews, approver-tracked workflow history, and conversion to Student (admission.service.ts:39-285).
2. Business goals
| Goal | Measure |
|---|---|
| No inquiry lost | Every walk-in/phone/website lead lands in the pipeline with a follow-up date |
| Fast conversion | Lead → Student conversion one action after qualification (grade/year/class set) |
| Pipeline visibility | Funnel stats per status via admissions analytics; leads filterable by status |
| Accountable follow-ups | Every follow-up has scheduledAt, optional completedAt, and createdBy |
| Controlled admissions | Decisions only from decidable statuses; closed applications immutable (admission.service.ts:257-269) |
3. User goals (top level; per-role detail in 02_User_Personas.md)
- Receptionist: capture a walk-in/phone lead in under a minute; never lose paper slips.
- Admissions Officer/Counselor: work the queue by status, log follow-ups, qualify, convert; see the next follow-up due.
- Campaign Manager: register campaigns; attribute lead sources.
- Org Admin/Principal: funnel health (conversion rate, stale applications); oversight of approvals.
4. Stakeholders
Reception desk, admissions/counseling staff, marketing, principal/admin, applicants
(students/parents), interview panels, and system actors (EventBus consumers,
BullMQ admission-reminder / admission-expiry workers (planned),
IMPLEMENTATION_PLAN.md §1.3).
5. Why this exists
Institutions track inquiries in registers and WhatsApp threads. This module replaces that with a tenant-isolated, status-driven pipeline whose terminal state feeds the existing Users + Students modules — so a converted lead or approved admission becomes an enrolled student without re-keying.
6. Platform dependencies (backend)
- Modules:
UsersModule,StudentsModule(conversion),AuthModule(guard). - Tenant isolation: every collection scoped by
tenantId+ soft-delete filter (base.repository.ts:20-30). - Events:
LeadCreated,LeadConverted,AdmissionSubmitted,AdmissionApproved,AdmissionRejected,AdmissionConvertedvia EventBus (crm.service.ts:50-63,166-173;admission.service.ts:54-57,159-168,219-223). - Queues (planned):
admission-reminder,admission-expiryworkers (IMPLEMENTATION_PLAN.md §1.3 — reminder for incomplete docs/interview scheduling, auto-reject stale;findStalescan already exists atadmission.repository.ts:53-62). - Storage: document uploads reference
fileId(storage provider interface) — no upload endpoint in this module yet.
7. Success metrics (module)
- Lead capture completion < 60 s (reception cadence).
- Status pipeline entries per lead are prompt-driven (follow-up due = surfaced first).
- Duplicate-lead 409 path reached instead of double-entry.
- Conversion requires grade/year/class — zero student records created without placement.
- No application is decided from a non-deciable status (server-enforced).
8. Module edge cases
- Duplicate email on lead create → 409
DUPLICATE_RESOURCE(crm.service.ts:42-47). - Convert an already-converted or closed lead → 400 (
crm.service.ts:120-125). - Convert without grade/academicYear/class → 400 (
crm.service.ts:145-149). - Close a lead →
closedAtauto-set whenclosedReasonis absent (crm.service.ts:94-96); reopening is not supported. - Admission decision from a non-decidable status → 400 (
admission.service.ts:141-145). - Editing a closed admission (approved/rejected/waitlisted/converted) → 400
(
admission.service.ts:257-269). - Converting a non-approved admission → 400 (
admission.service.ts:174-178). - User create during conversion is best-effort: existing email → existing user reused
(
crm.service.ts:132-143;admission.service.ts:187-200). - Cross-tenant IDs → 404, never leaked (scoped filter).
9. Module assumptions
- PRD native-app exclusion (flagged):
PRODUCT_REQUIREMENTS_DOCUMENT.md:144puts native mobile apps out of Phase 1 scope. Decision with the product owner (see 00-shared/01 §9): these docs specify a full-featured Flutter client against the complete CRM API surface. Roadmap conflicts resolve in favor of these docs. - RBAC not yet enforced on endpoints: all
/api/v1/crm/*routes sit behindJwtAuthGuardonly (crm.controller.ts:29);crm.read/crm.lead.manage/crm.campaign.manage(permissions.constants.ts:34-36) exist but are not yet decorator-applied — permission checks are a(planned)enforcement item (IMPLEMENTATION_PLAN.md §5.1). - No lead/admission delete endpoints:
BaseRepository.softDelete(base.repository.ts:68-74) exists; exposing it is(planned). UI must not offer delete today. - Workers
(planned): reminder/expiry queues are spec'd but not implemented. - Push reminders
(forward-looking): no device registry exists (00-shared/01 §9); follow-up push notifications are forward-looking. - Lead pipeline terminology:
CLOSED(schema name) is rendered as "dropped/closed".
10. Glossary (module)
| Term | Meaning |
|---|---|
| Lead | An inquiry record (new/contacted/qualified/converted/closed) |
| Convert | Promote lead/admission → User + Student; sets convertedAt |
| Follow-up | {note, scheduledAt, completedAt?, createdBy, createdAt} subdocument |
| Campaign | Marketing source with type/status/dates/metrics |
| Admission | Formal application with document + interview + decision stages |
| Workflow stage | {from, to, approver?, comment?, at} — full admission state history |
| Decidable | submitted / documents_pending / interview_scheduled / under_review |