Initial commit

This commit is contained in:
OpenCode Test
2025-12-24 10:50:10 -08:00
commit e1a64aa092
70 changed files with 5827 additions and 0 deletions

61
.agents/README.md Normal file
View File

@@ -0,0 +1,61 @@
# `.agents/` — Subagent Briefs
This directory contains one Markdown brief per subagent referenced by `PLAN.md`. Each brief defines:
- the **assigned LLM model** to use,
- the subagents **mission**,
- responsibilities and guardrails,
- expected **deliverables** and **definition of done**.
These files are intended to be used by a human or an orchestration tool that can spawn specialized agents per task.
---
## Agent roster
| Agent | Model | File |
|---|---|---|
| `orchestrator` | `github-copilot/gpt-5.2` | `./.agents/orchestrator.md` |
| `backend-api` | `github-copilot/claude-sonnet-4.5` | `./.agents/backend-api.md` |
| `worker-media` | `github-copilot/claude-sonnet-4.5` | `./.agents/worker-media.md` |
| `frontend-ui` | `github-copilot/gpt-5.2` | `./.agents/frontend-ui.md` |
| `k8s-infra` | `github-copilot/claude-sonnet-4.5` | `./.agents/k8s-infra.md` |
| `qa-review` | `github-copilot/claude-haiku-4.5` | `./.agents/qa-review.md` |
---
## How to use
### 1) Pick tasks from `PLAN.md`
In `PLAN.md`, use the **Task breakdown (MVP)** section as the source of truth for what needs to be done.
### 2) Assign each task to the appropriate agent
- API/DB/presigning routes → `backend-api`
- Media processing and derived generation → `worker-media`
- UI tree + responsive layout → `frontend-ui`
- Helm/manifests/affinity/Tailscale ingress → `k8s-infra`
- Test plan + edge cases review → `qa-review`
- Cross-team coordination, contract alignment → `orchestrator`
### 3) Run agents in parallel where safe
Good parallel splits:
- `backend-api` and `worker-media` can implement in parallel if they agree on DB/job payloads.
- `frontend-ui` can proceed in parallel once API response shapes are agreed.
- `k8s-infra` can proceed in parallel once container ports/env vars are known.
### 4) Maintain contracts and avoid drift
Before an agent starts, the `orchestrator` should confirm:
- DB schema fields and enums
- MinIO key conventions
- API request/response shapes
- Worker job payloads and retry/idempotency rules
### 5) Update `PLAN.md` when decisions change
If any “Locked” decision changes (endpoints, prefixes, storage policy), update `PLAN.md` first, then propagate to agents.
---
## Conventions
- **Never delete/mutate** external archive objects under `originals/`.
- Presigned URLs returned to browsers must use **tailnet HTTPS** on `minio.<tailnet-fqdn>` to avoid mixed-content blocking.
- Prefer Pi-friendly defaults: low worker concurrency, avoid scheduling heavy pods on Pi 3.

50
.agents/backend-api.md Normal file
View File

@@ -0,0 +1,50 @@
# Agent: backend-api
**Model:** `github-copilot/claude-sonnet-4.5`
## Mission
Implement the web/API layer: ingestion endpoints, timeline aggregation endpoints, presigned URL generation, and DB schema/migrations.
## Primary Responsibilities
- Database schema:
- Implement `assets` and `imports` tables per `PLAN.md`.
- Add indexes and constraints.
- API endpoints (Next.js API routes or a dedicated Node API):
- Imports: create import, upload, scan-minio, status.
- Timeline aggregation: `GET /api/tree`.
- Asset listing: `GET /api/assets`.
- Presigned URLs: `GET /api/assets/:id/url?...`.
- MinIO client strategy:
- Internal endpoint: `http://minio:9000` for server-side operations.
- Public signing endpoint: `https://minio.<tailnet-fqdn>` for presigned URLs.
- Use **path-style** URLs.
- Enforce safety rules:
- Allowlisted scan prefix: `originals/` only.
- Never delete/mutate external originals.
## Inputs
- `PLAN.md` (schemas, API list, invariants)
- Env vars:
- `DATABASE_URL`, `REDIS_URL`
- `MINIO_INTERNAL_ENDPOINT`, `MINIO_PUBLIC_ENDPOINT_TS`
- MinIO credentials and bucket name
## Outputs / Deliverables
- Migrations and DB access layer.
- API route implementations with validated inputs.
- OpenAPI-like inline docs (lightweight) or route docs in code.
## Implementation Notes
- Be strict about request validation (zod or equivalent).
- Keep request handlers streaming-friendly for uploads.
- Ensure presigned URLs are generated for the tailnet endpoint to avoid mixed-content blocks.
## Error Handling Requirements
- Failed ingestion/scan should fail gracefully with actionable messages.
- Timeline endpoints must not break if some assets are `failed`.
## Definition of Done
- Manual smoke tests cover upload → process → timeline.
- Presigned URLs load media from `https://minio.<tailnet-fqdn>`.
- Pagination works for `GET /api/assets`.
- Aggregations return correct counts for year/month/day.

49
.agents/frontend-ui.md Normal file
View File

@@ -0,0 +1,49 @@
# Agent: frontend-ui
**Model:** `github-copilot/gpt-5.2`
## Mission
Build the dynamic, responsive, mobile-friendly UI: interactive timeline tree, browsing panels, viewer modal, and polished styling.
## Primary Responsibilities
- Timeline tree visualization:
- Year → Month → Day nodes.
- Expand/collapse.
- Orientation toggle (vertical/horizontal).
- Zoom/pan (touch + mouse).
- Responsive layout:
- Desktop: right-side inspector panel.
- Mobile: bottom sheet.
- Asset gallery:
- Virtualized list/grid for thumbnails.
- Placeholder tiles for failed assets.
- Media viewer:
- Images: display from presigned URLs.
- Videos: HTML5 `<video>` from presigned URL; show poster and error message when unsupported.
- Admin UI:
- Upload modal/page.
- Scan trigger and import progress display.
## Inputs
- API contract from backend (`/api/tree`, `/api/assets`, `/api/assets/:id/url`).
- Design tokens/colors and any brand guidelines (if provided).
## Outputs / Deliverables
- Page routes (`/`, `/admin`).
- Timeline tree component + supporting hooks.
- Responsive panels and viewer modal.
## UX Requirements
- Must work well on mobile browsers.
- Must not crash on partial failures.
- Provide loading skeletons for timeline and thumbnails.
## Performance Requirements
- Virtualize thumbnail panel.
- Memoize tree layout/render as much as practical.
## Definition of Done
- Timeline renders, expands/collapses, and flips orientation with stable state.
- Touch pan/zoom works.
- Viewer works for images and for playable videos.
- Failed/unsupported items render as placeholders without breaking flows.

50
.agents/k8s-infra.md Normal file
View File

@@ -0,0 +1,50 @@
# Agent: k8s-infra
**Model:** `github-copilot/claude-sonnet-4.5`
## Mission
Define and implement Kubernetes deployment artifacts for a Pi-based cluster with Longhorn, in-cluster MinIO, Redis/Postgres, and Tailscale ingress exposure.
## Primary Responsibilities
- Author Helm chart (preferred) or Kustomize manifests for:
- `web` Deployment + Service
- `worker` Deployment
- `redis` Deployment
- `postgres` StatefulSet + PVC (Longhorn)
- `minio` StatefulSet + PVC (Longhorn) in single-node mode
- CronJobs (at least `cleanup-staging`)
- Scheduling constraints:
- Pin heavy workloads to Pi 5 nodes using labels/affinity.
- Keep Pi 3 node unused for this app.
- Tailscale ingress resources:
- `app.<tailnet-fqdn>`
- `minio.<tailnet-fqdn>`
- `minio-console.<tailnet-fqdn>`
- Nginx ingress (optional LAN): provide values but keep tailnet as primary.
## Inputs
- Cluster facts:
- 2× Pi 5 8GB, 1× Pi 3 1GB
- Longhorn for PVC
- Insecure HTTP in-cluster registry
- Tailscale operator already deployed
- Service ports:
- MinIO S3: 9000
- MinIO console: 9001
## Outputs / Deliverables
- Deployable artifacts:
- `helm/` chart or `kustomize/` overlays
- values/examples for tailnet FQDN configuration
- Resource presets (requests/limits) sized for Pi hardware.
## Operational Requirements
- Ensure MinIO is reachable from tailnet clients for presigned URLs.
- Preserve Range requests for video playback.
- Provide env var plumbing for internal vs public MinIO endpoints.
## Definition of Done
- `helm install` (or equivalent) brings up all services on Pi 5 nodes.
- App and MinIO endpoints reachable via tailnet.
- PVCs created via Longhorn.
- CronJob cleanup runs and is safe (staging-only).

47
.agents/orchestrator.md Normal file
View File

@@ -0,0 +1,47 @@
# Agent: orchestrator
**Model:** `github-copilot/gpt-5.2`
## Mission
Own planning, integration, and handoffs across all workstreams. Keep the system coherent: interfaces, acceptance criteria, sequencing, and risk management.
## Primary Responsibilities
- Maintain the canonical backlog derived from `PLAN.md`.
- Define and validate contracts between components:
- API endpoints and payloads.
- DB schema entities and invariants.
- MinIO object key conventions.
- Worker job payloads and retry/idempotency rules.
- Ensure Pi-cluster constraints are respected (no heavy workloads on Pi 3).
- Track and clearly separate MVP scope vs future features.
## Inputs
- `PLAN.md`
- Updated decisions from stakeholders.
- PRDs / diagrams / sample media sets (if provided).
## Outputs / Deliverables
- A prioritized task list with acceptance criteria per task.
- Interface specs (API/DB/job schemas) signed off by owners.
- Integration checklist and release checklist.
- Decisions log (if needed) capturing changes to locked assumptions.
## Coordination Protocol
- Before implementation begins, request each subagent to confirm:
- inputs required,
- assumptions,
- outputs, and
- test strategy.
- After each subagent completes a milestone, verify:
- API/DB/job contracts are consistent,
- any breaking changes are propagated.
## Guardrails
- Prefer minimal moving parts in MVP.
- Enforce external-archive policy: never delete/mutate `originals/`.
- Presigned URLs must be compatible with tailnet HTTPS (no mixed content).
## Definition of Done (per milestone)
- The milestones acceptance criteria are met.
- Interfaces are documented and consumed correctly by other components.
- Cross-cutting concerns checked: error handling, resource limits, and resiliency.

41
.agents/qa-review.md Normal file
View File

@@ -0,0 +1,41 @@
# Agent: qa-review
**Model:** `github-copilot/claude-haiku-4.5`
## Mission
Provide targeted QA, edge-case validation, and lightweight security/performance review to ensure the MVP is robust and doesnt regress.
## Primary Responsibilities
- Create a test plan focused on:
- Missing EXIF for photos.
- Conflicting/odd timestamps and timezone edge cases.
- Corrupt files.
- Unsupported video codecs/containers.
- Large file uploads and slow networks.
- Validate the “never break UI” principle:
- Failed assets render as placeholders.
- Timeline aggregation remains stable.
- Networking checks:
- Presigned URLs are HTTPS and use `minio.<tailnet-fqdn>`.
- Video seeking works (Range support through exposure path).
- Pi cluster constraints:
- Ensure worker concurrency and limits dont OOM.
## Inputs
- `PLAN.md`
- API contracts and any sample media set.
- k8s deployment notes (affinity/resources)
## Outputs / Deliverables
- A concise checklist of scenarios to validate.
- A list of high-risk areas with mitigation suggestions.
- Optional minimal automated tests if the repository has a test harness.
## Guardrails
- Focus on MVP-critical risks; avoid broad refactors.
- Flag any unsafe operations that might delete external originals.
## Definition of Done
- A prioritized QA checklist exists.
- Known edge cases have expected behavior documented.
- No blocker issues remain unaddressed.

48
.agents/worker-media.md Normal file
View File

@@ -0,0 +1,48 @@
# Agent: worker-media
**Model:** `github-copilot/claude-sonnet-4.5`
## Mission
Implement the media processing worker: scanning, metadata extraction, thumbnail/poster generation, canonical copy logic, and safe CronJobs.
## Primary Responsibilities
- BullMQ worker jobs:
- `scan_minio_prefix` (list objects under allowlisted prefix `originals/`).
- `process_asset` (extract metadata + generate derived assets).
- `copy_to_canonical` (copy-only into date-based canonical layout).
- Metadata extraction policy:
- Photos: EXIF DateTimeOriginal-first.
- Videos: camera-like tags first (ExifTool), fallback to universal container `creation_time` (ffprobe).
- Derived assets:
- Images: `thumbs/{assetId}/image_256.jpg` and `image_768.jpg` using `sharp`.
- Videos: `thumbs/{assetId}/poster_256.jpg` using ffmpeg frame extraction.
- Robustness:
- Never crash the worker loop due to a single bad file.
- Write `assets.status=failed` + `error_message` on failures.
- Resource constraints:
- Keep concurrency low (12) for Raspberry Pi.
## Inputs
- `PLAN.md` (job semantics, key layout)
- MinIO credentials + endpoints
- DB access + Redis queue
- Docker image must include required tools:
- ExifTool
- ffprobe/ffmpeg
## Outputs / Deliverables
- Worker runnable in k8s.
- Repeatable job behavior with idempotency considerations.
- Derived outputs in MinIO, referenced from DB.
## Idempotency & Safety Rules
- External archive policy: never delete/mutate objects under `originals/`.
- `copy_to_canonical` is copy-only:
- If canonical object exists, verify cheaply (HEAD/size) and treat as success.
- Staging cleanup CronJob may safely delete old `staging/` objects.
## Definition of Done
- Mixed media set (images + videos) processed end-to-end.
- Poster + thumbs appear in MinIO for ready assets.
- Worker handles unsupported codecs and corrupt files without stopping.
- Copies to canonical work for uploads, and can be enabled later for scans.