358 Commits

Author SHA1 Message Date
23f0616646 Merge pull request 'security: remove plaintext credentials from .cursorrules' (#70) from security/scrub-cursorrules-creds into dev
All checks were successful
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
2026-07-15 17:42:55 -05:00
586243cd56 security: remove plaintext dev/Postgres passwords from .cursorrules
All checks were successful
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
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.
2026-07-15 18:38:40 -04:00
da4fc72807 Merge pull request 'test: timing budgets + CI hardening (artifact v3 pin, npm cache retry)' (#69) from test/timing-budgets-ci-hardening into dev
All checks were successful
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
2026-07-15 08:03:20 -05:00
c0c997f796 test: timing budgets + CI hardening (artifact v3 pin, npm cache retry)
All checks were successful
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
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.
2026-07-15 08:56:31 -04:00
96351288f0 test: playkit v0.3.1 adoption, Zod widening, PROD smoke, NextAuth write gates (#68)
All checks were successful
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
2026-07-14 22:24:07 -05:00
72e89aef9f docs: playkit gaps + next e2e ideas (#67)
Some checks failed
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
2026-07-14 20:26:33 -05:00
e60abd9263 Merge pull request 'test: FastAPI e2e role-permission gates + gallery search filters' (#66) from test/fastapi-e2e-role-search into dev
All checks were successful
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
2026-07-14 19:47:07 -05:00
e78fad692f test: FastAPI e2e role-permission gates + gallery search filter coverage
All checks were successful
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
- 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.
2026-07-14 20:42:47 -04:00
c31c76b5a8 Merge pull request #65 from test/e2e-gaps-roadmap
Some checks failed
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
Fill e2e gaps and ROADMAP (#65)
2026-07-14 18:28:59 -05:00
4ef8fcc7e7 Track e2e fixture PNG (gitignore exception)
All checks were successful
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
2026-07-14 19:19:49 -04:00
d9910acdde Fill e2e gaps: storageState, real upload POST, session smoke
Some checks failed
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
Add auth setup project, viewer session check, upload that posts a fixture,
FastAPI login spec (skips without E2E_API_*), and repo ROADMAP.md.
2026-07-14 19:17:14 -04:00
988e9accf8 Merge pull request 'Expand e2e auth, Vitest CI, env-defaults, API catalog' (#64) from test/e2e-auth-vitest-ci into dev
All checks were successful
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
2026-07-14 18:11:05 -05:00
217b82d912 Bump playkit to v0.3 and use Zod API schemas
All checks were successful
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
Adopt assertSchema via ApiClient, playkitFailureArtifacts in Playwright
config, and keep e2e login on e2e@levkine.ca credentials from CI secrets.
2026-07-14 19:02:48 -04:00
47b15049bc Expand e2e auth coverage, Vitest CI, and shared URL defaults
All checks were successful
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
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.
2026-07-14 18:49:42 -04:00
62d5a66ffa Merge pull request 'Add Vitest + React Testing Library setup for viewer-frontend' (#63) from test/viewer-frontend-vitest-setup into dev 2026-07-14 17:39:59 -05:00
975d0c809d Add Vitest + React Testing Library setup for viewer-frontend
All checks were successful
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
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).
2026-07-14 18:35:30 -04:00
05b908241d Merge pull request 'test: add cross-endpoint integration and error-handling suites' (#62) from test/backend-integration-error-suites into dev 2026-07-14 17:24:37 -05:00
5303580107 test: add cross-endpoint integration and error-handling suites
All checks were successful
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
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.
2026-07-14 18:23:15 -04:00
fc8b47863d Merge pull request 'test: cover 7 previously-untested backend API route modules' (#61) from test/backend-pytest-coverage-gaps into dev 2026-07-14 17:17:20 -05:00
2d6bbf1d13 test: cover 7 previously-untested backend API route modules
All checks were successful
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
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.
2026-07-14 18:15:15 -04:00
0f24e7e6ba Merge pull request 'test: add Playwright e2e smoke suite for punimtag dev' (#60) from test/e2e-playwright-smoke into dev 2026-07-14 16:13:57 -05:00
0a9223c943 test: add Playwright e2e smoke suite for punimtag dev
All checks were successful
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
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).
2026-07-14 17:11:38 -04:00
44f3d696e4 Merge pull request 'feat: add dark mode and audit viewer-frontend accessibility' (#59) from a11y/dark-mode-and-focus-management into dev 2026-07-14 15:25:46 -05:00
c011c8078e feat: add dark mode and audit viewer-frontend accessibility
All checks were successful
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
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.
2026-07-14 16:24:51 -04:00
e54c60912c Merge pull request 'fix: prevent sign-out crash and surface real email-send failures' (#58) from fix/logout-crash-and-email-delivery into dev 2026-07-14 12:14:53 -05:00
bb09159133 fix: prevent sign-out crash and surface real email-send failures
All checks were successful
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
- 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
2026-07-14 12:44:33 -04:00
3e39f978f6 Merge pull request 'docs: close shipped triage issues; leave #43/#44 open' (#54) from docs/close-shipped-issues into dev
All checks were successful
CI / skip-ci-check (push) Successful in 6s
CI / docker-ci (push) Successful in 7s
CI / secret-scan (push) Successful in 12s
2026-07-09 19:41:40 -05:00
1bfc5adb6f docs: close shipped triage issues; leave #43/#44 open
All checks were successful
CI / skip-ci-check (pull_request) Successful in 7s
CI / docker-ci (pull_request) Successful in 8s
CI / secret-scan (pull_request) Successful in 12s
2026-07-09 20:41:18 -04:00
4f001e7887 Merge pull request 'docs: Postgres .179 + refresh next-steps' (#53) from docs/fix-postgres-179-and-next-steps into master
All checks were successful
CI / skip-ci-check (push) Successful in 6s
CI / docker-ci (push) Successful in 7s
CI / secret-scan (push) Successful in 15s
2026-07-09 14:17:07 -05:00
739ab17425 docs: retarget Postgres to .179 and refresh next-steps
All checks were successful
CI / skip-ci-check (pull_request) Successful in 8s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 14s
Update deploy docs off dead .181, refresh FIXES_2026-07-09, and point
.notes/task_list at Gitea issues as source of truth.
2026-07-09 15:13:31 -04:00
eeb00339da Merge pull request 'Release: merge dev into master (open-issue triage + thumb cache)' (#52) from dev into master
All checks were successful
CI / skip-ci-check (push) Successful in 6s
CI / docker-ci (push) Successful in 7s
CI / secret-scan (push) Successful in 12s
Reviewed-on: #52
2026-07-09 14:03:17 -05:00
3a4bfa9988 Merge pull request 'fix: open-issue triage (#21,#26,#45,#46,#47,#30-33)' (#51) from fix/open-issues-triage into dev
All checks were successful
CI / skip-ci-check (pull_request) Successful in 6s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 12s
Reviewed-on: #51
2026-07-09 13:58:27 -05:00
3769c897b0 perf: disk-cache grid thumbnails and document 2026-07-09 fixes
All checks were successful
CI / skip-ci-check (pull_request) Successful in 6s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 12s
Cache resized thumbs under .cache/photo-thumbnails (360px) so repeat
grid loads skip Sharp. Document ticket/infra fixes; drop unused SVGs.
2026-07-09 14:54:08 -04:00
ffddeca268 fix: address open triage issues (#21,#26,#45,#46,#47,#30-33)
All checks were successful
CI / skip-ci-check (pull_request) Successful in 6s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 11s
- #45: re-read local folder when recursive checkbox toggles
- #47: clear Identify crop spinner when image is already cached
- #46: search selected people by person_ids; AND for "First Last"
- #21: enqueue network import without blocking API walk
- #26: serve resized grid thumbnails for photos
- #30/#31/#33: re-enable small-face filters in auto-match
2026-07-09 14:42:08 -04:00
2dab2aa7f9 Merge pull request 'PunimTag Web Application - Major Feature Release' (#1) from dev into master
All checks were successful
CI / skip-ci-check (push) Successful in 6s
CI / docker-ci (push) Successful in 9s
CI / secret-scan (push) Successful in 12s
Reviewed-on: #1
2026-07-09 12:20:31 -05:00
d69ad1576d Merge pull request 'chore: merge master into dev (sync homelab CI bootstrap)' (#50) from chore/sync-ci-from-master into dev
All checks were successful
CI / skip-ci-check (pull_request) Successful in 10s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Successful in 16s
2026-05-29 21:52:46 -05:00
f0529e8274 chore: merge master into dev (sync homelab CI bootstrap)
All checks were successful
CI / skip-ci-check (pull_request) Successful in 9s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Successful in 15s
Resolve add/add conflicts in CI files by adopting the homelab Gitea
Actions workflow from master (#48), replacing the legacy dev ci.yml.
2026-05-29 22:52:19 -04:00
5144d9a3b0 Merge pull request 'Add homelab Gitea Actions CI (generic)' (#48) from ci/bootstrap-gitea-actions-docker into master
All checks were successful
CI / skip-ci-check (push) Successful in 11s
CI / docker-ci (push) Successful in 11s
CI / secret-scan (push) Successful in 16s
CI / skip-ci-check (pull_request) Successful in 10s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Successful in 16s
2026-05-29 21:46:27 -05:00
2db7ee88c9 ci: sync gitleaks allowlist
All checks were successful
CI / skip-ci-check (pull_request) Successful in 9s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Successful in 19s
2026-05-29 21:31:59 -05:00
c0b09b1d6b ci: refresh workflow (re-run pipelines) 2026-05-29 21:31:56 -05:00
2658bc7b07 ci: sync gitleaks allowlist
All checks were successful
CI / skip-ci-check (pull_request) Successful in 10s
CI / docker-ci (pull_request) Successful in 12s
CI / secret-scan (pull_request) Successful in 18s
2026-05-29 21:28:30 -05:00
7279c57955 ci: refresh workflow (re-run pipelines) 2026-05-29 21:28:28 -05:00
e2f980ad1a ci: sync gitleaks allowlist
All checks were successful
CI / skip-ci-check (pull_request) Successful in 12s
CI / docker-ci (pull_request) Successful in 14s
CI / secret-scan (pull_request) Successful in 18s
2026-05-29 21:24:22 -05:00
60c57bc351 ci: refresh workflow (re-run pipelines) 2026-05-29 21:24:13 -05:00
ef5d4df233 ci: add homelab gitleaks allowlist
All checks were successful
CI / skip-ci-check (pull_request) Successful in 10s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Successful in 21s
2026-05-29 21:19:59 -05:00
d876a67244 ci: refresh workflow (re-run pipelines) 2026-05-29 21:19:56 -05:00
4fd6c4f24c ci: refresh workflow (re-run pipelines)
Some checks failed
CI / skip-ci-check (pull_request) Successful in 9s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Failing after 27s
2026-05-29 20:31:01 -05:00
eaa03d115b ci: refresh workflow (re-run pipelines)
Some checks failed
CI / skip-ci-check (pull_request) Successful in 10s
CI / docker-ci (pull_request) Successful in 12s
CI / secret-scan (pull_request) Failing after 31s
2026-05-29 20:28:42 -05:00
e6bd689a22 ci: sync workflow template
Some checks failed
CI / skip-ci-check (pull_request) Successful in 9s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Failing after 36s
2026-05-29 20:26:18 -05:00
d21741c5b0 ci: refresh workflow (re-run pipelines)
Some checks failed
CI / skip-ci-check (pull_request) Successful in 10s
CI / docker-ci (pull_request) Successful in 11s
CI / secret-scan (pull_request) Failing after 25s
2026-05-29 20:20:47 -05:00