Backend returns 500 instead of 409/422 for duplicate usernames. Patch
both the profile update action and the onboarding completeProfile action
to intercept status 500 and surface it as a field-level error on the
username input rather than a generic top-level alert.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
superValidate with start_time/end_time: '' returns datetime validation
errors which superForm shows immediately on load. { errors: false } tells
superforms not to validate the default values — errors only appear after
the user attempts to submit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
z.string().datetime({ local: true }) accepts both datetime-local strings
("YYYY-MM-DDTHH:mm") for client-side form validation and UTC ISO strings
("...Z") received by the server after onSubmit conversion. The stricter
z.string().datetime() (no local: true) rejected the datetime-local strings
set by the $effect pre-fill, showing false validation errors on page load.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show the presenter's linked name beneath each item in the
published schedule. Fixes stale DataAgendaDoc refs now that
getAgendaSchedule returns ServiceAgendaAgendaListItem[].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
resolve() prepends the /app base path, but page.url.pathname already
includes it — causing double /app/ in pagination hrefs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Admin agenda page: approved items now sorted by start_time (nulls/zero-dates last)
- AgendaSchedule: group items by day with M月D日 header above each group
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends agendaItemSchema with a required coerced integer estimatedTime
(1–999 minutes) for the agenda submit flow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced raw ISO string slicing with dayjs.utc() formatting, consistent
with the rest of the codebase, so agenda item times are not shifted by
the browser's local timezone offset.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The backend returns naive datetime strings already in UTC+8. dayjs was
re-applying the browser's local +8 offset, shifting date labels by one
day. Centralise dayjs configuration in src/lib/dayjs.ts with the UTC
plugin and switch all event start/end date formatting to dayjs.utc() so
the string is read as-is without timezone conversion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Username: 3–32 → 5–255. Nickname: max 64 → max 24 (UTF-8 rune limit).
Applied to both onboarding and profile schemas.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also fixes the `completeProfile` form action: SvelteKit only supports form
actions in `+page.server.ts`, not `+layout.server.ts`. Moved the action to a
dedicated `/(app)/onboarding/+page.server.ts` and updated the dialog form's
`action` attribute to the absolute path `/app/onboarding?/completeProfile`.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Routes Sentry envelopes through a first-party /app/vitals endpoint
instead of directly to *.ingest.sentry.io. DSN host and project ID
are validated server-side from the SENTRY_DSN env var before proxying.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>