Product
Engineering Guidelines — SoConnective · CRM
Binding rules. ORIENT cites them in every brief; GATE verifies them. Changing a rule means editing this document first — never "just this once".
Code conventions
- G-01 Monorepo:
apps/cms(Payload backend) ·apps/crm(Next.js CRM) ·apps/docs(Syntax) ·apps/web(future) ·packages/db(RLS/migrations). - G-02 All identifiers, code, variables and documentation are in English (the whole project — PM docs included).
- G-03 API access via
lib/payload.ts(reads, JWT from cookie) andlib/payload-write.ts(create/update/delete →{ok,error}). Mutations are server actions; after a write, revalidate +router.refresh(). - G-04 Fetch in server components; client components only for interaction. Lists use
@tanstack/react-tablevia the sharedDataTable. - G-05 One design system (Shadcn UI Kit). Brand: self-hosted Satoshi + blue
#467df6(Ocean Breeze preset, locked). Official logos. No ad-hoc styling. - G-06 Relationship IDs are sent to Payload as numbers (
Number(id)). - G-07 Form selects fill their container (
SelectTriggerisw-full); form dialogs use balanced 2-column rows, no empty gutters.
Scope guardrails
- G-10 Out of scope now: Stripe/billing, e-sign, ads, real conversations (inbox is a placeholder), marketplace.
- G-11 No new dependency or subsystem without amending the BLUEPRINT first.
- G-12 No work without a task ID in TASKS.md.
- G-13 Firm decisions: no n8n (native automation) and no Chatwoot (native conversations later). See ADR 0006.
Security (non-negotiable)
- G-20 Server-side authz on every route; the frontend only HIDES.
- G-21 Tenant isolation in EVERY query (forced RLS +
tenantin data on create for scoped collections). In hooks, normalisedoc.tenantto its id. - G-22 Validate at the boundary; secrets only in env (fs-secrets / Coolify), never in git; mask tokens in logs.
- G-23 User
tokenExpirationaligned with the cookie (7d); guard invalid sessions to login. - G-24 Backend schema changes (new collection/field) require a committed Payload migration (
pnpm payload migrate:create+migrate).push:trueis dev-only; in prod it does NOT create tables. See ADR 0007.
Documentation (a deliverable, not an extra)
G-25 Every feature updates
CHANGELOG.md; every architectural decision creates/updates an ADR indocs/architecture/decisions/. The published site (docs.soconnective.com) reflects reality.docs/pmis published viasync-docs.mjs.G-26 At the end of every phase, write a detailed, specific phase document in English under
docs/pm/phases/phase-NN-<name>.mdcovering: scope delivered, data-model changes, key files, decisions, GATE results, and what was deferred. A stranger should be able to understand the phase from it alone.G-27 The CRM is built by Coolify/Nixpacks with
base_directory=/apps/crminstall_command=pnpm install --ignore-workspace, so it consumes a standaloneapps/crm/pnpm-lock.yaml, NOT the monorepo root lockfile. Any change toapps/crm/package.json(e.g. ashadcn addthat bumps a dep) MUST be followed by regenerating that file:cd apps/crm && pnpm install --ignore-workspace. Committing only the root lockfile leaves the CRM build failing onERR_PNPM_OUTDATED_LOCKFILE.
G-28 After any CRM-affecting commit, VERIFY the deploy actually finished (
application_deployment_queues.status = finishedfor app id 5 and the running container image tag == the commit). A failed build silently keeps the last-good container live, so the app looks unchanged while the change never shipped. Auto-deploy is not guaranteed to trigger — force via Coolify if the queue shows no new row.
Definition of Done
- G-30 Done = code + acceptance criteria verified + GATE = PASS + TASKS.md updated + BLUEPRINT amended if reality changed + CHANGELOG/ADR/phase doc updated. Nothing is presented to the user as "done" before the gate.
Documentation — single source, auto-published
All product/engineering documentation lives as Markdown under docs/ (and operational runbooks under infra/runbooks/). It is the single source of truth and is auto-published to https://docs.soconnective.com on every push (the apps/docs site regenerates its pages and navigation from these files).
To document something ("documenta X"):
- Add or edit a Markdown file under
docs/with a short frontmatter header:
Use--- title: Human Title section: Overview | Product | Security | Architecture | Integrations | Operations | Guides | Reference order: 20 description: One-line summary. ---##/###headings in the body (the#H1 is the frontmatter title). Standard Markdown only — no raw HTML, no Markdoc tags. - Regenerate the site pages:
node apps/docs/scripts/sync-docs.mjs(auto-discovers every doc, derives slugs, rewrites internal links, rebuilds the navigation — no manifest or nav editing). Commit the regeneratedapps/docs/src/app/docs/**+navigation.tstogether with the source. - Commit + push. The docs site auto-deploys.
Internal QA reports (docs/pm/gate-reports/) and agent plans are excluded from the public site automatically.