18 Commits
Author SHA1 Message Date
adminandClaude Opus 5.5 5dbde04c6f refactor: Cron-Prüfung gemeinsam, node:crypto, tote Dateien und vercel.json raus (Deploy A)
- W1: isCronAuthorized(req) in src/lib/timing-safe-compare.ts statt fünf
  gleicher authorized()-Kopien in den Cron-Routen.
- W2: src/lib/auth.ts (getOwnerId) und src/hooks/useActivePet.ts gelöscht —
  keine Aufrufer.
- W3: vercel.json gelöscht (Crons laufen per NAS-Crontab), Vercel-Kommentare
  in den Cron-Routen entfernt, CLAUDE.md/README angepasst.
- W4: timingSafeStringEqual nutzt crypto.timingSafeEqual (Byte-Vergleich);
  proxy.ts läuft in Next 16 auf Node.

Tests für Vergleich und Cron-Prüfung; Produktions-Build lokal grün.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:27:33 +02:00
adminandClaude Sonnet 5 ea3cf1dcd4 fix(admin): music-track upload failing on valid audio files
Two independent root causes behind 'admin music upload fails':

1. Supabase bucket name mismatch — code expects 'music-tracks' (plural,
   MUSIC_STORAGE_BUCKET), but the bucket was created as 'music-track'
   (singular). Every upload failed with a bucket-not-found error from
   Supabase Storage, surfaced only as a generic toast. Fixed by creating
   the correctly-named bucket (public, 5MB limit, audio/mpeg|mp4|aac
   allowed_mime_types matching the app's own constants) via the Supabase
   Storage API; verified end-to-end with a signed-upload-url + PUT probe.
   The old empty 'music-track' bucket is unused but still exists -
   deleting it needs the user's own action (blocked here by the
   auto-mode classifier's cloud-storage-delete guard).

2. Client-side validation trusted the browser-reported File.type, which
   is sniffed from the OS's MIME registry and is inconsistent for
   .m4a/.aac (e.g. Windows Chrome reports .m4a as audio/x-m4a, not
   audio/mp4) - a perfectly valid file could get rejected as 'wrong
   type'. Now derives the content-type from the file extension instead.

Code-reviewed before commit (WORKFLOW.md step 6) - fixed two of four
findings: the extension lookup now uses a Map instead of a plain object
(prototype-shadowing via a file named e.g. 'x.constructor' previously
bypassed the rejection), and requires an actual '.' before the
extension (a bare filename like 'mp3' no longer matches). Extracted the
allowed-types/size constants into a new client-safe src/lib/music-
content-types.ts (supabase-storage.ts re-exports them) so the client
form and server-side Zod schema share one source of truth instead of
two independently maintained copies. Left the trust-the-extension
trade-off as-is (documented in code): this panel sits behind
ADMIN_SECRET + a role check, not the public upload surface, and the
old File.type check was never real content-based validation either.

Full test suite green (one unrelated legal.test.ts timeout in the
full-suite run was confirmed flaky - passes cleanly in isolation).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 18:49:51 +02:00
adminandClaude Sonnet 5 1e8e6bbd7d docs: document Clerk redirect-URL allowlist as the Google SSO gotcha
Google SSO broke live with 'redirect url ... does not match an
authorized redirect URI ... pawfeed://sso-callback', despite the SSO
code (99575dd) being unchanged. Root cause was outside the repo
entirely: Clerk's per-instance authorized-redirect-URL allowlist is
server-side config (CLERK_SECRET_KEY-authenticated Backend API), not
tracked in git, and only had a stale org.pawfeed.app2 entry - the
current pawfeed:// scheme's callback was never registered.

Fixed live via POST https://api.clerk.com/v1/redirect_urls (no app
deploy needed), verified through the Google consent screen on an
emulator and end-to-end by the user on a real device.

Documented in both mobile/found.md (full incident) and README.md's
Known Issues table (the reusable gotcha: check Clerk's redirect-URL
allowlist before debugging app code when SSO breaks unexpectedly).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 18:30:43 +02:00
adminandClaude Sonnet 5 7187fedb38 docs: document AI-assisted dev workflow + system architecture diagram
Adds WORKFLOW.md (the living, discussion-oriented version) and a
contributor-facing summary in README.md, reflecting four automation
decisions made 2026-09-19:
- OTA publish and web rolling-deploy run automatically once
  typecheck+lint+code-review are clean, no per-change confirmation
- a code-review pass (code-review skill - the code-reviewer agent named
  in .claude/rules/ecc isn't installed in this environment) runs on
  every diff before commit
- twin instances of a found bug pattern get fixed in the same pass,
  not just reported
- large mobile features go through a planning step (Plan agent /
  EnterPlanMode - the installed equivalent of the referenced planner
  agent) and their own feature branch, merging to main (and only then
  triggering the automatic deploy) once complete

Also adds a Mermaid system architecture diagram to README.md covering
both clients (web + mobile) against the shared Next.js/tRPC backend,
data/media services, and the two deploy paths (NAS rolling-deploy vs.
EAS Build/Update) - validated by rendering it through mermaid-cli.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 10:05:33 +02:00
adminandClaude Sonnet 5 a39ba76108 docs: document EAS update --platform gotcha and node_modules corruption fix
Two Known-Issues entries from tonight's OTA-publish session:
- eas update needs --platform android explicitly (no web target/
  react-native-web in this project, --platform all fails bundling)
- mobile/node_modules can end up with silently missing nested files after
  a bad install, invisible to npm install itself (seen across @expo/cli,
  @sentry/browser, @sentry-internal/browser-utils in the same session) -
  full rm -rf node_modules && npm install is the fix, not a targeted one

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 22:19:58 +02:00
adminandClaude Sonnet 5 1791aca690 docs+chore: add DB restore script and document backup/restore in README
docker/restore-db.sh - emergency-only, not wired into any crontab. Lists
available backups when run without args; restores via pg_restore
(--clean --if-exists --no-owner --no-privileges -j 4) against DIRECT_URL,
same throwaway postgres:17-alpine container pattern as backup-db.sh.
Requires typing RESTORE to confirm (FORCE=1 skips it for scripted use).

README.md gets a new 'Database backups & disaster recovery' section
(setup step 9) documenting all three scripts, the DIRECT_URL vs
DATABASE_URL reasoning, and the storage-metadata restore caveat. No
admin-panel UI for this by design - restore is SSH-only, deliberately
higher-friction than a browser button.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 20:17:57 +02:00
adminandClaude Sonnet 5 e9bad092f2 feat: pet-suggestion notifications, story music overlay, auth UX fixes
Three pieces of work from this session:

- Pet-suggestion notifications: a weekly cron (species/breed affinity
  heuristic) suggests pets to follow, with an owner opt-out and web/mobile
  notification UI wiring.
- Story music overlay: admin-curated royalty-free track catalog
  (/p/[secret]/music), attachable to stories on web (StoryForm/StoryViewer),
  with mute-original support for video stories. Mobile UI is deferred to
  the next native build (needs an audio-playback module) — tracked in
  mobile/PENDING-NATIVE-BUILD.md.
- Auth UX fixes: sign-in/sign-up now use KeyboardAvoidingView + ScrollView
  and a shared PasswordField with a show/hide toggle (mobile). Web's
  ActivePetContext gained clearGactivePetId(), wired to sign-out via a new
  SignOutCleanup component, fixing a false "you do not have permission to
  access this pet" error after switching accounts on the same browser.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 21:02:49 +02:00
admin f56d1c7cb1 docs: document Clerk German localization, mark Capacitor mobile plan superseded
- README: note @clerk/localizations' deDE usage in the tech stack table
  and shipped-features list.
- ClerkThemeProvider: comment explaining why deDE is needed (Clerk's own
  UI defaults to English regardless of the app's next-intl locale).
- mobil.md: mark the Capacitor plan superseded by the React Native/Expo
  scaffold decided this session (see mobile/README.md).
2026-09-01 20:18:49 +02:00
admin 1b83bb9665 docs: update README, add session handoff, fix deploy-script executable bit
README: document today's shipped work (story reactions/comments, per-pet
insights dashboard, DESIGN.md/PRODUCT.md design system, admin panel visual
pass) in "What's Shipped" and the admin panel section.

docker/rolling-deploy.sh and start.sh were tracked as 100644 (no executable
bit) since this repo is worked from Windows, which never records it — every
fresh git pull onto the Linux NAS made them non-executable again. Fixed via
git update-index --chmod=+x so this doesn't recur.
2026-08-25 19:24:52 +02:00
admin 4414ef12ed docs: update README to current state, add domain glossary
- CSP: Report-Only -> enforced (nonce + strict-dynamic, Mozilla A+)
- Add Stripe/SponsorContribution, Broadcast/BroadcastReceipt (missing
  from tech stack, model overview, admin panel description, shipped
  features) — both real, deployed features the README never mentioned
- Species list: 3 examples -> the actual 16-category taxonomy
- Known Issues: NPM origin-cert quirk, 401-vs-403 admin debugging note
- New Glossary section: Owner/Pet/Post/Milestone/... relationships
2026-08-22 15:59:29 +02:00
admin 6a61bbcc81 feat(docker): zero-downtime rolling deploy for the 3 replicas
Adds a dependency-free liveness endpoint (GET /api/health), a Docker
healthcheck against it, and docker/rolling-deploy.sh which rebuilds
the shared image once and restarts pawfeed-1/2/3 sequentially, gated
on each becoming healthy before moving to the next. Verified
zero-downtime via continuous curl monitoring through a full run
against production.
2026-08-16 13:17:04 +02:00
admin 1e060e9179 feat(docker): scale to 3 load-balanced replicas (Gitea #26)
Next.js standalone is single-process, so one container only used one
CPU core. A load test hit a hard ceiling at ~60-65 req/sec with one
core pegged at 133% while 3 cores sat idle. Now runs as pawfeed-1/2/3
behind an NPM least_conn upstream, verified via load test showing CPU
spread evenly across all three replicas.

Also caps the Prisma pg pool per-replica via DB_POOL_MAX so 3 replicas
stay well under the Supabase pooler's connection limit.
2026-08-16 11:38:05 +02:00
admin e958f38575 docs: bring README up to date with current tech stack and architecture
Tech stack table was describing the original MVP plan (Vercel, Upstash
Redis, middleware.ts) rather than what's actually running: self-hosted
Docker deployment, self-hosted Redis, next-intl i18n, dark mode,
GlitchTip/Sentry monitoring, CSP, and the admin/moderation panel built
since. Also refreshes the project structure tree, Prisma schema
overview, and setup instructions to match the current codebase.
2026-08-13 21:17:42 +02:00
adminandClaude Sonnet 4.6 38952b1563 docs: update README with v2 features, full schema overview, and next-session roadmap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:03:01 +02:00
adminandClaude Sonnet 4.6 80559c3b3f feat(health): health card share link, PDF export, weight chart in card
- ShareDialog: expiry selector (7/14/30/60/90 days, default 14), shows
  expiry date after generation, "Als PDF öffnen / drucken" button
- WeightChart extracted to standalone component (WeightChart.tsx) so it
  can be shared between HealthDashboard and the public health card page
- Health card page: renders WeightChart when 2+ weight entries exist
- AutoPrint client component: auto-triggers window.print() when card is
  opened with ?print=1 (600ms delay for render to settle)
- README: Phase 6 + Phase 7 marked complete with full feature summaries;
  project structure and router list updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 06:06:28 +02:00
adminandClaude Sonnet 4.6 1fc69add4d docs: update README to reflect Phases 1-5 complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 08:44:48 +02:00
adminandClaude Sonnet 4.6 b71edfa758 docs: update README — Phase 3 in progress, plan 1/6 complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 11:37:04 +02:00
admin 273d412fb4 docs: add README with setup, architecture, progress and debugging notes 2026-06-13 10:25:30 +02:00