Commit Graph
29 Commits
Author SHA1 Message Date
NeilClack 220ff92e78 Portal: fix schedule type toggle, daily rendering, overnight spill, and mobile grid 2026-09-29 15:22:02 -05:00
NeilClack e6021a6345 test: Phase 5 verification scripts and opt-in e2e integration spec
Adds scripts to seed scenario data, create Proclamations, snapshot schedules,
drive the Kiosk-facing HTTP endpoints, and an opt-in (P5_INTEGRATION=1)
Vitest spec exercising create/type/copy against a scratch database. The
integration spec is skipped by default so the normal suite needs no DB.
2026-09-29 12:46:04 -05:00
NeilClack 68a979f1a1 Portal: transactional schedule copy service
copySchedule copies one License Key's Schedule to one or more other keys by
value in a single Prisma transaction (all targets or none), assigning fresh
Block IDs and preserving each block's dynamicAudio and Proclamation order.
Source/targets are scoped to the caller's account; self-copy and empty
target lists are rejected. The resulting schedule is run through the shared
validator before commit. Adds tests: daily/weekly copy, overwrite, multiple
targets, rollback, cross-account rejection, new IDs, changed version/ETag,
copy independence, and Kiosk-payload parity with the shared fixtures.
2026-09-29 10:49:06 -05:00
NeilClack 3bb8e0189b Portal: per-license schedule service, shared validator, and key-only GET
Implements the shared validateSchedule validator (daily + weekly, midnight
spillover, Sunday->Monday wrap, adjacency, empty-block rejection), a
per-License-Key schedule service (get/set type, CRUD blocks, weekly
prefill with confirmation), the content-hash version/ETag serializer, the
new GET /api/v2/licenses/[licenseKey]/schedule (200/304/404, type null),
and additive evolution of the legacy GET /api/v2/schedule. Adds validator,
serializer (against docs/fixtures), endpoint ETag/304, and service tests.
2026-09-29 10:23:10 -05:00
NeilClack 8412dfb69c Portal: System Name PUT endpoint and license-validation status
Add PUT /api/v2/licenses/[licenseKey]/system-name (200/400 invalid_name/
404 unknown_license/409 name_taken, idempotent) and extend POST
/api/v2/license with an optional systemName and additive systemNameStatus
(ok/unchanged/conflict/invalid). Validation always succeeds; an omitted
field never changes or clears a name and empty/whitespace is invalid.
Adds server and helper tests covering trimming, bounds, case-insensitive
uniqueness, cross-account reuse, 404, and idempotency.
2026-09-29 09:51:54 -05:00
NeilClack 179df1e252 Portal: 12-hour schedule times and dynamicAudio default on
Use TimeInput for Block start/end and show the day timeline axis with
AM/PM, so no 24-hour time is displayed in the schedule UI. New Blocks now
default dynamicAudio to true in the modal and server-side when the field
is absent; existing stored Blocks are untouched.
2026-09-29 08:53:22 -05:00
NeilClack ec826093eb Expose dynamic audio on the v2 schedule API 2026-09-11 18:41:57 -05:00
NeilClack 96a1342c10 Add Enable Dynamic Audio option to schedule blocks 2026-09-11 18:41:53 -05:00
NeilClack 177b7bb13a Flag overnight blocks in the v2 schedule API 2026-09-11 18:24:51 -05:00
NeilClack 545fb22910 Add v2 schedule API endpoint 2026-09-11 18:16:04 -05:00
NeilClack 4922e941ae Add schedule validation and service layer 2026-09-11 18:16:00 -05:00
NeilClack d16965dab6 Add AuditLog table and Prisma audit extension 2026-09-10 15:10:11 -05:00
NeilClack 0cb4b2148a Expose roleId on the Better Auth session user 2026-09-10 14:59:28 -05:00
NeilClack 29d53af8dd Remove unauthenticated /send email endpoint 2026-09-10 14:14:44 -05:00
NeilClack 84c905c9ff Add shared registration invite helper and use it for admin-created users 2026-09-10 14:08:51 -05:00
NeilClack 5ec3018f8b Email a set-password link when an admin creates a user 2026-09-10 13:42:33 -05:00
NeilClack 91d162c746 Rebuild admin pages around DataTable/AdminModal; restructure categories/groups and v2 groups API
Remove the generic $lib/svelte-admin CRUD layer and AdminTable.svelte; each
admin route now owns its own form/modal logic. Add DataTable.svelte,
superform-errors.ts, and profile-specific modal/field components.

Flatten proclamation categories/groups and drop subscription levels; add the
v2 groups API; update v1/v2 endpoints, serializers, auth, and regenerated
Prisma client with the new migrations.

Document the overhaul plan in docs/ADMIN_OVERHAUL.md.
2026-09-10 09:38:01 -05:00
NeilClack 64f7070ad7 Build API v2 2026-08-07 14:06:20 -05:00
NeilClack c52474d69b Update environment variables in resend module 2026-07-17 12:42:42 -05:00
NeilClack fd630ff714 Resolve build errors 2026-07-17 11:51:14 -05:00
NeilClack 2d0cf98ed3 fix tests: add subject to email-verification assertion, add url + api-key mock to hooks test 2026-07-08 15:36:11 -05:00
NeilClack 92f54e829e add subject line to verification email 2026-07-08 15:29:45 -05:00
NeilClack 46b2cdf53d api: API key authentication with rotation and grace period
- Add ApiKey Prisma model (keyHash, expiresAt, revokedAt)
- Protect /api/v1/* routes with Authorization: Bearer header check in hooks
- create rotateApiKey() utility: normal (48h grace) and emergency (immediate)
- Add Super-only /admin/api-keys page for key rotation with one-time reveal
- Fix roleId check by using parent layout's DB-fetched adminUser
- Add API Keys link to admin sidebar
2026-07-08 13:18:19 -05:00
NeilClack 38d1752f5b admin: Superforms + Zod validation, three-address-defaults schema, profiles toast fix
- Add Superforms + Zod 4 for all admin form validation
- Replace address isDefault with three separate boolean defaults (Mailing, Billing, Shipping)
- Update profiles page with three-checkbox address form and toast improvements
- Convert all admin page server actions to pass request directly to crud
- Export superFormErrorsToFieldErrors helper for profiles server actions
- Regenerate Prisma client for new schema fields
2026-07-07 13:36:23 -05:00
NeilClack 6ff8e878a4 test: add unit tests for all auth backend logic
- Register: edge cases for non-Error throws, error message assertions,
  and verify signUpEmail was called with correct payload
- Forgot-password: empty/missing email, Error/non-Error throws
- Reset-password: load (missing/expired/valid token) and action (short
  password, mismatch, throw, success redirect)
- Account setup: load (unauthorized, returns user), action (redirect,
  falsy create, throws, isRedirect passthrough)
- Email-verification: correct URL construction, sendMail delegation,
  throw propagation
- Hooks: sets/omits locals, passes building/auth to svelteKitHandler
- Fix Svelte 5  warning on setup page by using  with
  one-time guard instead of top-level prop read
2026-07-07 09:22:56 -05:00
NeilClack 209fd8456d auth: show email verified banner on login page after verification
- Append ?verified=true to callbackURL in verification link
- Login page reads query param and shows green success banner
  when user lands after email verification
2026-07-07 09:10:11 -05:00
NeilClack 667ae4e05e auth: build verification link from BASE_URL env var
- Build the verification URL as /api/auth/verify-email?token=xxx&callbackURL=/login
- Pass token from Better Auth callback instead of its built-in url
- Add callbackURL=/login so user lands on login after verifying
2026-07-07 08:59:25 -05:00
NeilClack ba83c48b9e auth: extract reusable sendVerificationEmail utility, enable sendOnSignUp
- Create src/lib/server/email-verification.ts with exported utility function
- Use it in auth.ts sendVerificationEmail callback
- Enable sendOnSignUp so verification email is sent on registration
2026-07-07 08:54:47 -05:00
NeilClack a42c32f014 Add email via Resend 2026-07-06 21:01:41 -05:00