Commit Graph

12 Commits

Author SHA1 Message Date
Claude
c7900c60d0
feat: implement admin panel and event management
API (apps/api/src/routes/admin.ts):
- GET /api/admin/me, /event, /uploads, /stats
- PATCH /api/admin/event for live config edits
- POST /api/admin/uploads/:id/{approve,reject}
- DELETE /api/admin/uploads/:id (also removes the object from R2)
- ZIP export and bulk import remain as 501 for the next iteration

Web (apps/web/src/routes/admin/Dashboard.tsx):
- Single-page dashboard with stats cards, event config form,
  filterable uploads grid (all/pending/approved/rejected) with
  per-card approve/reject/delete, infinite "load more", and a
  PDF QR shortcut in the footer.
- Logout via Cloudflare Access /cdn-cgi/access/logout.

Shared (packages/shared/src/schemas.ts):
- New zod schemas for AdminUpload, AdminUploadsResponse, AdminStats
  so the client and server agree on the admin payload shape.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 03:01:08 +00:00
Claude
913dc2b93d
fix: derive QR target URL from request, not stale env var
PUBLIC_BASE_URL was pointing to the planned pages.dev domain that
was never wired up, so QR codes encoded a non-functional URL. Use
the request's own origin as the source of truth (which also handles
custom domains automatically when added later) and only fall back
to PUBLIC_BASE_URL when an explicit override is passed via ?url=.
Also update PUBLIC_BASE_URL to the actual workers.dev hostname so
nothing else points at the wrong place.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 02:50:59 +00:00
Claude
516def235a
feat: add QR code endpoint with PNG/SVG/PDF formats
GET /api/qrcode returns the QR for the upload URL of the event.
?format=png (default, 800px) for screen, ?format=svg for vector, and
?format=pdf for an A6 printable card with the couple's names, the
event date (if set), and a "Aponte a câmera" instruction. The
encoded URL defaults to the request's origin + /enviar so it works
across environments without extra config; ?url= overrides for tests.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 02:42:29 +00:00
Claude
a27782e4de
fix: use path-style URLs for R2
The presigned PUT URLs were missing the bucket name (only the key),
so R2 read 'uploads' as the bucket, returned a 404 with no CORS
headers, and the browser reported it as a CORS failure. Switch to
path-style so the URL becomes
<account>.r2.cloudflarestorage.com/wedding-media/<key>, which R2
recognizes and applies the bucket's CORS policy to.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 02:35:10 +00:00
Claude
7a60f1777c
fix: keep upload pending until /confirm
Single-PUT init was inserting rows with status='approved' (skipping
the confirmation step), so a failed browser->R2 PUT left ghost
entries that the gallery happily listed. Always start as 'pending';
the existing /confirm flow is the only place that should approve.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 02:21:27 +00:00
Claude
dbfd917e50
feat: implement guest upload flow and public gallery
Backend:
- POST /api/uploads/init validates against event_config (size, video
  policy, duration), creates an uploads row, and returns either a
  single presigned PUT or a multipart batch of presigned part URLs
  depending on file size (50 MB threshold, 10 MB parts).
- POST /api/uploads/:id/confirm completes multipart on R2 if needed,
  HEADs the object to verify upload, and flips status to approved
  (post-moderation) or pending (pre-moderation).
- POST /api/uploads/:id/abort cancels in-flight multipart and removes
  the row.
- GET /api/gallery returns approved uploads in cursor-paginated
  reverse chronological order, with public R2 URLs.
- GET /api/stats returns lightweight counts for future home/admin use.

Frontend:
- lib/upload.ts handles single and multipart uploads via XHR with
  progress callbacks, video duration extraction, and abort signals.
- /enviar: real form with file picker (image/video), author name,
  message, per-file progress, multi-file support, and a success state.
- /galeria: responsive grid of approved items with lazy-loaded images,
  video preview tiles, infinite "load more", and a fullscreen lightbox
  showing the author and message.

Schema: turnstileToken is now optional so the MVP works without
Turnstile wired up; we layer it back in later.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 02:08:00 +00:00
Claude
4f85dd8721
chore: pin R2 endpoint and public URL in wrangler vars
Now that the bucket and r2.dev subdomain are provisioned, commit
the URLs as wrangler [vars] so deploys are reproducible without
relying on dashboard-managed plain-text variables. Only the access
key and secret remain dashboard-only secrets.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 02:01:12 +00:00
Claude
11a81975ff
fix: use boolean run_worker_first for wrangler 3.x compat
The array form of run_worker_first requires wrangler 4. Cloudflare
Build's local install resolves wrangler 3.x from our pinned devDep,
so switch to run_worker_first = true. The worker already handles
routing (/api/* -> Hono, else -> ASSETS), so semantics are unchanged.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 01:29:29 +00:00
Claude
11167e48f3
refactor: migrate web app to Workers + Static Assets format
The Cloudflare project was created as a Workers Build (the new
unified format), so the legacy Pages config (pages_build_output_dir,
functions/api/[[path]].ts) does not deploy. Switch to the modern
shape: a worker entry point that delegates to the Hono app for
/api/* and falls through to the [assets] binding for everything
else, with SPA fallback for client-side routes.

Build output (apps/web/dist) and bindings (D1, R2, env vars) are
unchanged.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-04 00:57:28 +00:00
Claude
89b1221706
fix: web build typescript errors
- Drop tsconfig.node.json: composite + noEmit conflict, and the
  vite.config.ts doesn't need its own project / node types.
- Inline vite.config.ts in the main tsconfig include list.
- Switch web build from `tsc -b` to `tsc --noEmit` since there are
  no project references anymore.
- Make b64urlDecode return Uint8Array<ArrayBuffer> so its output
  is accepted by crypto.subtle.verify under stricter lib types.
- Cast the Pages EventContext to ExecutionContext when forwarding
  to Hono; props is unused at runtime.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-03 23:56:44 +00:00
c0a15ae730
Atualizar o wrangler.toml 2026-05-02 13:31:53 -03:00
Claude
be13179832
chore: scaffold Cloudflare Pages monorepo for wedding photos app
Set up pnpm workspaces with three packages: a shared Zod-schema
package, a Hono-based API exported as a library, and a Vite/React/
Tailwind frontend that mounts the API via Cloudflare Pages Functions.
Storage is abstracted behind an S3-compatible provider so the project
can migrate from R2 to a self-hosted MinIO without code changes.

https://claude.ai/code/session_01TPBqgcSJMppgrpiq7fLywL
2026-05-01 23:30:50 +00:00