# Backlog from overnight session — 2026-07-16 Written to the repo because the available Gitea credential (`write:repository` only) cannot create issues. **Transfer these to Gitea once a token with `read:issue` + `write:issue` scope exists.** ## Blockers needing Jerod's input ### B1. Gitea API token for agent workflows The stored git credential can push code but not read/create issues (`required=[read:issue], token scope=write:repository`). Create a token at git.jerodrigged.com/user/settings/applications with `read:user`, `write:issue`, `write:repository` and set it as `GITEA_TOKEN` (user env var) on this machine. ### B2. Production (CT111) api/.env is a blank template The GitHub deploy now auto-creates `api/.env` from `.env.example`, which is why the new stack runs — but every secret is empty. Until real values are set on CT111 at `/opt/lisilou-portfolio/api/.env`: - admin dashboard login is disabled (no `ADMIN_SECRET`) - **new bookings send no n8n notification — real clients could book silently** - calendar availability shows all dates free (no Google creds) - SSO/client portal sign-in is inactive (no `OIDC_*` / `SESSION_SECRET`) Copy working values from CT114:`/opt/…/api/.env` (adjust `SITE_URL` / `CORS_ORIGIN` to https://lisilou.jerodrigged.com), then `docker compose restart api`. ### B3. Authentik provider + groups (issues #10/#12) Code for OIDC login and the client portal is deployed and tested, but Authentik needs one-time admin setup (see header comment in `api/auth.js`): 1. OAuth2/OpenID provider (confidential; redirect URIs for both dev and prod `/api/auth/callback`), application "LisiLou Portfolio" 2. `lisilou-admin` group with Elysse (grants dashboard access) 3. Enrollment flow for client self-registration (#12) — Authentik-side config only 4. Fill `OIDC_*` + `SESSION_SECRET` in both instances' `api/.env` ### B4. Decide the deploy topology (dev vs prod) Discovered overnight: `lisilou.jerodrigged.com` → NPM (CT102) → **CT111**, deployed by **GitHub** Actions from github.com/jhodgkin/lisilou-portfolio; the Gitea repo deploys to **CT114** (dev). The public site was 20 commits stale because pushes stopped reaching GitHub. I've synced GitHub main and both pipelines are green, but: - keeping two remotes in sync manually will drift again (mirror Gitea→GitHub, or point NPM at CT114, or move prod deploy to Gitea Actions) - CT111 and CT114 have separate SQLite DBs — real bookings live on CT111 only - `homelab/docs/infrastructure.md` is stale (lists CT114 as Keycloak; CT111 notes don't mention the GitHub runner deploy chain) ### B5. dev-lisilou.jerodrigged.com has no NPM proxy host The Cloudflare tunnel delivers the hostname to NPM (CT102), but NPM has no proxy host for it, so it falls through to the "Jerod Rigged" default landing page. Verified: `curl -H "Host: dev-lisilou.jerodrigged.com" http://192.168.1.185/` → landing page, while the same probe with `Host: lisilou.jerodrigged.com` → `healthy`. I could not fix this without the NPM admin login (192.168.1.185:81 — presumably in Vaultwarden; factory default is disabled, and neither SSH nor the ansible key works from this machine). **Fix (2 min in NPM UI):** Hosts → Proxy Hosts → Add: - Domain: `dev-lisilou.jerodrigged.com` - Scheme `http`, Forward Host `192.168.1.192`, Port `8080` - Websockets ON, Block Common Exploits ON; SSL tab: same as the `lisilou.jerodrigged.com` host Also confirm the hostname exists as a public hostname/CNAME in the CF tunnel config (it already resolves and reaches NPM, so likely fine). **So the agent can do this next time:** put the NPM admin credential in a place Claude can reach (e.g. `NPM_ADMIN_IDENTITY`/`NPM_ADMIN_SECRET` env vars, or an API-only NPM user), or install/authorize the `~/.ssh/ansible_ed25519` key on this machine. ## Security ### S1. Signed-contract download is unauthenticated and enumerable `GET /api/bookings/:id/contract` serves any signed contract by numeric id (kept because n8n email links use it). Replace with HMAC-signed URLs (`?token=…`, using SESSION_SECRET) and update the n8n workflow template. ### S2. Dev ADMIN_SECRET committed in playwright.config.js `9yPu…` is in git history and matches the dev instance. Rotate the dev secret and inject via env/Gitea secret instead of a hardcoded default. ## Content (needed to look professional — code is ready, assets are missing) ### C1. Real photography on the prod volume - `/images/hero.jpg` — new: homepage hero photo (soft scrim applied automatically) - portfolio category covers (`/images/portfolio/*-cover.jpg`) or working Immich album links — cards currently show the styled placeholder - location photos (`/images/locations//hero.jpg`, `1.jpg`, `2.jpg`) - `/images/logo.png`, `/images/favicon.ico`, profile photo Verify the Immich share albums referenced in `site.json` resolve on prod. ### C2. Contract template PDF `api/contracts/model-release.pdf` is absent on both instances — the e-sign step falls back and no PDF gets stamped. Drop the real contract on the volumes. ### C3. Confirm public contact details `site.json` has `hello@lisilou.com` and an empty phone; Venmo username `LisiLouPhoto` — confirm all are real before promoting the site. ## Nice-to-haves spotted during the walkthrough - Portfolio lightbox: verify Immich proxy flow end-to-end on prod (couldn't test without albums) - `/dashboard` and `/my-bookings` aren't linked from anywhere for the photographer; consider a footer link or bookmark - Add `robots.txt` + real meta description / OpenGraph tags for sharing - The "designer plugin" requested for the design review doesn't exist in this Claude Code environment — the pass was done manually (screenshots + fixes); if there's a specific plugin to install, add it to `.claude/settings.json`