| Metadata | Value |
|---|---|
| Status | Active |
| Version | 1.1.0 |
| Last Updated | 2026-09-10 |
| Author | Sangeetha Grantha Team |
| Document Type | Decision record |
[!NOTE] Decision record: preserve the original rationale and check its decision/supersession status. Current runtime guidance is in system architecture and Flyway migrations.
Deciders: Platform Team, Backend Team
The “Music-Aware Graph Explorer” feature requires the ability to visualize and traverse relationships between musical entities (Krithis, Composers, Ragas, Talas, Deities, Kshetras, Tags). We needed to decide on the underlying data store and architecture to support:
The primary choice was between introducing a dedicated graph database (Neo4j) as a projection, or leveraging the existing relational database (PostgreSQL) with recursive queries.
We have decided to use PostgreSQL with Recursive CTEs as the backend data source, coupled with Cytoscape.js for client-side visualization.
We formally reject the proposal to introduce Neo4j Community Edition at this stage.
Using PostgreSQL avoids the operational burden of managing a second database system. There is no need for:
The team has deep expertise in PostgreSQL and SQL. Introducing Cypher (Neo4j’s query language) would increase the cognitive load and onboarding time for new developers.
Our analysis indicates that PostgreSQL is sufficient for our current and projected scale:
Neo4j Enterprise is expensive, and Community Edition lacks critical features like clustering and hot backups. PostgreSQL is already provisioned and incurs no marginal cost.
The implementation follows a “Client-Side Graph” model:
┌─────────────────┐
│ Admin Web UI │
│ (Cytoscape.js) │
└────────┬────────┘
│ JSON Graph DTOs (Nodes/Edges)
┌────────▼────────┐
│ GraphService │
│ (Ktor Backend) │
└────────┬────────┘
│ Recursive SQL
┌────────▼────────┐
│ PostgreSQL │
└─────────────────┘
Nodes and Edges are derived directly from relative tables:
Nodes:
Krithi, Composer, Raga, Tala, Deity, Kshetram, Tag.UUID (Matches PostgreSQL Primary Key).Relationships:
(Krithi)-[:COMPOSED_BY]->(Composer)(Krithi)-[:IN_RAGA]->(Raga)(Krithi)-[:IN_TALA]->(Tala)(Raga)-[:JANYA_OF]->(Raga)We will use Recursive Common Table Expressions (WITH RECURSIVE) to perform traversals.
Example Depth-N Traversal Logic:
krithi_ragas, composers, etc.) to find connected entities.depth reaches the requested limit (e.g., 3).