Commit Graph
4 Commits
Author SHA1 Message Date
rin.kagamine b3f273942e feat: Phase 1 - multi-user auth foundation
- New auth.py module: users table, invite_codes table, JWT auth,
  password hashing (bcrypt), auth dependencies for FastAPI
- KITHARA_MODE=single|multi in .env (default: single)
- Single mode: no auth required, no login, user_id='default'
- Multi mode: full JWT auth, login/register endpoints, admin bootstrap
- Health endpoint now reports mode: {status, version, mode}
- Auth endpoints: POST /api/auth/login, /register, GET /me
- Admin endpoints: GET /admin/users, POST /admin/users,
  POST /admin/invites, GET /admin/invites,
  DELETE /admin/users/:id, PUT /admin/users/:id/role
- BYOK: PUT /api/auth/api-key for per-user Lyria keys
- DB migrations: user_id, shared, remixed_from columns on clips
- DB indexes for user-based and shared-content queries
- requirements.txt: added PyJWT and passlib[bcrypt]
- .env.example: documented all new config options
2026-05-31 11:59:07 -04:00
rin.kagamine 6ec5cf4b1b feat: env-configurable default ID3 tags for artist, album, genre
DEFAULT_ID3_ARTIST, DEFAULT_ID3_ALBUM, DEFAULT_ID3_GENRE in .env.
Clip-level metadata always takes priority. Env defaults fill in blanks.
Current defaults: Kagamine Rin / Kithara Studio / Hardcore Techno.

Also updated .env.example with all three new vars (commented out).
2026-05-31 11:21:14 -04:00
rin.kagamine 8ba7133269 feat: Add album artwork support
- Backend: artwork_filename column on clips table (auto-migration)
- Backend: PATCH /api/clips/{id}/artwork (upload image, 5MB limit)
- Backend: GET /api/clips/{id}/artwork (serve image with correct content-type)
- Backend: DELETE /api/clips/{id}/artwork (remove artwork file + null out DB)
- Backend: DELETE /api/clips/{id} now cascade-removes artwork file
- Frontend: Clip interface includes artwork_filename
- Frontend: Gallery ribbons show artwork thumbnail with hover overlay (play + upload)
- Frontend: Gallery tiles show artwork with hover overlay (play + upload)
- Frontend: DetailPanel shows full artwork with upload/change/remove controls
- Frontend: App.tsx handleUploadArtwork + handleRemoveArtwork handlers
- Storage: /data/artwork/ directory for image files
2026-05-29 18:27:28 -04:00
rin.kagamine 23672387e5 Fix Lyria API response parsing — audio in parts[1], not parts[0]
The Lyria API returns a candidates[].content.parts[] array where:
- parts[0] = text metadata (e.g. '<instrumental>')
- parts[1] = inlineData with the actual audio payload

Previous code only checked parts[0] for inlineData, which always failed
with 'No audio data in response'. Fixed by iterating all parts to find
the inlineData entry.

Successfully generated first real audio clip (lo-fi hip hop, 30s, 728KB MP3).

Also includes: .env.example, requirements updates, docker-compose fixes,
frontend vite config, logger setup.
2026-05-29 16:59:28 -04:00