Skip to content

Latest commit

 

History

History
97 lines (77 loc) · 4.55 KB

File metadata and controls

97 lines (77 loc) · 4.55 KB
name mtp-student-phase-a-decisions
description Resolved decisions for Student module Phase A (Exam-unblocker thin slice). Locked 2026-05-18. Drives the schema + service shape for the first Student build.
metadata
type
project

Student module Phase A — resolved decisions (2026-05-18)

Three architecturally significant decisions resolved after the six-cluster Student study landed. These were the top three open questions in inventory/student-replication-strategy.html. Update that page if these change.

1. Phase A scope = medium Student (~40-50 columns)

NOT slim (15 columns). The medium shape covers identity + bio + address + parents

  • contact + enrolment + status + audit. Slim was tempting for cleanliness but would force a churning rewrite when Phase B lands.

Approximate column inventory (refine during design step):

  • Identity (10): StudentId, EnrolmentNo, FullName, DOB, Gender, Photo, MobileNo, Email, AadharNo, RegistrationNo
  • Demographic (8): CategoryId, ReligionId, BloodGroupId, MotherTongueId, Nationality, MaritalStatus, IsPWD, IsForeignStudent
  • Family (5): FatherName, MotherName, GuardianName, GuardianMobileNo, GuardianRelationId
  • Address (8): PermanentAddress, CurrentAddress, CountryId, StateId, DistrictId, TalukaId, PinCode, IsHostelResident
  • Enrolment (10): ProgramId, SpecializationId, AdmissionYearId, BatchYearId, SemesterId, SectionId, DivisionId, RollNumber, AdmissionQuotaId, AdmissionTypeId, AdmissionDate
  • Status (5): Status, IsActive, IsBlocked, EligibilityStatus, BlockReason
  • Audit (4): CreatedAt, CreatedByUserId, UpdatedAt, UpdatedByUserId

Total ~50 columns. Profile extras (hobbies, achievements, custom fields) defer to Phase B/C/D.

2. StudentExam ownership = Student module owns it

StudentExam is a Student-module-owned projection table that mirrors (Student × Exam) state at registration time. Exam module reads only; never writes.

Why Student owns it:

  • Table name + columns are Student-state denormalisations
  • Updates flow from Student state changes (program / section / semester promotion) into the projection
  • Single write owner avoids ambiguity

Caveat: Exam-result-state fields currently on legacy STU_StudentExam (DegreeCertificateState, ConvocationState) MUST split out into an Exam-owned aggregate (exam.StudentExamResult or equivalent). Those fields are post-result, Exam-side concerns; they don't belong on a Student projection.

Sync mechanism: Student module emits domain events on enrolment / program / section / semester changes; an internal StudentExamProjectionHandler updates student.StudentExam rows. Marten event stream is the source of truth; the table is the read model.

3. Aggregate split = three aggregates

NOT one giant Student aggregate. NOT a per-feature explosion.

Aggregate Owns Changes when
StudentIdentity Bio, demographic, family, address, contact, photo Rarely (admission + occasional address/contact update)
StudentEnrolment Program, specialization, section, division, semester, roll, admission quota, status Per semester / on promotion / on transfer
StudentProfile Achievements, activities, hobbies, clubs, extension fields, mentor links Continuously (Phase B-G concern)

Shared StudentId (uuid). FK from Enrolment + Profile back to Identity.

Why three:

  • Different change frequencies = different consistency boundaries
  • Identity is mostly-immutable once admitted; Enrolment churns semester-by-semester
  • Profile holds the extensibility surface (per-tenant fields, page 09); keeping it separate prevents Identity from bloating
  • 180-parameter GNUMS SPs (InsertFromEnrollment, UpdateFromEnrollment) conflated identity + enrolment + profile; splitting them reverses that
  • Each aggregate gets its own service + repository + event stream

Phase A delivers: StudentIdentity (medium shape above) + StudentEnrolment (slim slice — current-semester only) + StudentExam projection. StudentProfile fully defers to Phase B/D.

How to apply

When working on Student-module code (Phase A or later):

  • Use these three aggregates, not a unified Student
  • Medium column count on StudentIdentity; don't pre-collapse to slim
  • StudentExam writes go through Student module's services; Exam module reads through a thin interface (IStudentExamReader or equivalent)
  • DegreeCertificateState / ConvocationState → Exam module, not Student
  • Profile fields (extension fields, hobbies, achievements) deferred to Phase B+; do not pollute Phase A schema

[[gnums-conventions]] [[mtp-tenancy-model]] [[mtp-authz-model]]