Files
lisilou-portfolio/docs/BACKLOG-2026-07-16.md
T
jhodgkin 773fcd5740
Deploy to Dev / Deploy & Smoke Test (push) Successful in 21s
Mark B5 resolved: NPM proxy host domain typo corrected
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:12:46 -06:00

5.9 KiB

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 RESOLVED 2026-07-16

Root cause was a typo in the NPM proxy host domain (jerodriggec.com); Jerod corrected it and the host is live. Original notes kept below for context.

B5 (original notes)

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.comhealthy. 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/<id>/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