docs(launch): website-integration env vars + cutover sequence

deployment-plan.md gains a full env-var reference (CRM + website) and the cutover env-flip sequence; launch-readiness.md gets the 2026-06-02 closeout; BACKLOG.md adds the deferred integration-health-panel idea (section L).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 17:22:12 +02:00
parent 990b566eff
commit 0416dc8d39
3 changed files with 158 additions and 1 deletions

View File

@@ -97,7 +97,7 @@ nginx vhost exists yet (fresh setup). Template: `portnimara_dev.conf`
1. Create `/etc/nginx/sites-available/crm_portnimara.conf` modelled on
`portnimara_dev.conf`: port-80 → 443 redirect + `.well-known/acme-challenge`
location; port-443 server `proxy_pass http://127.0.0.1:7100` with the same
header block (Host, X-Real-IP, CF-Connecting-IP, X-Forwarded-_, websocket
header block (Host, X-Real-IP, CF-Connecting-IP, X-Forwarded-\_, websocket
`Upgrade`/`Connection` for socket.io), `client_max_body_size 64M`,
`proxy_read_timeout 300`, buffering off. **HTTP-only first** (no `ssl\__`
lines yet) so Certbot can complete the challenge.
@@ -236,3 +236,74 @@ successfully applied`, 140→157, none unfinished), app boots (home 302,
removed; restored clone gone, off-box dump retained). Compose file kept
at `private/documenso-dryrun/docker-compose.yml` for a re-run. Prod
still untouched.
---
## Environment variables — initial deployment + cutover
> Single source of truth for the env each instance needs for the
> website<->CRM integration (added 2026-06-02). **Every website-side CRM
> var is a no-op when unset**, so the marketing site behaves exactly as
> today until these are filled at cutover. Full CRM schema: `src/lib/env.ts`.
### CRM instance (`crm.portnimara.com`)
| Var | Value | Notes |
| ------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `APP_URL` | `https://crm.portnimara.com` | Absolute URLs + email links (the inquiry sales-alert "Open in CRM" button). |
| `WEBSITE_INTAKE_SECRET` | shared secret | **MUST equal** the website's `CRM_INTAKE_SECRET`. If unset, `/api/public/website-inquiries` returns **503** and refuses all intake. |
| `EMAIL_REDIRECT_TO` | **unset in prod** | Dev-only reroute; the prod build guard fails if it is set. |
| `DATABASE_URL`, `REDIS_*`, storage/MinIO, `DOCUMENSO_*`, `SMTP_*`, better-auth secret | per `.env` | Standard (see Phase 1 Pre-flight). |
Per-port **settings** (stored in `system_settings`, set via Admin UI — NOT env):
- `website_intake_email_enabled` — boolean, **default OFF**. Flip ON at
cutover so the CRM sends the registrant confirmation + staff alert for
website inquiries (berth / residence / contact), reusing the branded
templates + per-port From. Keep OFF until the website's own sending is
turned off (see `WEBSITE_INQUIRY_EMAILS_DISABLED`) to avoid double-sends.
- `inquiry_notification_recipients` (JSON string[]) — staff who receive
berth + contact-form inquiry alerts.
- `residential_notification_recipients` (JSON string[]) — staff who receive
residence inquiry alerts.
- `inquiry_contact_email` (string) — fallback alert recipient + reply-to.
### Website instance (Nuxt marketing site — repo `ron/website.git`)
New vars for the CRM integration (read via `process.env` in Nitro;
**all no-op when unset → site unchanged**):
| Var | Value | Enables | Set when |
| --------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `CRM_INTAKE_URL` | `https://crm.portnimara.com` (bare host, no trailing slash) | Inquiry dual-write delivery + base URL for the berth feed | Cutover (safe earlier; just starts populating `website_submissions`) |
| `CRM_INTAKE_SECRET` | shared secret | Auth for the dual-write (`X-Webhook-Secret`); **MUST equal** CRM `WEBSITE_INTAKE_SECRET` | With `CRM_INTAKE_URL` |
| `CRM_BERTHS_ENABLED` | `1` (or `true`/`yes`) | Switches the public berth map/list to read from CRM `/api/public/berths` instead of NocoDB (requires `CRM_INTAKE_URL`) | Cutover, after CRM berth data is migrated + verified |
| `WEBSITE_INQUIRY_EMAILS_DISABLED` | `1` | Turns OFF the website's own Gmail confirmation + alert emails, handing email ownership to the CRM | Cutover, flipped **together** with CRM `website_intake_email_enabled = ON` |
UTM: **no env var** — cookieless; the client plugin reads `utm_*` from the
landing URL and forwards them via an `x-utm` header.
Existing website env (keep, unchanged): NocoDB url/token, SMTP user/pass,
`alertRecipientsBerths/Residences/Contact`, `RECAPTCHA_SECRET`,
`NUXT_PUBLIC_RECAPTCHA_SITE_KEY`, Directus url. NocoDB stays as the berth
fallback + the dual-write's primary target until the old system is retired;
SMTP + alert recipients stay until `WEBSITE_INQUIRY_EMAILS_DISABLED` is set.
### Cutover env-flip sequence (website)
1. Confirm CRM is up, berth data migrated, and `WEBSITE_INTAKE_SECRET` set on the CRM.
2. Set website `CRM_INTAKE_URL` + `CRM_INTAKE_SECRET` → verify a test inquiry lands in `website_submissions`.
3. Flip CRM `website_intake_email_enabled = ON` **and** website `WEBSITE_INQUIRY_EMAILS_DISABLED = 1` together → CRM is the single email owner.
4. Set website `CRM_BERTHS_ENABLED = 1` → public map reads from the CRM.
5. Watch errors; rollback = unset the website vars (instant revert to NocoDB + website email).
## Progress log (cont.)
- 2026-06-02: **Website integration prep (local only; no prod changes, nothing pushed).**
Website repo (`main`, uncommitted): env-gated berth feed (`CRM_BERTHS_ENABLED`),
cookieless UTM forwarding (no env), inquiry dual-write (pre-existing). Website
email kill-switch added (`WEBSITE_INQUIRY_EMAILS_DISABLED`). CRM repo: flag-gated
email ownership (`website_intake_email_enabled`, default OFF) reusing the inquiry
- residential templates plus a new contact-form alert template, hooked into
`/api/public/website-inquiries`. New website env vars documented above. CRM
tsc-clean + unit test added; website berth/UTM vue-tsc-clean. Nothing deployed.