EDA Data Model and Patterns
Activate when working with the Education Data Architecture (EDA) data model in depth: object relationships, record types, extension patterns, and the contact-centric philosophy that underpins it. EDA is the backbone of Education Cloud and underpins most higher-ed + K-12 Salesforce implementations.
Before Starting
- Confirm EDA (HEDA) is installed. EDA is a managed package; verify version and whether customization has already extended it.
- Understand the contact-centric philosophy. Students, faculty, alumni, guardians — all Contacts. The model disambiguates role via Affiliations and Relationships, NOT by separate objects per role.
- Know the record types. Many EDA objects (Account, Affiliation, Contact, Course_Offering__c) rely on record types for semantics. Without record types, the model collapses.
Core Concepts
Contact-centric model
Every Person = Contact. Roles are expressed via:
- Affiliation__c — Contact to Account relationship with role, status, dates (Student at MIT, Faculty at Harvard, Staff at a program).
- Relationship__c — Contact to Contact (Parent, Sibling, Advisor, Partner) with bidirectional symmetry handled by trigger.
Account record types
Academic_Program — a program offered by an institution.
Educational_Institution — the school/university itself.
Household_Account — a Household (parallel to NPSP).
Sports_Organization, Business_Organization — extracurricular affiliations.
Course data model
Course__c — the abstract course (Intro to Biology).
Course_Offering__c — a specific instance of a course for a term (Biology 101, Fall 2025, Prof Smith).
Term__c — academic term.
Course_Connection__c — a student's enrollment in a Course_Offering (and the faculty's teaching assignment is also a Course_Connection with record type Faculty).
Attributes
Student health, test scores, demographics often live in Attribute__c (a generic key-value pattern) to avoid endless fields on Contact. This is a contested design choice — it trades schema clarity for extensibility.
Common Patterns
Pattern: Student → Institution via Affiliation__c
When a student enrolls: create Contact, create Affiliation__c with Role = "Student", Status = "Current", related Account = Academic_Program. Historical affiliations remain with Status = "Former" when they graduate.
Pattern: Faculty teaching assignment
Faculty are Contacts with an Affiliation__c (Role = "Faculty") to the Academic_Program. Their teaching load is Course_Connection__c with record type "Faculty" (or similar) to a Course_Offering__c.
Pattern: Parent / Guardian
Guardian is a Contact. Relationship__c between student Contact and guardian Contact with Type = "Parent". Bidirectional trigger creates the reverse Relationship__c automatically.
Pattern: Multi-campus student
Student Contact has multiple Affiliations to different Account (Academic_Program) records, each with its own status. Reports aggregate by Affiliation, not Contact.
Decision Guidance
| Question |
Answer |
| Where do I store student role? |
Affiliation__c with Role = Student |
| Where do I store parent relationship? |
Relationship__c with Type = Parent |
| Where do I store enrollment in a specific class? |
Course_Connection__c |
| Where does graduation date live? |
End Date on the Student Affiliation |
| Where do I store extended demographics? |
Prefer fields on Contact; use Attribute__c only when schema truly varies |
Recommended Workflow
- Document the real-world concepts (student, faculty, course, term) and map each to an EDA object + record type.
- Draft the ERD with record types called out explicitly.
- Build a reference dataset: 10 students, 5 courses, 2 terms, 3 faculty.
- Validate reports and Affiliation rollups work on the reference dataset.
- Plan any extensions as fields on existing EDA objects; avoid shadow custom objects.
- Map integration fields (SIS → EDA) with record type resolution.
- Write an admin runbook for onboarding new student → Contact → Affiliation → Course_Connection.
Review Checklist
Salesforce-Specific Gotchas
- Relationship__c bidirectional trigger runs on insert/update. Bulk loads must expect double the record count.
- Course_Connection__c has record types that change the page layout. A "Student" connection and a "Faculty" connection use the same object — layout validation is per record type.
- Affiliation rollups (Primary Affiliation, Primary Household) are governed by EDA settings. Changing the hierarchy setting after data load causes rollup drift.
Output Artifacts
| Artifact |
Description |
| EDA ERD with record types |
Canonical schema view |
| Object + field dictionary |
Detailed field-level reference |
| Record-type matrix |
Object × record type × use case |
| SIS/LMS mapping |
Integration field map |
Related Skills
admin/education-cloud-eda-setup — install + configure
integration/integration-pattern-selection — SIS integration patterns
data/data-import-pipelines — large-volume student loads
1---2name: eda-data-model-and-patterns3description: Education Data Architecture (EDA) data model deep dive: Contact-centric, Affiliations, Relationships, Account record types (Academic Program, Educational Institution, Sports Organization), Course_Offering__c, Term__c, Course_Connection__c patterns. NOT for Education Cloud setup, student success hub and advisor workflows — use admin/education-cloud-eda-setup. NOT for generic object and relationship modeling — use data/data-model-design-patterns.4---56# EDA Data Model and Patterns78Activate when working with the Education Data Architecture (EDA) data model in depth: object relationships, record types, extension patterns, and the contact-centric philosophy that underpins it. EDA is the backbone of Education Cloud and underpins most higher-ed + K-12 Salesforce implementations.910## Before Starting1112- **Confirm EDA (HEDA) is installed.** EDA is a managed package; verify version and whether customization has already extended it.13- **Understand the contact-centric philosophy.** Students, faculty, alumni, guardians — all Contacts. The model disambiguates role via Affiliations and Relationships, NOT by separate objects per role.14- **Know the record types.** Many EDA objects (Account, Affiliation, Contact, Course_Offering__c) rely on record types for semantics. Without record types, the model collapses.1516## Core Concepts1718### Contact-centric model1920Every Person = Contact. Roles are expressed via:21- **Affiliation__c** — Contact to Account relationship with role, status, dates (Student at MIT, Faculty at Harvard, Staff at a program).22- **Relationship__c** — Contact to Contact (Parent, Sibling, Advisor, Partner) with bidirectional symmetry handled by trigger.2324### Account record types2526- `Academic_Program` — a program offered by an institution.27- `Educational_Institution` — the school/university itself.28- `Household_Account` — a Household (parallel to NPSP).29- `Sports_Organization`, `Business_Organization` — extracurricular affiliations.3031### Course data model3233- `Course__c` — the abstract course (Intro to Biology).34- `Course_Offering__c` — a specific instance of a course for a term (Biology 101, Fall 2025, Prof Smith).35- `Term__c` — academic term.36- `Course_Connection__c` — a student's enrollment in a Course_Offering (and the faculty's teaching assignment is also a Course_Connection with record type Faculty).3738### Attributes3940Student health, test scores, demographics often live in `Attribute__c` (a generic key-value pattern) to avoid endless fields on Contact. This is a contested design choice — it trades schema clarity for extensibility.4142## Common Patterns4344### Pattern: Student → Institution via Affiliation__c4546When a student enrolls: create Contact, create Affiliation__c with Role = "Student", Status = "Current", related Account = Academic_Program. Historical affiliations remain with Status = "Former" when they graduate.4748### Pattern: Faculty teaching assignment4950Faculty are Contacts with an Affiliation__c (Role = "Faculty") to the Academic_Program. Their teaching load is Course_Connection__c with record type "Faculty" (or similar) to a Course_Offering__c.5152### Pattern: Parent / Guardian5354Guardian is a Contact. Relationship__c between student Contact and guardian Contact with Type = "Parent". Bidirectional trigger creates the reverse Relationship__c automatically.5556### Pattern: Multi-campus student5758Student Contact has multiple Affiliations to different Account (Academic_Program) records, each with its own status. Reports aggregate by Affiliation, not Contact.5960## Decision Guidance6162| Question | Answer |63|---|---|64| Where do I store student role? | `Affiliation__c` with Role = Student |65| Where do I store parent relationship? | `Relationship__c` with Type = Parent |66| Where do I store enrollment in a specific class? | `Course_Connection__c` |67| Where does graduation date live? | End Date on the Student Affiliation |68| Where do I store extended demographics? | Prefer fields on Contact; use Attribute__c only when schema truly varies |6970## Recommended Workflow71721. Document the real-world concepts (student, faculty, course, term) and map each to an EDA object + record type.732. Draft the ERD with record types called out explicitly.743. Build a reference dataset: 10 students, 5 courses, 2 terms, 3 faculty.754. Validate reports and Affiliation rollups work on the reference dataset.765. Plan any extensions as fields on existing EDA objects; avoid shadow custom objects.776. Map integration fields (SIS → EDA) with record type resolution.787. Write an admin runbook for onboarding new student → Contact → Affiliation → Course_Connection.7980## Review Checklist8182- [ ] All record types in use are documented83- [ ] Reference dataset exercises all role/relationship variants84- [ ] Affiliation status and date semantics are agreed85- [ ] Course / Course_Offering / Course_Connection consistently modeled86- [ ] Attribute__c usage deliberately scoped87- [ ] SIS and LMS integrations map to correct record types88- [ ] Reports on Affiliation and Course_Connection match source data8990## Salesforce-Specific Gotchas91921. **Relationship__c bidirectional trigger runs on insert/update.** Bulk loads must expect double the record count.932. **Course_Connection__c has record types that change the page layout.** A "Student" connection and a "Faculty" connection use the same object — layout validation is per record type.943. **Affiliation rollups (Primary Affiliation, Primary Household) are governed by EDA settings.** Changing the hierarchy setting after data load causes rollup drift.9596## Output Artifacts9798| Artifact | Description |99|---|---|100| EDA ERD with record types | Canonical schema view |101| Object + field dictionary | Detailed field-level reference |102| Record-type matrix | Object × record type × use case |103| SIS/LMS mapping | Integration field map |104105## Related Skills106107- `admin/education-cloud-eda-setup` — install + configure108- `integration/integration-pattern-selection` — SIS integration patterns109- `data/data-import-pipelines` — large-volume student loads