Files
Calendar_Frontend/docs/deployment.md
PaddyandClaude Opus 5.5 0cda40f85e Rewrite the calendar frontend in Next.js
Replaces the Angular 18 app with Next.js 16 / React 19 / Tailwind 4 / shadcn,
the same stack and design system as nachklang-feedback, planned in
docs/rewrite-plan.md.

- Admin: all calendars in one mobile-friendly list (month groups, calendar
  chips, Kommend/Vergangen/Alle, search, sort, filters in the URL), an edit
  sheet for create/edit/duplicate/delete, publish confirmation, and an
  "Abonnieren" dialog with subscription links for every calendar.
- Public landing page: subscribe links from env instead of hardcoded, plus
  the next public events, server-rendered and revalidated every 5 minutes.
- All times handled explicitly as Europe/Berlin; whole-day events stored as
  00:00-23:59. Fixes carried over from the Angular app: the move dialog
  leaking a cancelled calendar change, saves that looked saved when they
  failed, in-place Date mutation, and duplicated calendar-id mappings.
- Same shared-session auth as before (proxy.ts gate, /admin/me, 401 vs 403).
- 112 Vitest tests over lib/; docs in docs/ (architecture, features,
  gotchas, API wish list, deployment).

Needs the API branch feature/calendar-ical-escaping-subscriptions deployed
first (GET /calendar/events/subscriptions).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:15:59 +02:00

70 lines
3.3 KiB
Markdown

# Deployment and switchover
How the Next.js app replaces the Angular build on `calendar.nachklang.art`. **The deploy itself is
done by a person** (never by Claude). Steps marked *unverified* could not be checked without access
to the Plesk server.
## Order matters
1. **API first**: merge and deploy the API branch `feature/calendar-ical-escaping-subscriptions`
(rebuild + restart; no new env vars - it uses the existing `API_BASE_URL` and
`*_CREDENTIAL` values). The old Angular app keeps working against it; the new app's "Abonnieren"
dialog needs it.
2. **Then the frontend.**
## Build
Node version: `.nvmrc` says 26, copied from the API repo - *unverified* that Plesk offers it; use
the version the API runs on.
```bash
npm ci
NEXT_PUBLIC_API_BASE_URL=https://api.nachklang.art \
NEXT_PUBLIC_ADMIN_APP_URL=https://admin.nachklang.art \
npm run build
```
- Both values are **inlined at build time** - they must be set for `npm run build`, not just at
runtime. (Values from the Angular `environment.prod.ts`.)
- `npm run build` runs `postbuild`, which copies `.next/static` into `.next/standalone/.next/static`.
Without it the standalone server serves the pages without CSS and JS.
- The build fetches the public events from the API to prerender `/`. If it can't reach the API it
still succeeds.
## Run (Plesk Node.js / Passenger)
- Application startup file: `.next/standalone/server.js`.
- The server listens on `PORT` (and `HOSTNAME`). Whether Passenger sets `PORT` itself or needs it
configured is *unverified* - check how the feedback app is set up on the same server.
- Optional runtime env: `API_BASE_URL` (internal address for the landing page's server-side fetch).
- The subdomain changes from serving static files to a Node.js app. *Unverified* how Plesk handles
that switch for an existing domain (document root vs. application root).
Checked locally (2026-09-28): `PORT=4300 node .next/standalone/server.js` serves `/` with events,
CSS/JS (200), the favicon, and redirects `/admin` without a cookie to `/admin/login`.
## Things that must already be true (unchanged from the Angular app)
The origin stays `https://calendar.nachklang.art`, so nothing should need changing - inferred from
the Angular app already using the same cookie auth:
- the API's CORS list contains `https://calendar.nachklang.art` (verified in `app.factory.ts`);
- the admin app's `NEXT_PUBLIC_ALLOWED_REDIRECT_ORIGINS` contains it (otherwise signing in lands on
the admin start page instead of coming back);
- the API's better-auth trusted origins contain it (otherwise sign-out fails).
## Smoke test after the switch
1. `/` loads styled, shows "Nächste Termine", and the Apple link opens a subscription.
2. `/admin` while signed out → admin login → back to `/admin` after signing in.
3. The list shows all calendars; an edit saves; "Abonnieren" lists links.
4. An account without calendar permission sees "Kein Zugriff" (no redirect loop).
5. "Abmelden" signs out and offers to sign in again.
6. On a phone: list, "+" button, bottom sheet.
7. An existing iCal subscription still updates (the feed URL is unchanged).
## Rollback
Keep the last Angular build (`dist/nachklang-calendar`) for about a week and switch the subdomain
back to it if needed. The API change is backwards compatible with the Angular app, so it can stay.