| | 64 | ==== !MembershipStageRecords ==== |
| | 65 | |
| | 66 | !MembershipStageRecords stores the history of membership stages for members. It is modeled as an entity because the period attributes identify a historical record, not only a simple relationship between Members and !MembershipStages. |
| | 67 | |
| | 68 | * '''Candidate keys:''' msr_id is chosen as the primary key. |
| | 69 | * '''Attributes:''' |
| | 70 | * msr_id: numeric identifier, required, unique. |
| | 71 | * valid_from: date, required, start date of the membership stage record. |
| | 72 | * valid_to: date, optional for the current active stage; when present, must be greater than or equal to valid_from. |
| | 73 | |
| 308 | | ==== has_stage ==== |
| 309 | | |
| 310 | | has_stage connects Members to !MembershipStages. It stores membership history: which membership stage a member had and during what period. It is needed even though member subtypes exist, because subtypes show the conceptual categories while this relationship records time periods and transitions. |
| 311 | | |
| 312 | | * '''Candidate keys:''' member student_index + ms_id + valid_from is chosen because a member can potentially enter the same stage more than once over time. |
| 313 | | * '''Attributes:''' |
| 314 | | * valid_from: date, required, start date of the membership stage. |
| 315 | | * valid_to: date, optional for the current active stage; when present, must be greater than or equal to valid_from. |
| | 327 | ==== for_member ==== |
| | 328 | |
| | 329 | for_member connects !MembershipStageRecords to Members. It represents which member a membership stage record belongs to. Each membership stage record belongs to exactly one member, while one member can have multiple membership stage records over time. |
| | 330 | |
| | 331 | ==== for_stage ==== |
| | 332 | |
| | 333 | for_stage connects !MembershipStageRecords to !MembershipStages. It represents which membership stage is recorded in a membership stage record. Each membership stage record refers to exactly one membership stage, while the same membership stage can appear in many membership stage records. |
| 321 | | ==== holds_function ==== |
| 322 | | |
| 323 | | holds_function connects !FullMembers to !OrganizationalFunctions. It represents a full member holding an organizational function during a mandate. It is needed because Board membership and coordinator responsibilities are roles held by full members, not separate membership stages. |
| 324 | | |
| 325 | | * '''Candidate keys:''' full member student_index + of_id + mandate_year is chosen because the same full member can hold different functions and the same function can be held by different full members in different mandates. |
| 326 | | * '''Attributes:''' |
| 327 | | * mandate_year: numeric, required, year of the organizational function mandate. |
| | 339 | ==== held_by ==== |
| | 340 | |
| | 341 | held_by connects !FunctionMandates to !FullMembers. It represents which full member held an organizational function during a mandate. Each function mandate belongs to exactly one full member, while one full member can have multiple function mandates over time. |
| | 342 | |
| | 343 | ==== mandate_of ==== |
| | 344 | |
| | 345 | mandate_of connects !FunctionMandates to !OrganizationalFunctions. It represents which organizational function is held in a function mandate. Each function mandate refers to exactly one organizational function, while the same organizational function can appear in many function mandates over different mandate years. |