From b3a78aa1665088e10d5cd17ecb562aca1fdf16d5 Mon Sep 17 00:00:00 2001 From: "Gan, Jimmy" Date: Thu, 9 Jul 2026 23:57:06 +0800 Subject: [PATCH] add PDD workflow: CLAUDE.md, PDD.md, active.md symlink --- CLAUDE.md | 88 +++++++++++++++++++++----------------------- docs/PDD.md | 23 ++++++++++++ docs/specs/active.md | 1 + 3 files changed, 66 insertions(+), 46 deletions(-) create mode 100644 docs/PDD.md create mode 120000 docs/specs/active.md diff --git a/CLAUDE.md b/CLAUDE.md index 33dae2f..a9361d4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,68 +1,64 @@ # NAS Tools Project -## Architecture -- Synology DS224+ (x86_64, 18GB RAM), Tailscale IP: `100.78.131.124`, LAN: `192.168.31.221` -- Docker: `/volume1/@appstore/ContainerManager/usr/bin/docker`, compose dirs: `/volume1/docker/*` -- VPS Caddy (`161.33.182.109`, Tailscale: `100.109.198.126`): reverse proxy for `*.jimmygan.com` -- Build VPS (server2, `158.101.140.85`, Tailscale: `100.70.115.1`): podman, fast network -- NAS Caddy: port 8443 fallback only (SNI broken) +## PDD Workflow -## Dashboard +This project follows **PDD (Product Definition Document)** development. + +**Always read these files before writing code:** +- `docs/PDD.md` — product vision, goals, targets (the north star) +- `docs/specs/active.md` — current sprint spec (what we're building now) + +**Workflow:** +1. PDD → Sprint Spec → Implementation → Validate ACs +2. Scope changes update the sprint spec first, code second +3. Never ship without ACs passing + +## Dev Commands + +- **Build dashboard:** `cd dashboard/frontend && npm run build` +- **Dev dashboard:** `cd dashboard/backend && uvicorn main:app --reload` + `cd dashboard/frontend && npm run dev` +- **Test:** `cd dashboard && python -m pytest backend/tests/` +- **Deploy:** Push to main → Gitea CI builds + deploys to NAS + +## Architecture + +- **Synology DS224+** (x86_64, 18GB RAM), Tailscale IP: `100.78.131.124`, LAN: `192.168.31.221` +- **Docker:** `/volume1/@appstore/ContainerManager/usr/bin/docker`, compose dirs: `/volume1/docker/*` +- **VPS Caddy** (`161.33.182.109`, Tailscale: `100.109.198.126`): reverse proxy for `*.jimmygan.com` +- **Build VPS** (server2, `158.101.140.85`, Tailscale: `100.70.115.1`): podman builds +- **NAS Caddy:** port 8443 fallback only (SNI broken) + +### Dashboard - Backend: Python FastAPI (`dashboard/backend/`) - Frontend: Svelte 5 + Tailwind CSS (`dashboard/frontend/`) -- Svelte 5 runes: use `$state`, `$props`, `$bindable` (not legacy `export let`) -- Sidebar categories: Main, Media, Tools (see `docs/architecture.md` for full layout) +- Svelte 5 runes: `$state`, `$props`, `$bindable` (not `export let`) - New pages: create route in `src/routes/`, import in `App.svelte`, update `Sidebar.svelte` -## CI/CD -Two workflows in `.gitea/workflows/`: +### CI/CD +Two Gitea workflows in `.gitea/workflows/`: - **deploy.yml** — main branch: tests → build → deploy to production - **deploy-dev.yml** — dev branch: tests → build → deploy to dev -Two runners: -- **VPS runner** (`vps` label on server2) — build + test jobs (podman) -- **NAS runner** (`nas` label on DS224+) — deploy jobs (docker, host networking) +Build flow: VPS builds → pushes to local registry (`100.78.131.124:5501/`) → streams to NAS → `docker compose up -d` -### Build flow -1. VPS builds Docker image + pushes to local registry `100.78.131.124:5501/` -2. Streams image to NAS: `podman save | gzip | ssh nasts "gunzip | docker load"` -3. NAS deploys: `docker compose up -d` +## Key Files -## Local Registry -- Container: `registry-mirror` on NAS, port 5501 -- Standalone mode (NOT Docker Hub proxy — blocked from China) -- VPS pushes with `podman push --tls-verify=false` - -## Authentication -- **Gitea API Access:** Token stored in `~/.config/tea/config.yml` (user: `jimmy`) -- **Gitea Token:** `aa8c20329040c56c079d2676318c6e33f14b221d` -- **Project Secrets:** Gitea repo secrets: CI_TOKEN, CI_DB_PASSWORD, SECRET_KEY, ADMIN_PASSWORD_HASH, TRANSMISSION_USER, TRANSMISSION_PASS - -## claude-dev CI Contract -- Source in `claude-dev/` (Dockerfile, required-tools.txt, scripts/) -- CI-first: update `claude-dev/*` in git, then push -- Workflow: `.gitea/workflows/deploy-claude-dev-dev.yml` -- Uses NAS runner with `DOCKER_BUILDKIT=0` -- Immutable tag format: `claude-dev:dev--` -- Runtime compose: `claude-dev/docker-compose.yml` -- Rollback: run workflow with `rollback_image` using value from `/volume1/docker/claude-dev/previous-image.txt` +- `docs/architecture.md` — full architecture reference +- `docs/TESTING.md` — test patterns and conventions +- `specs/` — sprint history +- `.gitea/workflows/deploy.yml` — main CI +- `.gitea/workflows/deploy-dev.yml` — dev CI +- `dashboard/backend/main.py` — FastAPI entry point +- `dashboard/frontend/src/App.svelte` — Svelte entry point ## Synology Quirks + - No `crontab` — edit `/etc/crontab` with `sudo` + `printf`, restart crond - No `scp` subsystem — use `cat file | ssh ... 'cat > dest'` - ACLs override Unix perms — use `sudo chmod 777` + `synoacltool -enforce-inherit` - Tailscale userspace mode — cannot bind Docker ports to Tailscale IPs ## DNS + - dnsmasq on NAS resolves `*.jimmygan.com` → `161.33.182.109` (Caddy VPS) - Tailscale split DNS: `jimmygan.com` → NAS (queries hit dnsmasq) - -## Proxy API -- URL: `https://www.bytecatcode.org` -- Models: `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-haiku-4-5-20251001` - -## Key Files -- `docs/architecture.md` — full architecture reference -- `docs/TESTING.md` — test patterns and conventions -- `.gitea/workflows/deploy.yml` — main CI -- `.gitea/workflows/deploy-dev.yml` — dev CI diff --git a/docs/PDD.md b/docs/PDD.md new file mode 100644 index 0000000..63b13f5 --- /dev/null +++ b/docs/PDD.md @@ -0,0 +1,23 @@ +# Product Definition Document — NAS Tools + +## Vision + +A single dashboard to manage all self-hosted services on the NAS — Docker containers, media, tools, system health — accessible from anywhere via a clean web UI. + +## Goals + +1. **Unified management** — one dashboard for all NAS services (containers, media, tools, auth) +2. **GFW-proof deployment** — all traffic routes through VPS + Tailscale, works from China +3. **Self-healing** — auto-detect down containers, email alerts, health checks +4. **CI/CD from Gitea** — push to deploy with zero manual SSH + +## Target Users + +Self (Jimmy Gan). Secondary: family members who access media services on the NAS. + +## Success Metrics + +- Dashboard loads in < 3s from anywhere +- All CI workflows green +- Zero manual SSH deploys +- < 5min recovery from container crash diff --git a/docs/specs/active.md b/docs/specs/active.md new file mode 120000 index 0000000..8d80f4e --- /dev/null +++ b/docs/specs/active.md @@ -0,0 +1 @@ +../../specs/sprint-06-code-quality.md \ No newline at end of file