Sangeetha-Grantha

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Sangeetha Grantha is a digital compendium of Carnatic classical music compositions (Krithis). It’s a multi-module monorepo with:

This is a Carnatic Music Krithi Analyser project using: Kotlin backend (Exposed ORM), React/TypeScript frontend, Python data pipeline scripts, PostgreSQL database. Always verify changes compile/build across all three layers before committing.

Essential Commands

Development Workflow (via Makefile)

make dev            # Full stack via Docker Compose (DB + Backend + Frontend + Extraction)
make dev-down       # Stop dev stack
make db             # Start database only
make db-reset       # Drop → create → Flyway migrate (schema V__ + reference data R__)
make seed-dev       # Dev-only sample content (reference data now ships via R__ repeatables)
make migrate        # Run pending migrations (Flyway)
make migrate-status # Show Flyway migration status
make bootstrap-admin # Provision the admin user (argon2id); needs ADMIN_EMAIL / ADMIN_PASSWORD
make test           # Backend unit tests
make test-integration # Backend integration tests (Testcontainers)
make test-frontend  # Frontend tests
make steel-thread   # End-to-end steel thread test
make check-docs     # Validate documentation links
make agent-evals    # Deterministic agent-config evals (CLAUDE.md, skills, hooks)
make clean          # Remove all containers and volumes

Build & Test

# Backend build (produces fat JAR)
./gradlew :modules:backend:api:build

# Backend tests
./gradlew :modules:backend:api:test

# Frontend (from modules/frontend/sangita-admin-web)
bun install
bun run dev      # development server on port 5001
bun run build    # production build

Gradle Tasks

./gradlew :modules:backend:api:run        # Run backend
./gradlew :modules:backend:api:runDev     # Run backend in dev mode

Verifying your work

Run the matching check before reporting a task complete, and paste the command output. Do not skip, delete, or weaken a failing test to make a task pass. If a test fails, fix the code, not the test — unless the Plan says the test itself is wrong. Deliberate test edits (new assertions, fixture changes that are themselves tests) require SANGITA_ALLOW_TEST_EDITS=1; 0/false do not opt out. Fixtures and src/test/setup.ts are not blocked.

Architecture

Module Structure

flowchart TB
  subgraph repo["modules"]
    direction TB

    subgraph shared["shared"]
      direction TB
      DOM["domain — @Serializable DTOs"]
      PRES["presentation — Rasika Compose UI"]
      MDATA["mobile-data — V2 client, storage, fixtures"]
    end

    subgraph mobile["mobile"]
      direction TB
      AND[androidApp]
      IOS[iosApp]
    end

    subgraph backend["backend"]
      direction TB
      API["api — Ktor AppKt"]
      DAL["dal — Exposed"]
      TS[test-support]
    end

    WEB["frontend/sangita-admin-web"]
  end

Key Patterns

Backend (Kotlin + Ktor)

Frontend (React + TypeScript)

Database

Critical Rules

  1. Flyway is the only migration engine (ADR-013) - always go through make migrate or make db-reset; never Liquibase, never ad-hoc SQL executors, never custom migration runners. Rationale for the 2026-06 switch: the previous custom tooling had forked into two diverging implementations (Python db-migrate for dev/prod, Kotlin MigrationRunner for tests) with incompatible tracking tables and no checksum validation on the test path; Flyway gives one standards-based engine for Kotlin (JVM API in Testcontainers), Python (CLI), Make, and CI, plus repeatable migrations for reference seed data. See application_documentation/02-architecture/decisions/ADR-013-db-migration-with-flyway.md.
  2. Dependency versions - use gradle/libs.versions.toml, no hardcoded versions in build.gradle.kts
  3. Audit logging - all backend mutations must log to AUDIT_LOG table
  4. Commit format - every commit must include Ref: application_documentation/... line
  5. Version updates require documentation sync - update any files that reference current-versions.md:
    • application_documentation/00-meta/current-versions.md
    • application_documentation/02-architecture/tech-stack.md
    • application_documentation/00-onboarding/getting-started.md

Things agents get wrong

Musicological Domain Rules

Carnatic correctness (lakshana) — musical forms (KRITHI/VARNAM/SWARAJATHI section requirements), Ragamalika, notation-vs-lyrics, and raga/tala/terminology rules — is documented in Domain Model §6. Treat it as a correctness contract for data entry, extraction, validation, and any generated SQL/seed data.

Claude Code Assets

This file stays canonical for cross-cutting rules; layer-specific conventions live in project skills so they load only when relevant. Don’t duplicate content between the two — link.

Layer Skills (.claude/skills/)

Load the matching skill before working in a layer instead of re-deriving its conventions:

Cursor loads the same skills via symlinks under .cursor/skills/. Canonical files stay in .claude/skills/. Do not copy the bodies into .cursor/ or .cursorrules.

Slash Commands (.claude/commands/)

/dev-start, /db-reset, /test-all, /steel-thread, /new-migration, /spec-from-track, /plan-from-spec, /commit (follows this repo’s commit conventions), /Sangeetha-Krithi-Analyser (krithi section analysis). Cursor mirrors these files in .cursor/commands/.

Specialist Subagents (.claude/agents/)

Delegated to on demand (not loaded every turn): kotlin-backend-engineer, postgres-engineer, python-engineer, and carnatic-musicologist (reviews krithi data for musicological correctness — useful for bulk-import batches). They defer to this file and the domain model for shared rules and add domain judgment on top.

Dev Servers & Preview (.claude/launch.json)

Named launch configs exist for frontend (port 5001), backend (8080), and full-stack (make dev). Start dev servers through the browser-preview tooling with these names — never as raw background Bash — then verify changes in the preview (console/network/page checks) rather than asking the user to check manually.

Cursor (.cursor/)

.cursorrules and .cursor/rules/project.mdc are pointers at this file. Git naming is .cursor/rules/git-conventions.mdc. Layer skills and slash commands are symlinks to .claude/skills/ and .claude/commands/ so they cannot drift. Edit-time hooks are wired in .cursor/hooks.json and run the same .claude/hooks/*.py scripts as Claude Code. Extra Cursor-only skills: agentic-prompt-optimizer, sangeetha-krithi-analyser.

Conductor Workflow

Work is tracked in conductor/tracks/TRACK-<ID>-<slug>.md files. Check conductor/tracks.md for active tracks before starting work. New work uses Intent → Spec → Plan on the track (see conductor-track-manager). Do not implement until Plan Status is Accepted. PR review follows REVIEW.md.

Toolchain & Versions

For current toolchain and library versions, see Current Versions.

Default Ports

Key Documentation

Debugging Guidelines

For CORS/auth issues, check VITE_API_BASE_URL and the frontend proxy first, not TOML. Use committed *.env.example / .env.*.example templates for variable names. Never Read gitignored .env files.

## Data & Migrations Always verify seed data populates junction tables (e.g., krithi_ragas), not just foreign key columns on the main entity. After any seed/migration, confirm data appears correctly through the full stack (DB → API → UI).

Git & Commits

Follow commit-policy strictly. Cursor agents also load .cursor/rules/git-conventions.mdc.

Infrastructure & Docker

When debugging Docker/infrastructure issues: check Dockerfile base image versions match project requirements, verify volume mount paths for the current DB version, and ensure Gradle caches are cleared before assuming code changes aren’t taking effect.