From e1a64aa09277b4562caa8867cc405b2550d7bbb9 Mon Sep 17 00:00:00 2001 From: OpenCode Test Date: Wed, 24 Dec 2025 10:50:10 -0800 Subject: [PATCH] Initial commit --- .agents/README.md | 61 ++ .agents/backend-api.md | 50 ++ .agents/frontend-ui.md | 49 ++ .agents/k8s-infra.md | 50 ++ .agents/orchestrator.md | 47 ++ .agents/qa-review.md | 41 ++ .agents/worker-media.md | 48 ++ .dockerignore | 6 + .gitignore | 6 + PLAN.md | 450 ++++++++++++ README.md | 221 ++++++ apps/web/Dockerfile | 38 + apps/web/app/admin/page.tsx | 8 + apps/web/app/api/assets/[id]/url/route.ts | 94 +++ apps/web/app/api/assets/route.ts | 114 +++ apps/web/app/api/healthz/route.ts | 3 + .../app/api/imports/[id]/scan-minio/route.ts | 66 ++ apps/web/app/api/imports/[id]/status/route.ts | 65 ++ apps/web/app/api/imports/[id]/upload/route.ts | 108 +++ apps/web/app/api/imports/route.ts | 37 + apps/web/app/api/tree/route.ts | 137 ++++ apps/web/app/components/MediaPanel.tsx | 291 ++++++++ apps/web/app/components/TimelineTree.tsx | 368 ++++++++++ apps/web/app/layout.tsx | 14 + apps/web/app/page.tsx | 40 + apps/web/next-env.d.ts | 6 + apps/web/next.config.mjs | 13 + apps/web/package.json | 21 + apps/web/tsconfig.json | 26 + apps/worker/Dockerfile | 35 + apps/worker/package.json | 19 + apps/worker/src/index.ts | 58 ++ apps/worker/src/jobs.ts | 616 ++++++++++++++++ apps/worker/tsconfig.json | 7 + argocd/tline-application.yaml | 26 + bun.lock | 693 ++++++++++++++++++ helm/tline/Chart.yaml | 6 + helm/tline/templates/_helpers.tpl | 151 ++++ helm/tline/templates/configmap.yaml.tpl | 17 + .../cronjob-cleanup-staging.yaml.tpl | 64 ++ .../templates/ingress-tailscale.yaml.tpl | 120 +++ .../templates/job-ensure-bucket.yaml.tpl | 64 ++ helm/tline/templates/job-migrate.yaml.tpl | 51 ++ helm/tline/templates/minio.yaml.tpl | 107 +++ helm/tline/templates/postgres.yaml.tpl | 100 +++ helm/tline/templates/redis.yaml.tpl | 57 ++ helm/tline/templates/secret.yaml.tpl | 32 + .../service-minio-tailscale-console.yaml.tpl | 27 + .../service-minio-tailscale-s3.yaml.tpl | 27 + helm/tline/templates/web.yaml.tpl | 89 +++ helm/tline/templates/worker.yaml.tpl | 57 ++ helm/tline/values.yaml | 254 +++++++ opencode.jsonc | 111 +++ package.json | 28 + packages/config/package.json | 12 + packages/config/src/index.ts | 25 + packages/config/tsconfig.json | 7 + packages/db/migrations/0001_init.sql | 88 +++ .../0002_assets_duration_and_indexes.sql | 16 + packages/db/package.json | 19 + packages/db/src/index.ts | 23 + packages/db/src/migrate.ts | 43 ++ packages/db/tsconfig.json | 7 + packages/minio/package.json | 17 + packages/minio/src/index.ts | 97 +++ packages/minio/tsconfig.json | 7 + packages/queue/package.json | 17 + packages/queue/src/index.ts | 128 ++++ packages/queue/tsconfig.json | 7 + tsconfig.base.json | 20 + 70 files changed, 5827 insertions(+) create mode 100644 .agents/README.md create mode 100644 .agents/backend-api.md create mode 100644 .agents/frontend-ui.md create mode 100644 .agents/k8s-infra.md create mode 100644 .agents/orchestrator.md create mode 100644 .agents/qa-review.md create mode 100644 .agents/worker-media.md create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 PLAN.md create mode 100644 README.md create mode 100644 apps/web/Dockerfile create mode 100644 apps/web/app/admin/page.tsx create mode 100644 apps/web/app/api/assets/[id]/url/route.ts create mode 100644 apps/web/app/api/assets/route.ts create mode 100644 apps/web/app/api/healthz/route.ts create mode 100644 apps/web/app/api/imports/[id]/scan-minio/route.ts create mode 100644 apps/web/app/api/imports/[id]/status/route.ts create mode 100644 apps/web/app/api/imports/[id]/upload/route.ts create mode 100644 apps/web/app/api/imports/route.ts create mode 100644 apps/web/app/api/tree/route.ts create mode 100644 apps/web/app/components/MediaPanel.tsx create mode 100644 apps/web/app/components/TimelineTree.tsx create mode 100644 apps/web/app/layout.tsx create mode 100644 apps/web/app/page.tsx create mode 100644 apps/web/next-env.d.ts create mode 100644 apps/web/next.config.mjs create mode 100644 apps/web/package.json create mode 100644 apps/web/tsconfig.json create mode 100644 apps/worker/Dockerfile create mode 100644 apps/worker/package.json create mode 100644 apps/worker/src/index.ts create mode 100644 apps/worker/src/jobs.ts create mode 100644 apps/worker/tsconfig.json create mode 100644 argocd/tline-application.yaml create mode 100644 bun.lock create mode 100644 helm/tline/Chart.yaml create mode 100644 helm/tline/templates/_helpers.tpl create mode 100644 helm/tline/templates/configmap.yaml.tpl create mode 100644 helm/tline/templates/cronjob-cleanup-staging.yaml.tpl create mode 100644 helm/tline/templates/ingress-tailscale.yaml.tpl create mode 100644 helm/tline/templates/job-ensure-bucket.yaml.tpl create mode 100644 helm/tline/templates/job-migrate.yaml.tpl create mode 100644 helm/tline/templates/minio.yaml.tpl create mode 100644 helm/tline/templates/postgres.yaml.tpl create mode 100644 helm/tline/templates/redis.yaml.tpl create mode 100644 helm/tline/templates/secret.yaml.tpl create mode 100644 helm/tline/templates/service-minio-tailscale-console.yaml.tpl create mode 100644 helm/tline/templates/service-minio-tailscale-s3.yaml.tpl create mode 100644 helm/tline/templates/web.yaml.tpl create mode 100644 helm/tline/templates/worker.yaml.tpl create mode 100644 helm/tline/values.yaml create mode 100644 opencode.jsonc create mode 100644 package.json create mode 100644 packages/config/package.json create mode 100644 packages/config/src/index.ts create mode 100644 packages/config/tsconfig.json create mode 100644 packages/db/migrations/0001_init.sql create mode 100644 packages/db/migrations/0002_assets_duration_and_indexes.sql create mode 100644 packages/db/package.json create mode 100644 packages/db/src/index.ts create mode 100644 packages/db/src/migrate.ts create mode 100644 packages/db/tsconfig.json create mode 100644 packages/minio/package.json create mode 100644 packages/minio/src/index.ts create mode 100644 packages/minio/tsconfig.json create mode 100644 packages/queue/package.json create mode 100644 packages/queue/src/index.ts create mode 100644 packages/queue/tsconfig.json create mode 100644 tsconfig.base.json diff --git a/.agents/README.md b/.agents/README.md new file mode 100644 index 0000000..305f38f --- /dev/null +++ b/.agents/README.md @@ -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 subagent’s **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.` to avoid mixed-content blocking. +- Prefer Pi-friendly defaults: low worker concurrency, avoid scheduling heavy pods on Pi 3. diff --git a/.agents/backend-api.md b/.agents/backend-api.md new file mode 100644 index 0000000..6124ebf --- /dev/null +++ b/.agents/backend-api.md @@ -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.` 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.`. +- Pagination works for `GET /api/assets`. +- Aggregations return correct counts for year/month/day. diff --git a/.agents/frontend-ui.md b/.agents/frontend-ui.md new file mode 100644 index 0000000..1cc590a --- /dev/null +++ b/.agents/frontend-ui.md @@ -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 `