Commit Graph
14 Commits
Author SHA1 Message Date
maroandClaude Sonnet 5 8d60d48bd0 Fix .env writer: quote values so shell metacharacters don't break source
CI / test (push) Successful in 3m14s
deploy.sh sources .env directly as bash (`set -a; source .env`), but
setup.sh wrote raw unquoted values. The default SMTP_FROM ("ANOUMA
<no-reply@...>") contains `<`/`>`, which bash parses as redirections,
failing with "syntax error near unexpected token `newline'" on every
deploy. Both scripts' env_set now write double-quoted values with
backslashes/quotes escaped — valid for both `source` and Docker
Compose's env_file parsing (which strips matching quotes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 02:12:24 +02:00
maroandClaude Sonnet 5 8d88363583 Fix release deploy: use bash for the deploy step's set -o pipefail
CI / test (push) Successful in 3m14s
Release / test (push) Successful in 3m10s
Release / build-and-deploy (push) Successful in 43s
Gitea Actions runs `run:` steps with `sh` by default, which doesn't
support bash's `set -o pipefail` ("Illegal option -o pipefail",
exit 2). node:22-bookworm-slim (Debian) includes bash, so declaring
shell: bash for this step fixes it without changing the base image.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 01:13:45 +02:00
maroandClaude Sonnet 5 eca8e24fd9 Fix release deploy: use a Node-based image so checkout's JS action runs
CI / test (push) Successful in 2m58s
Release / test (push) Successful in 3m0s
Release / build-and-deploy (push) Failing after 36s
docker:27-cli is Alpine with no Node.js, but actions/checkout@v4 is a
JS action that needs a Node runtime in the job container — it failed
at Checkout with exit 127. node:22-bookworm-slim already has Node
(same reason the test job's node:22-alpine works); Docker CLI and
openssh-client are added via apt instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 00:42:29 +02:00
maroandClaude Sonnet 5 517f640666 Fix release deploy: give build-and-deploy a container with Docker CLI
CI / test (push) Successful in 3m5s
Release / test (push) Successful in 3m0s
Release / build-and-deploy (push) Failing after 10s
The runner (gitea-anouma-runner) runs as a Docker container itself
(gitea/runner:3) with the host's docker.sock mounted in, but no
`docker` CLI binary. A job with no `container:` runs directly inside
that minimal runner image, so `docker login/build/push` failed with
"docker: command not found". Using docker:27-cli gives the job the
CLI; the runner mounts the same host socket into it automatically
(sibling containers), and openssh-client is installed for the deploy
step's ssh call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 00:33:10 +02:00
maroandClaude Sonnet 5 27aa625c0e Fix CI: run next typegen before tsc so route-aware types resolve
CI / test (push) Successful in 3m14s
Release / test (push) Successful in 3m7s
Release / build-and-deploy (push) Failing after 34s
This Next.js version generates LayoutProps/PageProps/RouteContext
into .next/types only via `next dev`, `next build`, or `next typegen`
(see node_modules/next/dist/docs .../06-cli/next.md). Typecheck ran
`tsc --noEmit` standalone before Build, so those globals didn't exist
yet, failing with "Cannot find name 'LayoutProps'".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 23:46:32 +02:00
maroandClaude Sonnet 5 bd38781502 Fix CI: scope NODE_ENV=production to the build step only
CI / test (push) Failing after 1m24s
Setting it job-wide made `npm ci` treat NODE_ENV=production as an
implicit --omit=dev, silently skipping eslint/typescript/test
devDependencies and failing Lint with "eslint: not found".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 23:43:12 +02:00
maroandClaude Sonnet 5 0cb99243c7 Trigger empty commit to test Gitea Actions after moving repo hooks to local disk
CI / test (push) Failing after 48s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 23:40:42 +02:00
maroandClaude Sonnet 5 5af7158368 Trigger empty commit to re-test Gitea Actions after hook resync
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 23:17:35 +02:00
maroandClaude Sonnet 5 8c2aadeda0 Trigger empty commit to test Gitea Actions/webhook pipeline
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 23:10:44 +02:00
maroandClaude Sonnet 5 56b2a6497b Overhaul deployment to Gitea Actions CI/CD, remove update.sh
Production no longer builds from source or self-updates via cron/git pull:
setup.sh now only provisions the server once (Docker, /opt/anouma, a
restricted `anouma-deploy` SSH user whose key can only ever run
deploy.sh, generated secrets). All future deployments run through
.gitea/workflows/ci.yml (lint/typecheck/test/build on every push) and
release.yml (on a vX.Y.Z tag: build the image, push it to the Gitea
registry, then SSH-trigger deploy.sh on the server), which pulls,
migrates, restarts, healthchecks, backs up the database first, and
automatically rolls back the code on a failed healthcheck.

docker-compose.yml's app service now runs a registry image
(${ANOUMA_IMAGE}) instead of building locally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 22:58:09 +02:00
maroandClaude Sonnet 5 1cd15aff25 Add email verification, personal calendar feed, and full SEO implementation
- Customer accounts now require email verification (hashed, single-use,
  time-limited tokens) before they can request/confirm bookings, with
  resend flows on login/account/booking widget and rate limiting.
- Admins get a private, rotatable iCalendar (ICS) subscription feed of
  their confirmed bookings and public events, timezone-correct for
  Europe/Berlin including DST, never exposing meeting passwords.
- Adds a full SEO layer: per-page canonical/OG/Twitter metadata with
  CMS-editable overrides and content-derived fallbacks, a dynamic
  sitemap.xml and robots.txt driven by real published content, JSON-LD
  (Organization/LocalBusiness, WebSite, WebPage, BreadcrumbList, Service,
  Event, BlogPosting) that never fabricates data, and a CMS-managed
  redirect table for changed slugs.
- Global ANOUMA-naming audit: the brand name is never used to label
  personal account/calendar areas anywhere in the app, CMS, or emails.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 22:57:31 +02:00
maroandClaude Sonnet 5 50c39a70e0 Add full Docker deployment: setup.sh, update.sh, healthcheck, TURN support
- setup.sh: interactive/non-interactive one-shot installer (build, DB
  healthcheck, migrate, seed, start), idempotent secret generation, NPM
  reverse-proxy network auto-detection and optional join, optional
  AUTO_UPDATE cron install.
- update.sh: release-tag-gated updates only (never bare main), DB backup
  with retention before every update, lock file against concurrent runs,
  automatic code rollback on failed post-update healthcheck.
- Dockerfile: multi-stage build, non-root user, built-in HEALTHCHECK against
  the new /api/health route, wholesale COPY so new source dirs (e.g.
  scripts/) never silently go missing at runtime.
- docker-compose.yml: internal anouma-network (configurable), named volume
  for Postgres, app depends_on postgres healthy, no unnecessary published
  ports; docker-compose.override.yml.example documents joining an existing
  NPM network without ever touching NPM itself.
- Fix host-detection: isHost was Boolean(user), wrongly granting host
  privileges to logged-in customers; now checks user.collection === "users".
- Wire configurable STUN/TURN servers through to the WebRTC client
  (lib/meeting/iceServers.ts) so a TURN server can be added later via env
  vars only, no code changes.
- DEPLOYMENT.md, updated README.md and .env.example documenting the whole
  flow: NPM integration, env vars, WebRTC, updates, backups, rollback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 21:50:28 +02:00
maro d3d53e68a9 Ignore stray installer files (.rpm/.deb/.AppImage) to avoid accidental commits 2026-08-25 21:13:35 +02:00
maro 5d83c0dc1e Add calendar-based booking system: accounts, availability, admin calendar
- Customer accounts (separate auth collection) with /konto area
- Availability + AvailabilityOverrides collections driving real slot calculation
- BookingRequests with race-safe confirmation (Postgres advisory lock + transaction)
- Booking emails (request received, admin notify, confirmed, rejected, alternative proposed/accepted, cancelled)
- Confirmed online bookings auto-create a private linked video-call Event
- Custom Payload admin calendar view (month grid + day schedule)
- Wired booking widget into offer pages and /termin-buchen
2026-08-25 16:52:34 +02:00