v1.0
Reference
Admin
Counselor
Warden

DAC Academy — Workflow Catalog


WORKFLOW 1: LEAD CREATION

AspectDetail
TriggerStaff clicks "New Lead" on /leads or navigates to /leads/new
ActorAdmin or Counselor
Screen/leads/new — Lead Form component
InputsstudentName, targetExam, class, parentName, parentPhone, branchId, probability, status, optional: dateOfBirth, placeCity, schoolName, mediumBoard, strengthSubject, weakSubject, parentOccupation, parentHasWhatsapp, notes, assignedToUserId, source, alternatePhone, alternateHasWhatsapp, state, fullAddress, medicalCheckUp
ValidationsPhone via isValidPhone (libphonenumber-js), WhatsApp consistency (if alternatePhone provided but blank, must equal parentHasWhatsapp), status transitions enforced, registration payment required if status='registered'
System Actions1. Validate via createLeadSchema (Zod safeParse) 2. Normalize phone to E.164 3. Insert into leads table 4. Write audit log 5. If status='registered', also create receipt and registration record inside a transaction
OutputsNew leads row. If registered: receipts row, registrations row
NotificationsNone at this stage
Auditlead.create — afterData with all lead fields
Failure ConditionsDuplicate lead (branch+phone+name unique constraint), invalid phone number
RecoveryEdit the existing lead instead of creating duplicate

WORKFLOW 2: LEAD STATUS TRANSITION

AspectDetail
TriggerStaff updates lead status on edit form or via Register button
ActorAdmin or Counselor
ScreenLead Form (/leads/[id]/edit) or Register Lead Dialog on lead detail
Valid Statusesnewcontactedinterestedregisteredadmitted (automatic), lost (from any non-terminal state)
Registered PathRegistering requires payment details: amountPaise (default 300000), paymentMode, transactionId, paymentScreenshot
System ActionsFor registered: 1. Validate payment 2. Create receipt (REG kind) 3. Create registration record 4. Update lead status 5. Fire-and-forget receipt PDF generation 6. Fire-and-forget WhatsApp notification 7. Audit log
OutputsUpdated lead, registration record, receipt with number
NotificationsWhatsApp to parent: registration confirmation with receipt number
Auditlead.status_change — before and after status

WORKFLOW 3: ADMISSION CREATION

This is the most complex workflow in the system. It creates 10+ database records in a single transaction.

AspectDetail
TriggerStaff submits the admission form on /admissions/new
ActorAdmin or Counselor
Screen/admissions/new — Multi-section admission form
Pre-requisitesActive academic session must exist. Active checklist items must exist. Batch must not be completed/cancelled.
InputsSee Phase 5 Admissions section for complete field list
Transaction Flow1. Lock batch row (FOR UPDATE) 2. Check batch capacity 3. Create/verify parent user (if email provided) 4. Hash Aadhaar (if provided) 5. Create Student record 6. Update lead status to 'admitted' 7. Create student_session row 8. Create hostel allocation (if applicable) 9. Generate receipt (ADM kind) 10. Create Admission record 11. Write fee_components from batch templates 12. Create FeeRecord 13. Create paid installment for initial payment 14. Create future installments 15. Initialize document checklist 16. Insert admission items 17. Increment batch version (optimistic lock) 18. Audit log
Post-Transaction1. Fire WhatsApp admission notification 2. Generate and store receipt PDF (async)
ConcurrencyBatch row locked FOR UPDATE inside transaction. Capacity re-checked after lock. Version increment on batch.
OutputsStudent, Admission, FeeRecord, Installments, Receipt, StudentSession, HostelAllocation (if needed), AdmissionChecklist, AdmissionItems, FeeComponents
NotificationsWhatsApp to parent: admission confirmation with receipt details, items given/remaining, parent login credentials
Auditadmission.submit — full afterData snapshot

WORKFLOW 4: FEE PAYMENT RECORDING

AspectDetail
TriggerStaff clicks "Record Payment" on fee/student page, or selects an unpaid installment
ActorAdmin or Counselor
ScreenAdd Payment Dialog (from /fees or /students/[id])
InputsfeeRecordId, amountPaise, paymentMode, transactionId, paymentScreenshotUrl, optional: installmentId (to resolve specific installment)
Transaction Flow1. Lock fee_record row (FOR UPDATE) 2. Verify remainingPaise >= payment amount 3. Create receipt (ADM kind) 4. Create paid installment row 5. Update fee_record: totalPaidPaise += amount, remainingPaise -= amount (version check) 6. Mark any matching installment as paid 7. Audit log
Financial InvariantstotalFeePaise = totalPaidPaise + remainingPaise (DB-enforced CHECK)
OutputsReceipt, paid installment, updated fee_record
NotificationsWhatsApp to parent: payment confirmation
Failure ConditionsOverpayment (amount > remaining), duplicate transaction ID
RecoveryVoid the payment if recorded in error

WORKFLOW 5: INSTALLMENT VOIDING

AspectDetail
TriggerStaff clicks "Void" on a paid installment
ActorAdmin or Counselor
ScreenPayment History on /students/[id]
InputsInstallment ID, version, void reason
Transaction Flow1. Lock fee_record 2. Mark installment as voided (voidedAt, voidedBy, voidReason) 3. Recalculate fee_record aggregates 4. Audit log
Financial ImpactVoiding reverses the payment: totalPaidPaise -= amount, remainingPaise += amount
Receipt StatusVoiding an installment does NOT void the receipt. Receipts are immutable.
OutputsVoided installment, recalculated fee_record

WORKFLOW 6: STUDENT STATUS TRANSITION (LIFECYCLE)

AspectDetail
TriggerStaff uses Status Transition Dialog on student detail page
ActorAdmin or Counselor
Available Transitionsactiveleft (with leftDate, reason), activetc_issued (with tcNumber), activeremoved (with reason), activecompleted (with completedDate)
Transaction Flow1. Lock student_session row 2. Update status, set appropriate date fields 3. Clear batchId on left/tc_issued/removed 4. Audit log
Business RulesCannot leave if fee arrears exist (app-enforced). TC issuance requires fee clearance.
OutputsUpdated student_session row

WORKFLOW 7: STUDENT RE-ENROLLMENT

AspectDetail
TriggerStaff clicks "Re-enroll" on student detail page
ActorAdmin or Counselor
Pre-requisitesStudent must have a terminal status (left/tc_issued/removed/completed)
InputsstudentId, batchId, optional: new sessionId
Transaction Flow1. Verify student's latest session is in terminal status 2. Create new student_session row with status='active' for current/selected session 3. Set student's batchId to new batch 4. Set student isActive=true 5. Audit log
OutputsNew active student_session, updated student

WORKFLOW 8: STUDENT PROMOTION

AspectDetail
TriggerStaff clicks "Promote" on student detail page
ActorAdmin or Counselor
Pre-requisitesNext academic session must exist. Student must be active in current session.
Transaction Flow1. Create new student_session for next session with status='active' 2. Create fee_record for new session 3. Carry forward any unpaid fee balance 4. Audit log
OutputsNew student_session and fee_record for new session

WORKFLOW 9: STUDENT REINSTATEMENT

AspectDetail
TriggerStaff clicks "Reinstate" on student detail page
ActorAdmin or Counselor
Transaction Flow1. Find the student's most recent student_session 2. Update its status back to 'active' 3. Clear leftDate/tcNumber/removalReason 4. Set student isActive=true 5. Audit log
OutputsReactivated student_session, updated student

WORKFLOW 10: HOSTEL OUTING REQUEST (PARENT)

AspectDetail
TriggerParent submits outing form on /parent/hostel-outing
ActorParent (must own the student)
Screen/parent/hostel-outing — Outing Form
InputsstudentId, startDate, endDate, reason, type, accompaniedBy, accompaniedByDetails, expectedReturnDate, expectedReturnTime
ValidationsEnd date >= start date, reason 1-1000 chars, parent must own student (requireOwnership), student must be hostel-opted and have active session
System Actions1. Validate via requestOutingSchema 2. Verify ownership 3. Verify hostel-opted and active session 4. Insert into hostel_outings (status='pending') 5. Audit log 6. Fire-and-forget WhatsApp notification to warden
OutputsNew hostel_outings row

WORKFLOW 11: OUTING REVIEW (WARDEN/ADMIN)

AspectDetail
TriggerWarden/admin opens outing detail page and clicks Approve/Reject
ActorWarden or Admin
Screen/hostel/outings/[id] — Review Form
Inputsstatus (approved/rejected), comment (optional)
ScopingWarden: only outings for students in their hostel. Admin: all outings via branch scope.
System Actions1. Scoping check 2. Update outing status, reviewedByUserId, reviewedAt, reviewNotes 3. Audit log 4. Fire-and-forget WhatsApp notification to parent
OutputsUpdated outing status

WORKFLOW 12: OUTING RETURN (WARDEN/ADMIN)

AspectDetail
TriggerWarden/admin marks an approved outing as returned
ActorWarden or Admin
Pre-requisitesOuting must be in 'approved' status
System Actions1. Scoping check 2. Update status to 'returned', set returnedAt timestamp 3. Audit log
OutputsUpdated outing — status changes from 'approved' to 'returned'

WORKFLOW 13: MEDICAL REQUEST SUBMISSION (PARENT)

AspectDetail
TriggerParent submits medical request form on /parent/medical
ActorParent
Screen/parent/medical
InputsstudentId, disease, medicineName, doseQuantity, doseTime, optional: consultedDoctor, notes
ValidationsStudent must be hostel-opted, have active session, parent must own student
System Actions1. Validate via submitRequestSchema 2. Verify ownership 3. Verify hostel-opted and active session 4. Insert into medical_requests (status='pending') 5. Audit log
OutputsNew medical_requests row

WORKFLOW 14: MEDICAL REQUEST ACKNOWLEDGMENT (WARDEN/ADMIN)

AspectDetail
TriggerWarden/admin clicks "Acknowledge" on medical request in queue
ActorWarden or Admin
ScreenMedical Requests tab on /hostel or /warden/medical
Pre-requisitesRequest status must be 'pending'. Warden: request must be for student in their hostel.
System Actions1. Scoping check (warden hostel filter) 2. Update status to 'acknowledged' 3. Set acknowledgedByUserId, acknowledgedAt 4. Optimistic lock via version 5. Audit log 6. Fire-and-forget WhatsApp notification to parent
OutputsUpdated medical request (pending → acknowledged)

WORKFLOW 15: MEDICAL REQUEST COMPLETION/REJECTION (WARDEN/ADMIN)

AspectDetail
TriggerWarden/admin clicks Complete or Reject on acknowledged request
ActorWarden or Admin
Pre-requisitesRequest must be in 'acknowledged' status
CompletionStatus → 'completed'. No additional fields.
RejectionStatus → 'rejected'. Requires rejectionReason.
System Actions1. Scoping check 2. Validate status transition 3. Update with optimistic lock 4. Audit log
OutputsUpdated medical request

WORKFLOW 16: SESSION ACTIVATION

AspectDetail
TriggerAdmin clicks "Activate" on a session in Settings
ActorAdmin
Screen/settings → Sessions tab
Transaction Flow1. Begin transaction 2. Deactivate all currently active sessions 3. Activate the selected session 4. Audit log
Business RulesOnly one session can be active at a time. Cannot deactivate a session that has active students.
OutputsUpdated academic_sessions rows

WORKFLOW 17: FEE REMINDER CRON

AspectDetail
TriggerCron job calls /api/cron/fee-reminders
ActorSystem (cron)
Logic1. Find all unpaid/past-due installments 2. For each, check if reminderSent=false 3. Enqueue WhatsApp notification 4. Set reminderSent=true
OutputsEnqueued notification jobs

WORKFLOW 18: NOTIFICATION QUEUE PROCESSING

AspectDetail
TriggerCron job calls /api/cron/process-notifications
ActorSystem (cron, ~every 2 minutes)
Logic1. Fetch up to 5 pending jobs with scheduledAt <= now 2. Atomically claim (UPDATE status='processing' WHERE status='pending') 3. For each job: send WhatsApp via WATI API 4. On success: mark 'completed' 5. On failure: retry with exponential backoff (2^attempt minutes), up to 3 attempts
SafetyAtomic claim prevents duplicate sends across overlapping cron invocations
OutputsProcessed notification jobs

WORKFLOW 19: USER CREATION (ADMIN)

AspectDetail
TriggerAdmin fills user creation form
ActorAdmin
Screen/users — User Dialog
Inputsemail, password (auto-generated or custom), name, role, branchId, hostelId, phone
System Actions1. Validate input via createUserSchema 2. Create Better Auth user via auth.api.signUpEmail 3. Update users table with role/branch/hostel 4. Set emailVerified=true 5. Audit log
OutputsNew users row and Better Auth account

WORKFLOW 20: PARENT ACCOUNT CREATION

AspectDetail
TriggerAdmission submission (auto) OR staff clicks "Create Parent Account" button
ActorSystem (auto) or Admin/Counselor (manual)
Logic1. If email doesn't exist in users: create via Better Auth signUpEmail 2. Generate random password Parent@XXXX 3. Set role='parent', emailVerified=true 4. Link to student via parentUserId 5. Return credentials for display
OutputsNew parent users row and Better Auth account