ADR-0041: Child Nucleus Role in the Module Join Table — nucleus_members, not core students
Status: accepted
Date: 2026-08-31
Deciders: @barateza
Tags: [student-profile, nucleus, data-model, module, issue-151]
Context
The SDD-151 draft put nucleus_role and nucleus_supervisor_role as columns on core students. Two facts contradict that shape: (1) decision #21 (2026-06, "Decisão #21 — nucleusRole no módulo, não no core (#151)") already resolved that the nucleus role belongs to the nucleus module, which is active in both workers (plugin registration) and app; (2) the grilling resolved that children do hold nucleus roles — CONSELHEIRO, AJUDANTE, ANFITRIAO, MEMBRO — but never SUPERVISOR/SUPERVISOR_DE_REDE, which are adult volunteer roles owned by the Voluntários module (#194). A child belongs to exactly one nucleus (hard requirement, consistent with the "Azul Celeste" region rule).
Options considered
(a) Flat nucleus_role column on students. Contradicts decision #21, forces single-nucleus at the schema level, and mixes the child role vocabulary into the core entity where the adult vocabulary (#194) also lands.
(b) Join table nucleus_members(student_id, nucleus_id, role) in @neemias/nucleus. A row IS the participation fact — nucleus_role on students disappears and the draft's "role requires nucleus_participates" invariant dissolves with it. The role vocabulary lives with the module; single-nucleus is enforced at the app layer; multiple nuclei per child stays a non-breaking future option.
Decision
Adopt (b). The nucleus module owns nucleus_members; core students keeps its denormalized nucleusParticipates/nucleusRegion/nucleusName for existing queries. SDD-151 drops both nucleus_role and nucleus_supervisor_role columns; the supervisor roles remain exclusively in #194.
Consequences
- No core-schema migration for roles — the nucleus module ships its own migration, consistent with its plugin shape.
- One-nucleus-per-child is a product rule enforced in the module's service layer; the schema still permits multi if the rule ever changes.
- The child role enum (
CONSELHEIRO | AJUDANTE | ANFITRIAO | MEMBRO) is defined once, in the module, and shared with the UI select (CAD-RQ-04).