Implements issue #141 — .kc server-side metadata integration Phase 1.
When a .kc file is uploaded, the server extracts silo/manifest.json and
silo/metadata.json from the ZIP archive and indexes them into the
item_metadata table. Plain .fcstd files continue to work unchanged.
Extraction is best-effort: failures are logged but do not block the upload.
New packages:
- internal/kc: ZIP extraction library (Extract, Manifest, Metadata types)
- internal/db: ItemMetadataRepository (Get, Upsert, UpdateFields,
UpdateLifecycle, SetTags)
New API endpoints under /api/items/{partNumber}:
- GET /metadata — read indexed metadata (viewer)
- PUT /metadata — merge fields into JSONB (editor)
- PATCH /metadata/lifecycle — transition lifecycle state (editor)
- PATCH /metadata/tags — add/remove tags (editor)
SSE events: metadata.updated, metadata.lifecycle, metadata.tags
Lifecycle transitions (Phase 1): draft→review→released→obsolete,
review→draft (reject).
Closes#141