chore(prod): codify cluster DB + move /data to NAS#73
Conversation
The Notes section escaped data.notes, so the rich-text editor's HTML showed as literal tags (<p>, <br>, …) in the PDF. Scope of Work and Lead Letter — the same kind of rich-text content — already render raw HTML; Notes now matches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Production (bidwright.rassaun.com) no longer runs an internal postgres. The database lives on the Rassaun Postgres HA cluster (Patroni), reached via the floating leader VIP 10.0.0.85 (vip-manager follows the primary on failover). The /data volume (uploads, projects, knowledge) now lives on the Synology NAS over NFSv4, matching the other Dokploy apps. Brings docker-compose.prod-registry.yml in line with the live Dokploy stack (sourceType=raw, migrated out-of-band): - remove the internal `postgres` service + its depends_on in db-migrate/api/worker - drop the unused `bidwright-pgdata` volume - switch `bidwright-data` to an NFS volume backed by 10.0.1.106:/volume1/dokploy-storage/bidwright - point the DATABASE_URL default at the cluster VIP (real creds stay in the Dokploy env) agent-home and redis stay on local volumes — NFS is a poor fit for bubblewrap mount/locking and for redis AOF. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13243c805a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return `<h2>Notes</h2><div class="section-body">${escapeHtml(data.notes)}</div>`; | ||
| // Notes are rich text (HTML) from the editor — render as HTML like Scope of | ||
| // Work and Lead Letter, not escaped (which showed the raw tags). | ||
| return `<h2>Notes</h2><div class="section-body">${data.notes}</div>`; |
There was a problem hiding this comment.
Sanitize rich-text notes before rendering
When a quote note contains raw HTML from the rich-text editor or API, this now injects it directly into the Playwright-rendered PDF HTML. Because /projects/:projectId/revisions/:revisionId accepts notes as an arbitrary string and generatePdfBuffer calls page.setContent, a pasted payload such as an event handler or script in the Notes field can execute during PDF generation instead of being displayed as content. Preserve rich text by allowing only safe tags/attributes rather than inserting the stored string verbatim.
Useful? React with 👍 / 👎.
What
Brings
docker-compose.prod-registry.ymlin line with the already-live production stack on Dokploy (bidwright.rassaun.com). The actual prod migration was applied directly to the Dokploy raw compose + redeployed; this PR updates the repo mirror so the documented source-of-truth matches.Changes
postgresservice and itsdepends_onindb-migrate/api/worker; drop the unusedbidwright-pgdatavolume. The database already lives on the Patroni cluster, reached via the floating leader VIP10.0.0.85(vip-manager moves it to the current primary on failover — verified pg-1/.86 leader, pg-2/.87 replica).DATABASE_URLdefault now points at the VIP (real creds stay in the Dokploy env)./data→ Synology NAS:bidwright-datais now an NFSv4 volume backed by10.0.1.106:/volume1/dokploy-storage/bidwright, matching the other Dokploy apps. 18,226 files (2.3 GB) rsync'd;secrets/integrations.keymd5-verified identical.agent-home(per-user CLI auth + bubblewrap homes) andredis— NFS is a poor fit for bwrap mount/locking and redis AOF.Why CI is unaffected
Dokploy is
sourceType=raw, so future deploys use the stored compose + env (already updated), not this file. The CI deploy job only bumpsBIDWRIGHT_TAG. This file is the manual mirror; updating it keeps the two in sync.Verification (prod, post-cutover)
done; api/worker/web/redis healthy./dataconfirmed NFS-backed inside the container; write-through OK./health→{"status":"ok","dataRoot":"/data"}; web/→ 200.🤖 Generated with Claude Code