- Add Dependency type to internal/kc and extract silo/dependencies.json
from .kc files on commit
- Create ItemDependencyRepository with ReplaceForRevision, ListByItem,
and Resolve (LEFT JOIN against items table)
- Add GET /{partNumber}/dependencies and
GET /{partNumber}/dependencies/resolve endpoints
- Index dependencies in extractKCMetadata with SSE broadcast
- Pack real dependency data into .kc files on checkout
- Update PackInput.Dependencies from []any to []Dependency
Closes#143
Implements issue #142 — .kc checkout pipeline that repacks silo/ entries
with current DB state before serving downloads.
When a client downloads a .kc file via GET /api/items/{pn}/file/{rev},
the server now:
1. Reads the file from storage into memory
2. Checks for silo/ directory (plain .fcstd files bypass packing)
3. Repacks silo/ entries with current item_metadata + revision history
4. Streams the repacked ZIP to the client
New files:
- internal/kc/pack.go: Pack() replaces silo/ entries in ZIP, preserving
all non-silo entries (FreeCAD files, thumbnails) with original
compression and timestamps. HasSiloDir() for lightweight detection.
- internal/api/pack_handlers.go: packKCFile server helper, computeETag,
canSkipRepack lazy optimization.
ETag caching:
- ETag computed from revision_number + metadata.updated_at
- If-None-Match support returns 304 Not Modified before reading storage
- Cache-Control: private, must-revalidate
Lazy packing optimization:
- Skips repack if revision_hash matches and metadata unchanged since upload
Phase 2 packs: manifest.json, metadata.json, history.json,
dependencies.json (empty []). Approvals, macros, jobs deferred to
Phase 3-5.
Closes#142
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