| Metadata | Value |
|---|---|
| Status | Active |
| Version | 1.4.0 |
| Last Updated | 2026-09-10 |
| Author | Sangeetha Grantha Team |
| Document Type | Current guide |
This document outlines the canonical shared domain model for Sangita Grantha. It connects the product requirements (root PRD) to the schema and data structures used by:
modules/shared/domain).The goal is to keep one mental model of the Carnatic Krithi catalog across all surfaces.
| Entity | Description | Key Fields | Related Entities |
|---|---|---|---|
User |
Admin/editor/reviewer identity. | id, email, fullName, displayName, passwordHash, isActive, timestamps |
RoleAssignment, AuditLog, editorial fields on Krithi/KrithiLyricVariant/KrithiNotationVariant |
Role |
RBAC role definition. | code, name, capabilities (JSONB) |
RoleAssignment |
RoleAssignment |
Assignment of roles to users. | userId, roleCode, assignedAt |
User, Role |
Composer |
Canonical Carnatic composer. | id, name, nameNormalized, birthYear, deathYear, place, notes, timestamps |
Krithi |
Raga |
Canonical raga dictionary (melakarta + janya). | id, name, nameNormalized, melakartaNumber, parentRagaId, arohanam, avarohanam, notes, timestamps |
Krithi, KrithiRaga |
Tala |
Tala / rhythmic cycle definitions. | id, name, nameNormalized, angaStructure, beatCount, notes, timestamps |
Krithi, KrithiNotationVariant |
Deity |
Deity addressed by a Krithi. | id, name, nameNormalized, description, timestamps |
Krithi, Temple |
Temple |
Temple / kshetram metadata. | id, name, nameNormalized, city, state, country, primaryDeityId, latitude, longitude, notes, timestamps |
Krithi, Deity, TempleName |
TempleName |
Multilingual/alias temple names. | id, templeId, languageCode, scriptCode, name, normalizedName, isPrimary, source, createdAt |
Temple |
Krithi |
Core musical composition (sahitya + metadata). | id, title, incipit, titleNormalized, incipitNormalized, composerId, primaryRagaId, talaId, deityId, templeId, primaryLanguage, musicalForm, isRagamalika, workflowState, sahityaSummary, notes, createdByUserId, updatedByUserId, timestamps |
Composer, Raga, Tala, Deity, Temple, KrithiRaga, KrithiLyricVariant, KrithiSection, KrithiTag, KrithiNotationVariant |
KrithiRaga |
Mapping of a Krithi to one or more ragas. | krithiId, ragaId, orderIndex, section (raga_section_enum), notes |
Krithi, Raga |
KrithiLyricVariant |
Lyric variant in specific language/script/school. | id, krithiId, language, script, transliterationScheme, isPrimary, sampradayaId, variantLabel, sourceReference, lyrics, createdByUserId, updatedByUserId, timestamps |
Krithi, Sampradaya, KrithiLyricSection |
KrithiSection |
Structural sections of a Krithi. | id, krithiId, sectionType, orderIndex, label, notes, timestamps |
Krithi, KrithiLyricSection, KrithiNotationRow |
KrithiLyricSection |
Per-variant text per section. | id, lyricVariantId, sectionId, text, normalizedText, timestamps |
KrithiLyricVariant, KrithiSection |
KrithiNotationVariant |
Notation variant (swara/jathi) for Varnam/Swarajathi. | id, krithiId, notationType (SWARA/JATHI), talaId, kalai, eduppuOffsetBeats, variantLabel, sourceReference, isPrimary, createdByUserId, updatedByUserId, timestamps |
Krithi, Tala, KrithiNotationRow |
KrithiNotationRow |
Individual notation row within a section. | id, notationVariantId, sectionId, orderIndex, swaraText, sahityaText, talaMarkers, timestamps |
KrithiNotationVariant, KrithiSection |
Tag |
Controlled vocabulary element. | id, category, slug, displayNameEn, descriptionEn, createdAt |
KrithiTag |
KrithiTag |
Join between Krithi and Tag. | krithiId, tagId, source, confidence |
Krithi, Tag |
Sampradaya |
Lineage / school for patantharam. | id, name, type (PATHANTARAM/BANI/SCHOOL), description, createdAt |
KrithiLyricVariant |
ImportSource |
Origin of imported Krithi data. | id, name, baseUrl, description, contactInfo, createdAt |
ImportedKrithi |
ImportedKrithi |
Staging record for imported compositions. | id, importSourceId, sourceKey, rawTitle, rawLyrics, rawComposer, rawRaga, rawTala, rawDeity, rawTemple, rawLanguage, parsedPayload (JSONB), importStatus, mappedKrithiId, reviewerUserId, reviewerNotes, reviewedAt, createdAt |
ImportSource, Krithi, User |
AuditLog |
Immutable record of admin/editor actions. | id, actorUserId, actorIp, action, entityTable, entityId, diff (JSONB), metadata (JSONB), changedAt |
All mutable entities |
Notes:
Krithi is the central root for most flows (search, browse, edit).KrithiLyricVariant + KrithiSection + KrithiLyricSection allow rich
sectioned lyrics per language/script/sampradaya.KrithiNotationVariant + KrithiNotationRow support notation for Varnam
and Swarajathi compositions (swara/jathi notation).Tag/KrithiTag and Sampradaya provide thematic and lineage
classification.musicalForm on Krithi is KRITHI, VARNAM, SWARAJATHI, or UNESTABLISHED. Unestablished is not a fourth musical form for directories/facets; V1 public catalogue excludes those rows, V2 includes published unclassified compositions without a form badge.Database enums are mirrored in KMP DTOs; values and semantics must stay aligned.
| Enum (DB) | Enum (KMP) | Values | Usage |
|---|---|---|---|
workflow_state_enum |
WorkflowStateDto |
draft, in_review, published, archived |
Editorial lifecycle of Krithis |
language_code_enum |
LanguageCodeDto |
sa, ta, te, kn, ml, hi, en |
Composition & variant languages |
script_code_enum |
ScriptCodeDto |
devanagari, tamil, telugu, kannada, malayalam, latin |
Scripts for lyrics/translit |
raga_section_enum |
RagaSectionDto |
pallavi, anupallavi, charanam, other |
Optional raga–section mapping |
import_status_enum |
ImportStatusDto |
pending, in_review, mapped, rejected, discarded |
Import review lifecycle |
musical_form_enum |
MusicalFormDto |
KRITHI, VARNAM, SWARAJATHI, UNESTABLISHED |
Form classification; UNESTABLISHED is unknown, not a form choice |
Mapping rules:
draft → DRAFT).kotlinx.serialization with string values matching
the DB enums.High-level relationships between core entities:
Krithi → Composer: many-to-one via composerId.Krithi → Raga / KrithiRaga:
primaryRagaId for the main raga (non-ragamalika).KrithiRaga rows for ragamalika and richer raga mapping.Krithi → Tala: optional talaId.Krithi → Deity / Temple: optional associations.Krithi → KrithiLyricVariant: one-to-many.
(krithiId, language, script).Krithi → KrithiSection: one-to-many.
KrithiLyricVariant → KrithiLyricSection: one-to-many.
KrithiSection → KrithiLyricSection:
Krithi → KrithiNotationVariant: one-to-many.
KrithiNotationVariant → KrithiNotationRow: one-to-many.
KrithiSection → KrithiNotationRow:
Krithi ↔ Tag: many-to-many via KrithiTag.
KrithiLyricVariant → Sampradaya:
sampradayaId plus free-form variantLabel.Temple → TempleName: one-to-many.
TempleName.isPrimary marks canonical name per language/script.ImportSource → ImportedKrithi: one-to-many.ImportedKrithi → Krithi:
mappedKrithiId once canonicalized.ImportedKrithi → User:
reviewerUserId for mapping/rejection decisions.User ↔ Role ↔ RoleAssignment:
AuditLog → all mutating entities:
entityTable + entityId identify the affected row.action and diff capture what changed.These relationships should be reflected consistently in:
../diagrams/erd.md).modules/shared/domain).modules/backend/dal).database/migrations/ and documented in
database/SANGITA_SCHEMA_OVERVIEW.md.modules/shared/domain (e.g. KrithiDto,
KrithiLyricVariantDto, TagDto) form the public and admin API
contracts.Technical constraints:
kotlinx.datetime.Instant in KMM, TIMESTAMPTZ/DATE in
Postgres; avoid Java legacy date/time classes.kotlin.uuid.Uuid serialized as strings; UUID columns in DB.Process:
../diagrams/erd.md).../api/*.md).These rules encode the musical-domain correctness (lakshana) that all surfaces — data entry, extraction/enrichment, validation, and generated SQL/seed data — must respect. They complement the structural model above: the schema defines what can be stored; these rules define what is musically valid. Prefer musicological accuracy over convenience — an incorrect raga scale or tala anga is a data-quality defect, not a cosmetic one.
musical_form_enum distinguishes KRITHI, VARNAM, SWARAJATHI, and UNESTABLISHED. The first three have different structural requirements; validation must not treat one form’s sections as another’s. UNESTABLISHED means the classification is not known — it is not a fourth form in directories, and a specific form facet must not match it.
CHARANAM rows even when a
source omits a heading between them.KrithiNotationVariant / KrithiNotationRow.KrithiRaga rows (orderIndex, optional section) and set
Krithi.isRagamalika = true.primaryRagaId is insufficient for a ragamalika — never collapse
a ragamalika down to one raga.KrithiNotationVariant / KrithiNotationRow) except where explicitly
aligned — as in Varnams, where swara and sahitya are positionally tied.notationType (SWARA/JATHI) and tala/kalai/eduppu metadata on the
notation variant; do not infer them from lyric text.melakartaNumber,
parentRagaId, arohanam/avarohanam). Any generated scale must be valid
for the named raga.angaStructure,
beatCount); generated tala data must have correct angas.variantLabel for finer distinctions?TempleName.isPrimary?These should be resolved before significantly expanding the public API surface or ingesting very large, diverse data sets.
The composition remains the central entity, with krithi_ragas preserving ordered membership and lyric variants preserving language/script/source identity. UNESTABLISHED is an explicit unknown classification; V1 public reads exclude it and V2 includes it when published.
The schema guide and actual Flyway migrations define persistence; API DTOs need not mirror every internal table.