Audience: Developers, researchers, and AI agents who need to understand, modify, or extend the ontology-driven form system in HeritageGraph.
Last Updated: February 2026 (aligned withontology/HeritageGraph.yamlv1.0.0)
- Overview β How It All Connects
- Architecture Diagram
- Source of Truth Files
- Ontology β Frontend Mapping
- Registered Entity Types (24 total)
- Controlled Vocabularies (Enums)
- How to Make Changes
- Field Type Reference
- OntologyClass Interface
- OntologyField Interface
- Ontology β Backend Model Alignment
- Data Flow: Form β API β Database
- CIDOC-CRM Alignment Reference
- PROV-O Provenance Layer
- Troubleshooting & Common Mistakes
- File Map
HeritageGraph uses a registry-driven architecture where a single TypeScript file (registry.ts) defines every entity type. The entire UI β forms, data tables, detail views, and navigation β auto-generates from this registry.
HeritageGraph.yaml (LinkML) β Canonical ontology (classes, slots, enums)
β
βΌ
Heritage.ttl (OWL/Turtle) β Generated OWL for linked-data consumers
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (heritage_graph_ui/src/lib/ontology/) β
β β
β types.ts β TypeScript interfaces (OntologyField, etc.) β
β enums.ts β Controlled vocabularies (dropdown options) β
β registry.ts β Entity class definitions (fields, sections...) β
β index.ts β Barrel re-export β
β β
β β auto-generates β β
β β
β OntologyForm β Contribute forms β
β OntologyDataTable β Knowledge tables β
β Detail views β Entity detail pages β
β Contribute page β Dashboard intent cards β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ (POST/GET via Bearer token)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend (heritage_graph/apps/cidoc_data/) β
β β
β models.py β Django models (must match field keys) β
β serializers.py β DRF serializers β
β views.py β ViewSets + search β
β urls.py β API routes (must match apiEndpoint) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Golden rule: The field key in the registry must exactly match the Django model field name, and apiEndpoint must match the URL route registered in urls.py.
ββββββββββββββββββββββββββββββββ
β ontology/HeritageGraph.yaml β
β (LinkML β 2060 lines) β
β 40+ classes, 100+ slots β
βββββββββββββ¬ββββββββββββββββββββ
β derived from
βββββββββββββΌββββββββββββββββββββ
β ontology/Heritage.ttl β
β (OWL/Turtle β 5190 lines) β
βββββββββββββ¬ββββββββββββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββ
β β β
ββββββββΌβββββββ ββββββββββΌβββββββββ ββββββββββΌβββββββββ
β enums.ts β β registry.ts β β Django models β
β 22 enums βββββΆβ 24 classes β β cidoc_data β
β dropdowns β β fields/cols β β heritage_data β
βββββββββββββββ ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β β
ββββββββββββΌβββββββββββ ββββββββΌβββββββββββ
β OntologyForm β β DRF Serializer β
β auto-generates UI βββββΆβ API ViewSet β
βββββββββββββββββββββββ βββββββββββββββββββ
| File | Location | Purpose | Lines |
|---|---|---|---|
| HeritageGraph.yaml | ontology/HeritageGraph.yaml |
Canonical LinkML schema β classes, slots, enums, prefixes | ~2060 |
| Heritage.ttl | ontology/Heritage.ttl |
Generated OWL/Turtle for linked-data consumers | ~5190 |
| types.ts | heritage_graph_ui/src/lib/ontology/types.ts |
TypeScript interfaces (OntologyField, OntologyClass, etc.) |
~103 |
| enums.ts | heritage_graph_ui/src/lib/ontology/enums.ts |
Controlled vocabularies for select fields |
~230 |
| registry.ts | heritage_graph_ui/src/lib/ontology/registry.ts |
All 24 entity class definitions with fields, sections, columns | ~900 |
| index.ts | heritage_graph_ui/src/lib/ontology/index.ts |
Barrel export | ~17 |
| HeritageGraph.yaml concept | Frontend equivalent |
|---|---|
classes: block |
OntologyClass in registry.ts |
slots: block |
OntologyField in each class's fields array |
enums: block |
Entry in ontologyEnums in enums.ts |
class_uri |
classUri property on OntologyClass |
is_a (inheritance) |
parentClass property on OntologyClass |
slot_usage (required, range) |
required, options, relationTo on OntologyField |
When translating from HeritageGraph.yaml to the frontend registry, follow these rules:
| YAML construct | Frontend mapping | Example |
|---|---|---|
ArchitecturalStructure class |
const architecturalStructure: OntologyClass with key: "structure" |
registry.ts |
name slot with slot_uri: rdfs:label |
nameField("Structure Name") |
Every class |
note slot with slot_uri: crm:P3_has_note |
noteField() |
Every class |
has_current_location slot with range: Place |
{ type: "relation", relationTo: "location" } |
Structures |
ArchitecturalStyleEnum enum |
ontologyEnums.ArchitecturalStyleEnum in enums.ts |
Structure form |
multivalued: true in YAML |
multivalued: true on OntologyField |
Ritual deity links |
required: true in slot_usage |
required: true on OntologyField |
Name fields |
| Registry Key | Label | Category | Ontology Class | CIDOC-CRM URI | API Endpoint |
|---|---|---|---|---|---|
person |
Person | social | Person |
crm:E21_Person |
/cidoc/persons/ |
location |
Place | spatiotemporal | Place |
crm:E53_Place |
/cidoc/locations/ |
event |
Event | event | HistoricalEvent |
crm:E5_Event |
/cidoc/events/ |
period |
Historical Period | spatiotemporal | β |
crm:E4_Period |
/cidoc/historical_periods/ |
tradition |
Tradition | conceptual | β |
crm:E55_Type |
/cidoc/traditions/ |
source |
Source | provenance | DataSource |
crm:E73_Information_Object |
/cidoc/sources/ |
deity |
Deity | conceptual | Deity |
crm:E28_Conceptual_Object |
/cidoc/deities/ |
guthi |
Guthi | social | Guthi |
crm:E74_Group |
/cidoc/guthis/ |
structure |
Architectural Structure | tangible | ArchitecturalStructure |
crm:E22_Human-Made_Object |
/cidoc/structures/ |
ritual |
Ritual Event | event | RitualEvent |
crm:E7_Activity |
/cidoc/rituals/ |
festival |
Festival | event | Festival |
crm:E7_Activity |
/cidoc/festivals/ |
iconography |
Iconographic Object | tangible | IconographicObject |
crm:E22_Human-Made_Object |
/cidoc/iconographic_objects/ |
monument |
Monument | tangible | BuddhistMonument |
heritageGraph:BuddhistMonument |
/cidoc/monuments/ |
calendar |
Calendar System | spatiotemporal | CalendarSystem |
time:Calendar |
/cidoc/calendar_systems/ |
syncretism |
Syncretic Relationship | conceptual | SyncreticRelationship |
crm:E13_Attribute_Assignment |
/cidoc/syncretic_relationships/ |
kumari_tenure |
Living Goddess Tenure | event | LivingGoddessTenure |
crm:E4_Period |
/cidoc/kumari_tenures/ |
kumari_selection |
Living Goddess Selection | event | LivingGoddessSelection |
heritageGraph:LivingGoddessSelection |
/cidoc/kumari_selections/ |
kumari_retirement |
Living Goddess Retirement | event | LivingGoddessRetirement |
heritageGraph:LivingGoddessRetirement |
/cidoc/kumari_retirements/ |
documentation |
Documentation Activity | provenance | DocumentationActivity |
crm:E7_Activity |
/cidoc/documentation_activities/ |
caste_group |
Caste Group | social | CasteGroup |
crm:E74_Group |
/cidoc/caste_groups/ |
assertion |
Heritage Assertion | provenance | HeritageAssertion |
crminf:I2_Belief |
/cidoc/assertions/ |
| Registry Key | Label | Ontology Class | Purpose |
|---|---|---|---|
material |
Material | Material |
Physical substances used in construction/ritual |
technique |
Technique | Technique |
Craft methods used in production |
religious_tradition |
Religious Tradition | ReligiousTradition |
Reference for tradition dropdowns |
| Category Key | Label | Icon | Entities |
|---|---|---|---|
tangible |
Tangible Heritage | landmark | structure, iconography, monument, material, technique |
conceptual |
Conceptual Entities | lightbulb | deity, tradition, syncretism, religious_tradition |
event |
Events & Rituals | calendar | event, ritual, festival, kumari_tenure, kumari_selection, kumari_retirement |
social |
Social Organizations | users | person, guthi, caste_group |
spatiotemporal |
Spaces & Time | map | location, period, calendar |
provenance |
Sources & Provenance | book-open | source, documentation, assertion |
All enums live in heritage_graph_ui/src/lib/ontology/enums.ts. Each is an array of { value, label, description? }.
| Enum Key | Values | Used By | Ontology Source |
|---|---|---|---|
ConditionTypeEnum |
Good, Damaged, Ruined, Restored | Structure condition | ConditionTypeEnum |
ExistenceStatusEnum |
Extant, PartiallyExtant, Destroyed, Lost, Hypothetical, Unknown | Structure/Monument status | ExistenceStatusEnum |
RitualTypeEnum |
19 values (NityaPuja β ProcessionalMovement) | Ritual type | RitualTypeEnum |
DatePrecisionEnum |
Exact, Year, Decade, Century, Circa | TimeSpan precision | DatePrecisionEnum |
ArchitecturalStyleEnum |
Pagoda, Shikhara, Dome, Chaitya, Stupa | Structure style | ArchitecturalStyleEnum |
GuthiTypeEnum |
SiGuthi β RajGuthi (8 types) | Guthi classification | GuthiTypeEnum |
SyncreticTypeEnum |
Equivalence, Appropriation, Fusion, Historical | Syncretic relationship type | SyncreticTypeEnum |
LocationTypeEnum |
city, village, region, temple, monument, museum, archaeological_site | Place type | Custom |
SourceTypeEnum |
book, journal, archive, thesis, web, field_note, oral_history, inscription | Source material type | Custom |
TraditionCategoryEnum |
ritual, dance, storytelling, craft, music, festival | Tradition category | Custom |
EventTypeEnum |
festival, ritual, historical, ceremony | Event classification | Custom |
RecurrenceEnum |
annual, biennial, monthly, one_time | Event frequency | Custom |
ReligiousTraditionEnum |
Hindu, Buddhist, Syncretic, Jain, Animist, Other | Deity/calendar tradition | ReligiousTradition |
CustodianTypeEnum |
government, academic, community, museum, private, religious | Data custodian type | Custom |
DataCiteResourceTypeEnum |
Dataset, Text, Image, Audio, Interview, PhysicalObject, Collection | Source resource type | DataCite |
IdentifierTypeEnum |
DOI, ISBN, Handle, URL, LocalArchiveID, ISSN | Persistent ID type | DataCite |
VerificationMethodEnum |
cross_check, expert_review, field_visit, archival_comparison, oral_testimony | Verification method | Custom |
DocumentationMethodEnum |
8 methods (photographic_survey β drone_survey) | Documentation activity | Custom |
FestivalTypeEnum |
ChariotFestival, MaskedDance, Jatra, Other | Festival classification | Ontology |
StructureTypeEnum |
9 types (Temple β Other) | Structure classification | Ontology subclasses |
IconographicObjectTypeEnum |
Paubha, Murti, Other | Iconographic object type | Ontology subclasses |
MonumentTypeEnum |
Stupa, Chaitya, Other | Monument type | Ontology subclasses |
Scenario: Add a "patron_deity" field to the Guthi form.
Step 1 β Edit registry.ts:
Find the guthi definition and add to its fields array:
{
key: "patron_deity", // Must match Django model field name
label: "Patron Deity", // Human-readable label
type: "relation", // Field type (see Section 8)
section: "function", // Which section to place it in
order: 2, // Sort order within section
relationTo: "deity", // Related ontology class key
relationEndpoint: "/cidoc/deities/", // API endpoint for search
description: "Primary deity this Guthi serves"
},Step 2 β Django model (if new field):
# heritage_graph/apps/cidoc_data/models.py
class Guthi(CIDOCBaseModel):
# ... existing fields ...
patron_deity = models.ForeignKey('Deity', null=True, blank=True, on_delete=models.SET_NULL)Step 3 β Serializer + migration:
cd heritage_graph
python manage.py makemigrations cidoc_data
python manage.py migrateAdd the field to the serializer's Meta.fields list if needed.
That's it. The form, table, and detail view all update automatically.
Scenario: Add a "MaterialTypeEnum" for construction materials.
Step 1 β Edit enums.ts:
Add inside the ontologyEnums object:
MaterialTypeEnum: [
{ value: "stone", label: "Stone", description: "Natural stone (brick, slate, marble)" },
{ value: "wood", label: "Wood", description: "Timber construction material" },
{ value: "brick", label: "Brick", description: "Fired clay brick" },
{ value: "metal", label: "Metal", description: "Bronze, copper, iron" },
{ value: "terracotta", label: "Terracotta", description: "Unglazed ceramic" },
],Step 2 β Use it in a field:
{
key: "primary_material",
label: "Primary Material",
type: "select",
options: ontologyEnums.MaterialTypeEnum,
section: "architecture",
order: 4,
},Step 3 β Django model:
Add corresponding choices tuple to the Django model field.
Scenario: Add an "Inscription" entity for stone/copper-plate inscriptions.
Step 1 β Define the class in registry.ts:
const inscription: OntologyClass = {
key: "inscription",
label: "Inscription",
labelPlural: "Inscriptions",
description: "Stone or copper-plate inscription with epigraphic content",
classUri: "crm:E34_Inscription",
icon: "file-text", // Lucide icon name
apiEndpoint: "/cidoc/inscriptions/", // Must match Django URL
category: "tangible", // Category group
navigable: true, // Show in sidebar/nav
sections: [
{ key: "basic", label: "Basic Information" },
{ key: "content", label: "Epigraphic Content" },
{ key: "location", label: "Location" },
],
fields: [
nameField("Inscription Name"),
{ key: "script", label: "Script", type: "text", section: "content", order: 1,
placeholder: "e.g., Lichhavi Brahmi, Ranjana", description: "Writing system used" },
{ key: "language", label: "Language", type: "text", section: "content", order: 2,
placeholder: "e.g., Sanskrit, Nepal Bhasa" },
{ key: "transcription", label: "Transcription", type: "textarea", section: "content", order: 3,
description: "Full transcription of the inscription text" },
{ key: "date_earliest", label: "Date", type: "text", section: "basic", order: 2,
placeholder: "e.g., 464 CE (Lichhavi)" },
{ key: "location_name", label: "Location", type: "text", section: "location", order: 1 },
{ key: "coordinates", label: "Coordinates", type: "coordinates", section: "location", order: 2 },
noteField(),
],
columns: [
{ key: "name", label: "Name", sortable: true, visible: true },
{ key: "script", label: "Script", sortable: true, visible: true, format: "badge" },
{ key: "language", label: "Language", sortable: true, visible: true },
{ key: "date_earliest", label: "Date", sortable: true, visible: true },
],
};Step 2 β Register it:
Add to the ontologyClasses export:
export const ontologyClasses: Record<string, OntologyClass> = {
// ... existing entries ...
inscription,
};Step 3 β Create the contribute page:
Create heritage_graph_ui/src/app/dashboard/contribute/inscription/page.tsx:
"use client";
import OntologyForm from "@/components/ontology-form";
import { getOntologyClass } from "@/lib/ontology";
export default function ContributeInscriptionPage() {
const cls = getOntologyClass("inscription")!;
return <OntologyForm ontologyClass={cls} />;
}Step 4 β Add to contribute dashboard (optional):
Edit heritage_graph_ui/src/app/dashboard/contribute/page.tsx β add an entry to contributionIntents:
{
key: "inscription",
label: "Record an Inscription",
description: "Stone or copper-plate inscriptions with transcription and dating.",
icon: "π",
category: "Tangible Heritage",
route: "/dashboard/contribute/inscription",
difficulty: "advanced",
gradient: "from-blue-500 to-sky-600",
},Step 5 β Django backend:
- Add model in
heritage_graph/apps/cidoc_data/models.py - Add serializer in
serializers.py - Add ViewSet in
views.py - Register route in
urls.pyβrouter.register(r'inscriptions', InscriptionViewSet) - Run
makemigrations+migrate
Step 6 β Knowledge page (auto-generated):
Create heritage_graph_ui/src/app/dashboard/knowledge/inscription/page.tsx following the same pattern as other knowledge pages.
Relation fields let users link entities together (e.g., "this ritual invokes deity X").
{
key: "invokes_deity", // Django field name
label: "Invokes Deity", // Form label
type: "relation", // Must be "relation"
section: "participation", // Form section
order: 2,
relationTo: "deity", // Registry key of the related class
relationEndpoint: "/cidoc/deities/", // API endpoint for autocomplete search
multivalued: true, // Allow linking multiple entities
description: "Deity invoked or made present through ritual"
},The EntitySearch component renders an autocomplete dropdown that calls the related API endpoint.
Sections visually group fields in the form. Add to the sections array:
sections: [
{ key: "basic", label: "Basic Information" },
{ key: "provenance", label: "Provenance & Sources" }, // β new
{ key: "status", label: "Status & Condition", description: "Current physical state" },
],Then set section: "provenance" on any field you want in that group.
The contribute page at /dashboard/contribute/ shows intent cards grouped by category.
Edit heritage_graph_ui/src/app/dashboard/contribute/page.tsx:
// Add to the contributionIntents array
{
key: "your_entity", // Unique key
label: "Your Label", // Card title
description: "Description...", // Card description
icon: "ποΈ", // Emoji icon
category: "Tangible Heritage", // Category group header
route: "/dashboard/contribute/your-entity", // Must match page route
difficulty: "beginner", // beginner | intermediate | advanced
gradient: "from-blue-500 to-sky-500", // Tailwind gradient
},| Type | Renders As | When to Use | Example |
|---|---|---|---|
text |
Single-line input | Short strings, names, dates as text | Name, aliases, "c. 1200 CE" |
textarea |
Multi-line textarea | Long descriptions, notes, transcriptions | Biography, route description |
number |
Number input | Integer values | Year offset, start year |
float |
Number input (decimal) | Decimal values | Confidence score (0.0β1.0) |
date |
Date picker | ISO dates | Last known existence date |
select |
Dropdown | Pick one from enum | Structure type, ritual type |
multiselect |
Multi-select | Pick many from enum | (not yet fully implemented) |
boolean |
Checkbox | Yes/no flags | is_critical_for_festival |
url |
URL input | Web links | Digital source URL |
coordinates |
Lat/Long input | GPS positions | Structure coordinates |
relation |
Entity search autocomplete | Link to another entity | Deity β Structure, Ritual β Festival |
interface OntologyClass {
key: string; // Machine key ("structure", "deity")
label: string; // Human label ("Architectural Structure")
labelPlural: string; // Plural ("Architectural Structures")
description: string; // From ontology description
classUri?: string; // CIDOC-CRM URI ("crm:E22_Human-Made_Object")
parentClass?: string; // Inheritance ("structure" β "monument")
icon?: string; // Lucide icon name
apiEndpoint: string; // Django API route ("/cidoc/structures/")
fields: OntologyField[]; // Form fields
columns: OntologyColumn[]; // Data table columns
sections?: { key, label, description? }[]; // Form section groupings
navigable?: boolean; // Show in sidebar/nav? (default: false)
category?: string; // "tangible"|"conceptual"|"event"|"social"|"spatiotemporal"|"provenance"
}interface OntologyField {
key: string; // Must match Django model field name exactly
label: string; // Human-readable label
type: FieldType; // "text"|"textarea"|"select"|"relation"|...
description?: string; // Help text below the field
required?: boolean; // Form validation
options?: Array<{ value, label, description? }>; // For select/multiselect
relationTo?: string; // For relation: related class registry key
relationEndpoint?: string; // For relation: API endpoint for search
multivalued?: boolean; // Accept multiple values
section?: string; // Section key for grouping
order?: number; // Sort order within section
placeholder?: string; // Input placeholder text
defaultValue?: any; // Default value
}Every frontend entity class must have a corresponding Django model, serializer, ViewSet, and URL route.
| Step | File | What to do |
|---|---|---|
| 1 | cidoc_data/models.py |
Add Django model with fields matching registry key values |
| 2 | cidoc_data/serializers.py |
Add ModelSerializer |
| 3 | cidoc_data/views.py |
Add ModelViewSet |
| 4 | cidoc_data/urls.py |
Register with router: router.register(r'endpoint', ViewSet) |
| 5 | Run migrations | python manage.py makemigrations cidoc_data && python manage.py migrate |
| 6 | ontology/enums.ts |
Add any new enums |
| 7 | ontology/registry.ts |
Add OntologyClass definition |
| 8 | contribute/<key>/page.tsx |
Create contribute page |
| 9 | contribute/page.tsx |
Add intent card |
- Registry
keyβ Django model field name β API JSON key (all identical) coordinatesfields serialize as"lat,long"stringsselectfieldvaluemust match Djangochoicestuple first elementrelationfields typically map toForeignKeyorManyToManyFieldin Django
User fills form
β
βΌ
OntologyForm component reads class definition from registry
β
βΌ
Collects field values, validates required fields
β
βΌ
POST to apiEndpoint (e.g., /cidoc/structures/)
with Authorization: Bearer <session.accessToken>
β
βΌ
Django REST Framework serializer validates & saves
β
βΌ
PostgreSQL (prod) / SQLite (dev) stores the data
β
βΌ
Knowledge table fetches via GET to same apiEndpoint
The ontology is fully aligned with CIDOC-CRM (ISO 21127). Key mappings:
| HeritageGraph Class | CIDOC-CRM Class | Role |
|---|---|---|
| ArchitecturalStructure | E22 Human-Made Object | Physical heritage objects |
| Temple, Stupa, Chaitya | E22 (subclassed) | Domain-specific subtypes |
| Deity | E28 Conceptual Object | Divine concepts (not physical) |
| Person | E21 Person | Actors who perform activities |
| Guthi | E74 Group | Social organizations |
| Place | E53 Place | Geographic locations |
| TimeSpan | E52 Time-Span | Temporal extents |
| Production | E12 Production | Object creation events |
| RitualEvent | E7 Activity | Intentional activities |
| Consecration | E7 Activity | Ritual activation events |
| Enshrinement | E7 Activity | Deity installation events |
| TransferOfCustody | E10 Transfer of Custody | Stewardship changes |
| ConditionAssessment | E14 Condition Assessment | Condition evaluations |
| DataSource | E73 Information Object | Documentary sources |
| HeritageAssertion | CRMinf I2 Belief | Propositional claims |
| SyncreticRelationship | E13 Attribute Assignment | Syncretic equivalence claims |
Key properties (slots):
| HeritageGraph Slot | CIDOC-CRM Property | Meaning |
|---|---|---|
name |
rdfs:label |
Primary label |
note |
P3 has note |
Free-text description |
has_current_location |
P55 has current location |
Current location |
was_produced_by_event |
P108i was produced by |
Production link |
carried_out_by |
P14 carried out by |
Actor who performed event |
has_timespan |
P4 has time-span |
Temporal extent |
took_place_at |
P7 took place at |
Event location |
depicts_deity |
P62 depicts |
Iconographic depiction |
enshrined_deity |
P12 occurred in the presence of |
Deity installed |
invokes_deity |
P12 occurred in the presence of |
Deity invoked |
HeritageGraph implements assertion-level provenance using PROV-O:
HeritageAssertion (prov:Entity / crminf:I2_Belief)
βββ assertion_content β prov:value (the claim text)
βββ asserted_property β what property is being claimed
βββ asserted_value β the claimed value
βββ was_derived_from_source β prov:wasDerivedFrom β DataSource
βββ was_attributed_to_agent β prov:wasAttributedTo β Person
βββ generated_at_time β prov:generatedAtTime (ISO datetime)
βββ confidence_score β 0.0β1.0 reliability
βββ reconciliation_status β confirmed | conflicting | unverified
βββ supersedes_assertion β prov:invalidated (version chain)
This means every factual claim about a heritage entity can be traced back to:
- Who said it (agent)
- When they said it (timestamp)
- Where they got it (source)
- How confident we are (score)
- Whether it conflicts with other claims (reconciliation)
- β
Check
sectionmatches a key in the class'ssectionsarray - β
Check
orderis set (fields without order sort unpredictably) - β
Check the class is exported in
ontologyClassesinregistry.ts
- β
Check
type: "select"is set - β
Check
options: ontologyEnums.YourEnumpoints to an existing enum - β
Check the enum is properly exported from
enums.ts
- β
Check
apiEndpointmatches the Django URL route exactly (including trailing slash) - β
Check the ViewSet is registered in
cidoc_data/urls.py - β Check the backend is running
- β
Check the Django serializer includes the field in
Meta.fields - β
Check the field
keyexactly matches the model field name (case-sensitive)
- β
Check
relationEndpointis correct (must be a valid API endpoint) - β Check the related entity's ViewSet supports search/list
- β
Check
navigable: trueis set on the class - β
Check
categoryis set to a valid category key
- β
Check
getOntologyClass("your_key")uses the correct registry key - β
Check the file is at
contribute/your-route/page.tsx - β
Check the contribute dashboard card's
routematches the page path
heritage_graph_ui/
βββ src/
βββ lib/ontology/
β βββ types.ts # TypeScript interfaces
β βββ enums.ts # 22 controlled vocabularies
β βββ registry.ts # 24 entity class definitions
β βββ index.ts # Barrel export
β
βββ components/
β βββ ontology-form.tsx # Auto-generates forms from registry
β βββ contribute/
β βββ step-wizard.tsx # Multi-step wizard container
β βββ step-indicator.tsx # Wizard progress bar
β βββ type-picker.tsx # Card-based type selector
β βββ entity-search.tsx # Autocomplete entity linker
β βββ assertion-wrapper.tsx # Provenance fields
β
βββ app/dashboard/
βββ contribute/
β βββ page.tsx # Contribute dashboard (21 intent cards)
β βββ person/page.tsx # Person form
β βββ deity/page.tsx # Deity form
β βββ structure/page.tsx # Structure wizard
β βββ ritual/page.tsx # Ritual wizard
β βββ festival/page.tsx # Festival form
β βββ guthi/page.tsx # Guthi form
β βββ location/page.tsx # Place form
β βββ source/page.tsx # Source form
β βββ event/page.tsx # Event form
β βββ period/page.tsx # Period form
β βββ tradition/page.tsx # Tradition form
β βββ iconography/page.tsx # Iconographic object form
β βββ monument/page.tsx # Monument form
β βββ calendar/page.tsx # Calendar system form
β βββ syncretism/page.tsx # Syncretic relationship form
β βββ kumari-tenure/page.tsx # Living Goddess tenure form
β βββ kumari-selection/page.tsx # Living Goddess selection form
β βββ kumari-retirement/page.tsx # Living Goddess retirement form
β βββ documentation/page.tsx # Documentation activity form
β βββ caste-group/page.tsx # Caste group form
β βββ assertion/page.tsx # Heritage assertion form
β
βββ knowledge/
βββ [domain]/page.tsx # Auto-generated data tables
ontology/
βββ HeritageGraph.yaml # Canonical LinkML schema (source of truth)
βββ Heritage.ttl # Generated OWL/Turtle
heritage_graph/apps/cidoc_data/
βββ models.py # Django models (must match field keys)
βββ serializers.py # DRF serializers
βββ views.py # ViewSets + search
βββ urls.py # API route registration
See also: FORMS.md for detailed form mechanics, AGENTS.md for full project context, ARCHITECTURE.md for system design.