Sync master: scrub public docs, untrack internal notes/caches, roadmap update #71

Merged
ilia merged 30 commits from dev into master 2026-07-26 14:52:55 -05:00
Owner
  • Scrub homelab IPs and default credentials from README.md and .cursorrules; reduce emoji density in README
  • Untrack .notes/ (internal meeting notes) and frontend/.vite/ cache; ignore .notes/, logs/, .vite/
  • Deduplicate env templates: merge .env_example variants into .env.example (root, viewer, admin) and update docs/scripts references
  • Roadmap update
- Scrub homelab IPs and default credentials from README.md and .cursorrules; reduce emoji density in README - Untrack .notes/ (internal meeting notes) and frontend/.vite/ cache; ignore .notes/, logs/, .vite/ - Deduplicate env templates: merge .env_example variants into .env.example (root, viewer, admin) and update docs/scripts references - Roadmap update
ilia added 30 commits 2026-07-26 14:31:57 -05:00
fix: prevent sign-out crash and surface real email-send failures
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 9s
bb09159133
- NextAuth session/jwt callbacks no longer return null (the client
  useSession() hook chokes on a null session, crashing the app on
  sign-out for deactivated/refreshed sessions) — fixes #57
- UserMenu/Header sign-out handlers close the Manage Users overlay and
  popover before calling signOut(), and no longer let a rejected
  signOut() promise go unhandled
- Added an app-level error boundary as a safety net for any remaining
  client render errors
- Registration and forgot-password flows now tell the user honestly
  when the confirmation/reset email failed to send instead of always
  claiming success — related to #56
- lib/email.ts throws a clear, actionable error when neither
  SMTP nor Resend is configured, instead of a cryptic SDK error
- Documented required SMTP/Resend env vars in DEPLOYMENT_CHECKLIST.md
  (were missing entirely, which is why no confirmation/reset emails
  were ever sent in deployed environments) — fixes #56
feat: add dark mode and audit viewer-frontend accessibility
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 11s
c011c8078e
Add next-themes light/dark/system theming with an accessible toggle
in every header, and close out an a11y pass across the viewer app:
skip-to-content link, main landmarks and heading hierarchy on every
route, focus-trapped dialog semantics for the photo viewer modals,
aria-label/live-region coverage for dynamic messages and icon
buttons, and dark: variants for previously light-only colors.
test: add Playwright e2e smoke suite for punimtag dev
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 10s
CI / e2e (pull_request) Successful in 46s
0a9223c943
Add an e2e/ Playwright harness (via @levkin/playkit) that smoke-tests
the public DEV host: login page loads, sign-out never redirects to a
LAN host, FastAPI /health responds, and forgot-password mail lands in
Mailtrap with a public reset link (Kolby #56/#57 regressions).

Wire it into Gitea Actions as a new `e2e` job (self-hosted runner,
Chromium via Playwright), gated behind the existing skip-ci-check.
Add npm root scripts (install:e2e, test:e2e) and gitignore e2e build
artifacts (node_modules, reports, .env).
test: cover 7 previously-untested backend API route modules
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 11s
CI / e2e (pull_request) Successful in 27s
2d6bbf1d13
Adds pytest coverage for metrics, click_log, role_permissions, videos,
pending-identifications, pending-linkages, and reported-photos — the
last three required extending conftest with a second (auth) test
database + DDL mirroring the Prisma schema-auth.prisma tables, since
those endpoints read/write DATABASE_URL_AUTH via raw SQL.

pending-photos.py is intentionally left uncovered for now (heavy
filesystem/hash-based duplicate-detection logic needs its own mocking
strategy) and tracked as a follow-up.
test: add cross-endpoint integration and error-handling suites
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 11s
CI / e2e (pull_request) Successful in 26s
5303580107
Adds test_api_integration.py (person identification, tag+search,
favorites+search, bulk favorites, and role-permission-grant workflows
chained across multiple endpoints) and test_api_errors.py (404/401/403/422
consistency sweeps, SQL-injection/XSS-style input handling, large-payload
handling) per the two suites the existing tests/API_TEST_PLAN.md already
documented but never implemented.

Along the way, found and documented (via a passing test, not a fix) that
GET /api/v1/faces/unidentified has no auth dependency, unlike its sibling
routes.
Add Vitest + React Testing Library setup for viewer-frontend
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 11s
CI / e2e (pull_request) Successful in 28s
975d0c809d
Establishes frontend unit testing infra (jsdom env, RTL, jest-dom
matchers, common Radix/jsdom polyfills) and seeds it with tests for
lib/utils.ts, lib/photo-utils.ts, hooks/useFocusTrap.ts, and
ThemeToggle.tsx (46 tests total).
Expand e2e auth coverage, Vitest CI, and shared URL defaults
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 13s
CI / e2e (pull_request) Successful in 2m14s
CI / viewer-unit (pull_request) Successful in 2m38s
47b15049bc
Wire viewer-frontend Vitest into Gitea Actions, centralize DEV base URLs
in env-defaults.json, expand playkit API catalog specs, and land auth/mail
flows plus verify-email public-host redirect and idle-logout e2e hooks.
Bump playkit to v0.3 and use Zod API schemas
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 12s
CI / viewer-unit (pull_request) Successful in 1m59s
CI / e2e (pull_request) Successful in 1m54s
217b82d912
Adopt assertSchema via ApiClient, playkitFailureArtifacts in Playwright
config, and keep e2e login on e2e@levkine.ca credentials from CI secrets.
Merge pull request 'Expand e2e auth, Vitest CI, env-defaults, API catalog' (#64) from test/e2e-auth-vitest-ci into dev
CI / skip-ci-check (push) Successful in 4s
CI / docker-ci (push) Successful in 6s
CI / secret-scan (push) Successful in 11s
CI / viewer-unit (push) Successful in 2m39s
CI / e2e (push) Successful in 4m13s
988e9accf8
Fill e2e gaps: storageState, real upload POST, session smoke
CI / skip-ci-check (pull_request) Successful in 3s
CI / docker-ci (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 12s
CI / viewer-unit (pull_request) Successful in 3m11s
CI / e2e (pull_request) Failing after 5m24s
d9910acdde
Add auth setup project, viewer session check, upload that posts a fixture,
FastAPI login spec (skips without E2E_API_*), and repo ROADMAP.md.
Track e2e fixture PNG (gitignore exception)
CI / skip-ci-check (pull_request) Successful in 8s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 15s
CI / viewer-unit (pull_request) Successful in 1m32s
CI / e2e (pull_request) Successful in 1m55s
4ef8fcc7e7
Merge pull request #65 from test/e2e-gaps-roadmap
CI / skip-ci-check (push) Successful in 8s
CI / docker-ci (push) Successful in 7s
CI / secret-scan (push) Successful in 16s
CI / e2e (push) Successful in 1m23s
CI / viewer-unit (push) Failing after 14m57s
c31c76b5a8
Fill e2e gaps and ROADMAP (#65)
test: FastAPI e2e role-permission gates + gallery search filter coverage
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 10s
CI / viewer-unit (pull_request) Successful in 2m33s
CI / e2e (pull_request) Successful in 2m38s
e78fad692f
- Wire E2E_API_USERNAME/PASSWORD (admin) + E2E_API_VIEWER_USERNAME/PASSWORD
  (viewer) into the Gitea Actions e2e job so FastAPI-authed specs run in CI.
- Add api.role-permissions.spec.ts: viewer 403 vs admin 200/200/200 on
  /api/v1/users, /api/v1/role-permissions, and /api/v1/photos/bulk-delete
  (safe no-op via a non-existent photo id — proves the gate, not deletion).
- Add gallery.search-filters.spec.ts: tag_id and person_id filters on the
  public /api/search route return correct subsets, combined filters narrow
  results, and the /search UI tag-filter interaction updates the URL/count.
- Update ROADMAP/README/.env.example for the new env vars and coverage.
Merge pull request 'test: FastAPI e2e role-permission gates + gallery search filters' (#66) from test/fastapi-e2e-role-search into dev
CI / skip-ci-check (push) Successful in 5s
CI / docker-ci (push) Successful in 5s
CI / secret-scan (push) Successful in 11s
CI / viewer-unit (push) Successful in 2m30s
CI / e2e (push) Successful in 2m33s
e60abd9263
docs: playkit gaps + next e2e ideas (#67)
CI / skip-ci-check (push) Successful in 4s
CI / docker-ci (push) Successful in 6s
CI / secret-scan (push) Successful in 11s
CI / e2e (push) Failing after 3m3s
CI / viewer-unit (push) Successful in 3m9s
72e89aef9f
test: playkit v0.3.1 adoption, Zod widening, PROD smoke, NextAuth write gates (#68)
CI / skip-ci-check (push) Successful in 4s
CI / docker-ci (push) Successful in 6s
CI / secret-scan (push) Successful in 11s
CI / admin-unit (push) Successful in 1m23s
CI / viewer-unit (push) Successful in 2m2s
CI / e2e (push) Successful in 2m43s
96351288f0
test: timing budgets + CI hardening (artifact v3 pin, npm cache retry)
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 12s
CI / viewer-unit (pull_request) Successful in 1m29s
CI / e2e (pull_request) Successful in 4m8s
CI / admin-unit (pull_request) Successful in 4m24s
c0c997f796
Closes three items from the outstanding e2e/CI gap list:

- Timing budgets: timings.measure() only ever recorded durations for the
  (still-unwired) Pushgateway export — nothing failed CI when a step got
  slow. Add e2e/timing-budgets.ts (expectWithinBudget + shared BUDGET_MS
  buckets) and wire it into every measure() call site across the suite.
  Mail-wait steps are deliberately left unbudgeted (external mail-trap
  delivery latency, not a code performance signal).

- actions/upload-artifact@v4 doesn't work against this Gitea/act runner's
  artifact backend — pin to v3 for the e2e failure-report upload.

- Shared act_runner npm cache has corrupted platform-native tarballs before
  (@next/swc-linux-x64-musl) and reds viewer-unit/admin-unit/e2e with no
  product bug involved. All three npm ci steps now retry once after
  `npm cache clean --force` on first failure.

Verified: full local suite green against DEV (37 passed, 6 skipped, no
budget assertion failures) before wiring into CI.
Merge pull request 'test: timing budgets + CI hardening (artifact v3 pin, npm cache retry)' (#69) from test/timing-budgets-ci-hardening into dev
CI / skip-ci-check (push) Successful in 5s
CI / docker-ci (push) Successful in 7s
CI / secret-scan (push) Successful in 15s
CI / admin-unit (push) Successful in 33s
CI / viewer-unit (push) Successful in 1m3s
CI / e2e (push) Successful in 3m10s
da4fc72807
security: remove plaintext dev/Postgres passwords from .cursorrules
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 17s
CI / admin-unit (pull_request) Successful in 22s
CI / viewer-unit (pull_request) Successful in 42s
CI / e2e (pull_request) Successful in 1m50s
586243cd56
These were committed in cleartext and pushed to remote history. Rotate the
dev server SSH password and Postgres 'ladmin' password separately; this
only stops the leak going forward and points at Infisical/vault instead.
Merge pull request 'security: remove plaintext credentials from .cursorrules' (#70) from security/scrub-cursorrules-creds into dev
CI / skip-ci-check (push) Successful in 5s
CI / docker-ci (push) Successful in 6s
CI / secret-scan (push) Successful in 19s
CI / admin-unit (push) Successful in 20s
CI / viewer-unit (push) Successful in 40s
CI / e2e (push) Successful in 1m55s
23f0616646
chore: deduplicate env templates into .env.example
CI / skip-ci-check (push) Successful in 18s
CI / docker-ci (push) Successful in 19s
CI / secret-scan (push) Successful in 32s
CI / viewer-unit (push) Successful in 2m42s
CI / admin-unit (push) Successful in 3m22s
CI / e2e (push) Successful in 4m17s
CI / skip-ci-check (pull_request) Successful in 18s
CI / docker-ci (pull_request) Successful in 21s
CI / secret-scan (pull_request) Successful in 31s
CI / viewer-unit (pull_request) Successful in 1m30s
CI / admin-unit (pull_request) Successful in 2m26s
CI / e2e (pull_request) Failing after 7m8s
d6b546c95e
ilia closed this pull request 2026-07-26 14:43:10 -05:00
ilia reopened this pull request 2026-07-26 14:43:13 -05:00
ilia merged commit 688c6f7d8e into master 2026-07-26 14:52:55 -05:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ilia/punimtag#71