Document templates list with eight active templates such as a deal proposal and a quote cover letter.
When to use
Use when teams write proposals, procedures or notes inside the app and export them to .docx or PDF, instead of a separate wiki.
When not to use
Real-time co-editing needs a separate WebSocket sidecar process; without it one person edits at a time.
What it adds
3 admin pages, starting at /backend/documents.
11 database tables.
47 API routes.
7 widgets on other admin pages.
15 events other modules can react to.
7 permissions to give to roles.
Readme
This is the author's README, shortened. To install, use the steps in Install.
The catalog tests those steps. Install notes in the README may be out of date.
@open-mercato/documents
Collaborative internal documents for Open Mercato: a tenant/organization-scoped backoffice module where staff co-author rich-text documents in real time (TipTap + Yjs), organized in folders, shared per-document (owner / editor / commenter / viewer), annotated with inline comments + @mentions, versioned, and exported to .docx/PDF.
Spec: Documents collaborative editor.
Show the full README
Realtime collaboration sidecar (M2)
Real-time editing is served by a Hocuspocus WebSocket sidecar — a separate long-lived Node process, not a Next.js route (App Router route handlers can't hold long-lived sockets). Entry: server/documents-collab-server.ts.
Run it
# Dev (from the repo root, alongside `yarn dev`):
yarn workspace @open-mercato/documents collab # tsx server/documents-collab-server.ts
# Production package entry:
yarn workspace @open-mercato/documents build
yarn workspace @open-mercato/documents collab:prod
# Scaffolded standalone app (run as a second workload from the same image):
yarn documents:collab
The sidecar bootstraps the app's module registry + ORM via bootstrapFromAppRoot() (the same path the mercato queue worker fleet uses), then opens a fresh request-scoped container per document load/store so every query is tenant/org-scoped.
The create-app Docker Compose templates include a documents-collab service on port 4101. In other schedulers, run yarn documents:collab as a separate service and set NEXT_PUBLIC_DOCUMENTS_COLLAB_URL before building the app to its browser-reachable ws:// or wss:// endpoint.
Environment
Var
Where
Default
Purpose
DOCUMENTS_COLLAB_PORT
sidecar
4101
WebSocket listen port
DOCUMENTS_COLLAB_REDIS_URL
sidecar
unset (or REDIS_URL)
Redis used to synchronize Yjs updates and awareness across sidecar replicas. When neither is set the sidecar runs single-node mode and logs a startup warning; multi-instance deployments require Redis
DOCUMENTS_COLLAB_REDIS_PREFIX
sidecar
development-only local namespace
Deployment-scoped Redis key prefix. Required whenever Redis is configured in production. All replicas in one deployment must share it; deployments using the same Redis database must use different values
NEXT_PUBLIC_DOCUMENTS_COLLAB_URL
app (client)
—
ws(s)://… the browser connects to; when unset, users with edit capability get optimistic-locked single-user autosave while read-only users keep the last-saved view
DOCUMENTS_COLLAB_ALLOWED_ORIGINS
sidecar
local/test: all
comma-separated exact browser origins allowed during the WebSocket handshake. In production the sidecar requires an allowed origin, sourced from this var orAPP_URL/NEXT_PUBLIC_APP_URL
DOCUMENTS_COLLAB_JWT_SECRET_V2
app + sidecar
unset (fails closed)
shared secret for v2 capability tokens; must contain at least 32 UTF-8 bytes. When unset the app mints no token and clients fall back to non-collaborative editing
DOCUMENTS_COLLAB_JWT_SECRET
app + sidecar
—
optional v1 rollout secret; the sidecar accepts legacy v1 tokens only while this is set to a ≥32-byte value that differs from the v2 secret
DOCUMENTS_COLLAB_APP_ROOT
sidecar
auto-resolved
app root for bootstrapFromAppRoot (defaults to the resolved mercato app)
DOCUMENTS_COLLAB_START
sidecar
on
set off to import the module without auto-starting the server (used by tests)
DATABASE_URL
sidecar
—
required for the cross-process event bridge (force-close on unshare/delete/restore)
DOCUMENTS_PDF_CHROMIUM_PATH
app (M4)
auto-probe
Chromium/Chrome executable for PDF export (falls back to PUPPETEER_EXECUTABLE_PATH then common system paths)
Security model (the sidecar is the chokepoint)
First 4,000 characters. Full README on npm or in the repository.
Technical details for maintainers and agentsTest results per Open Mercato version, anatomy, versions, receipts, quality and agent rules.
warnpeer-exact-pinPeer dependencies pin Open Mercato exactly (@open-mercato/shared 0.9.0), so an app on any other release of Open Mercato gets a Yarn peer warning.
The catalog reads the latest and the previous stable release. Older versions stay on npm.
Receipts
0.8.0 · previousEvery import resolves against the published 0.8.0 packages. Not tested by the catalog yet. Queued for Sunday's run (02:17 UTC).
0.9.0 · latestEvery import resolves against the published 0.9.0 packages. Not tested by the catalog yet. Queued for tonight's run (02:17 UTC).
next · 0.10.1-develop.7701Queued for Sunday's run (02:17 UTC).
Quality
Rules for Verified · 0.9 · 4 of 5 pass
○VER-1Receipt on 0.9: queued for tonight's run (02:17 UTC).
✓VER-2Fits statically on 0.9: ok.
✓VER-3Supply chain: ok.
✓VER-4No lint errors.
✓VER-5No repository in the descriptor to compare.
The nightly run installs it in a new Open Mercato 0.9.0 app: scaffold, install, add, generate, typecheck, initialize, build, start, smoke. A module's own code runs during the test. Verified is a compatibility signal, not a security review. How levels work