Web app for Indian classical musicians (Carnatic and film repertoire): songs, media uploads, lookup tables (ragams, composers, movies, …), curated lists, and Firebase-based sharing. Built with SvelteKit, Tailwind CSS, and Firebase (Auth, Firestore, Storage).
Current release: v0.1.3 (see package.json). The running build shows v{version} in the site footer (injected at build time).
- Public landing:
/(SEO-friendly marketing page with feature sections and auth-aware CTA) - Login:
/login - Authenticated app home:
/dashboard - Song library:
/library(tabbed Carnatic / Film views) - Song lists:
/lists, list detail/lists/[listId], list-item editor/lists/[listId]/edit-song/[itemKey] - TODOs:
/todos(separate page from dashboard) - Lookups:
/lookupsand/lookups/[kind]
Authenticated pages use a shared app chrome with:
- left navigation
- global breadcrumbs
- mobile drawer navigation
- Library tabs: Carnatic and Film shown separately; kind dropdown removed.
- Library columns:
- Carnatic: Song title, Raagam, Composer
- Film: Song title, Movie, Music director, Actor
- Film decade options:
Vintage,Retro,Latest - Inline lookup creation: Add lookup attributes directly from song forms via popup modal.
- Lookups validation: Name/Title required, Description optional.
- Dashboard: Add Carnatic/Film actions at top, pinned lists prioritized.
- TODOs: Dedicated page with table view sorted by newest first.
- Lists: Tabbed All/Carnatic/Film list songs; maintain category-specific ordering.
- List item editing: Dedicated route for editing a list item’s full attributes.
- Node.js 20+ (LTS recommended)
- npm 9+
- A Firebase project with Firestore, Storage, and Authentication (Google sign-in; optional email/password)
In this project directory (where package.json lives):
npm install-
Copy the example environment file:
Windows (PowerShell or cmd):
copy .env.example .env
macOS / Linux:
cp .env.example .env
-
Edit
.envand set your Firebase web app values (allPUBLIC_*variables). These are not secret server keys; they identify your Firebase project in the browser. -
In the Firebase Console, enable Firestore, Storage, Authentication (Google provider), then deploy rules and indexes from this directory:
firebase login firebase use <your-project-id> firebase deploy --only firestore:rules,firestore:indexes,storage
Composite indexes for lookup search (
ownerId+ name/title fields, etc.) live infirestore.indexes.json—deploy them so searchable dropdowns work.Hosting (after a build):
npm run build firebase deploy --only hosting
firebase.jsonpoints hosting at the static build output (build/).
npm run devThe dev server defaults to http://localhost:5173 (Vite). Open that URL; sign in on /login once Firebase is configured.
npm run buildOutput is written to build/ (SvelteKit static adapter). The UI footer reads package.json → version via Vite (vite.config.ts).
npm run previewServes the contents of build/ so you can verify routing and assets before deploying.
npm run checkWatch mode:
npm run check:watch| Area | Collections / notes |
|---|---|
| Songs | carnaticSongs, filmSongs — associations use Firestore DocumentReference fields into lookup collections |
| Lookups | ragams, thaalams, composers, songTypes, teachers, movies, musicDirectors, actors, moods — each has CRUD under /lookups and can be added inline from song forms |
| Lists | songLists — items store songKind (carnatic | film) and songId |
| Sharing | carnaticSongGrants / filmSongGrants — recomputed from list visibility |
- Confirm
.envexists and everyPUBLIC_FIREBASE_*variable is set (no trailing spaces). - Restart the dev server after changing
.env.
- Deploy
firestore.rulesandstorage.rulesto the same Firebase project as your.envkeys. - In the console, confirm Authorized domains includes
localhost(and your production domain) under Authentication → Settings. - If Firestore logs
permission-deniedon snapshot listeners, deploy this repo’sfirestore.rules(firebase deploy --only firestore:rules). Rules must useresource.datafor fields you filter on (e.g.ownerId); usingget()on the same collection/document you’re querying often causes collection queries to be rejected even when individual reads would work. - Also confirm indexes:
firebase deploy --only firestore:indexesusing the same Firebase project asPUBLIC_FIREBASE_*in.env.
- Google sign-in uses
signInWithPopupfirst; Firebase closes the OAuth popup withwindow.close(). - Do not send
Cross-Origin-Opener-Policyfrom this app (includingsame-origin-allow-popups) — browsers still block that close in common cases.firebase.jsonand Vite intentionally omit COOP so the popup can finish. - If the popup is blocked, the client falls back to
signInWithRedirect.
- Deploy
firestore.indexes.json(firebase deploy --only firestore:indexes). - Current search/sort fields expected by lookups:
ragams.name,thaalams.name,composers.name,teachers.name,musicDirectors.name,actors.namesongTypes.categoryName,moods.moodName,movies.title
- SPA fallback is configured for static hosting (
firebase.jsonrewrites). Deploy the latestbuild/output afternpm run build.
- Use Chrome DevTools (or Edge) → Sources for breakpoints; Network for failed Firebase requests.
- Check the terminal for Vite compile errors and HMR updates.
node --inspect-brk node_modules/vite/bin/vite.js devThen attach your IDE’s debugger to the printed inspector URL.
| Path | Purpose |
|---|---|
src/ |
SvelteKit routes and components |
src/lib/models/schema.ts |
Firestore document shapes |
src/lib/appVersion.ts |
App version string from build (package.json) |
firestore.rules / firestore.indexes.json |
Firestore security and indexes |
storage.rules |
Cloud Storage security rules |
firebase.json |
Firebase Hosting / deploy config |
vite.config.ts |
Injects __APP_VERSION__ from package.json |
See package.json.