Files
hermes-skills/skills/devops/debt-recovery-workflow/references/twentycrm-deployment.md
T

2.7 KiB

TwentyCRM Deployment for DRE

Server

  • Host: Core VPS (netcup, 8C/15G, Debian 13)
  • URL: https://crm.debtrecoveryexperts.com
  • Deploy: Docker Compose under /root/docker/twenty/
  • Port: 3001 (mapped from container port 3000)

Docker Compose Stack

  • twenty-server (NestJS backend)
  • twenty-worker (BullMQ async worker)
  • twenty-db (PostgreSQL 16)
  • twenty-redis (Redis cache)

Env Vars (/.env in project dir)

  • SERVER_URL MUST be set to the public URL (e.g. https://crm.debtrecoveryexperts.com)
  • REACT_APP_SERVER_BASE_URL MUST match SERVER_URL — injected into frontend build at runtime
  • ENCRYPTION_KEY generated on first deploy
  • PG_DATABASE_PASSWORD set on first deploy

API Access

Custom Objects Created (DRE Data Model)

  • Claims (claim) — Claim Number, Amount, Debt Type, Current Tier, Status, State, Date Filed, AI Score, Description
  • Debtors (debtor) — Business Name, Contact Name, Email, Phone, Address, Business Type, Notes
  • Payments (payment) — Payment Amount, Date, Method, DRE Fee, Costs Deducted, Net to Client
  • Case Notes (caseNote) — Content, Timestamp

Relationships (via GraphQL metadata API)

The correct mutation format uses relationCreationPayload inside the field object:

mutation {
  createOneField(input: {
    field: {
      name: "debtorRelation",
      label: "Debtor",
      type: RELATION,
      objectMetadataId: "<SOURCE_OBJECT_ID>",
      relationCreationPayload: {
        type: "MANY_TO_ONE",
        targetObjectMetadataId: "<TARGET_OBJECT_ID>",
        targetFieldLabel: "Claims",
        targetFieldIcon: "IconBriefcase"
      }
    }
  }) { id name }
}

The relationCreationPayload is nested inside the field object, NOT at the top level of the input. This is different from what the error messages suggest.

First-time Setup

  1. Visit https://crm.debtrecoveryexperts.com
  2. Click "Continue with Email" — magic link sent to inbox
  3. Create workspace → admin account is the first workspace member
  4. Generate API key from Settings → API Keys

Authentication (Cloudflare Access)

  • CRM is behind Cloudflare Access (proxy enabled)
  • Users authenticate via email magic link through Cloudflare
  • Optional 2FA (TOTP) can be enabled per-user from Cloudflare dashboard
  • NOT behind Caddy basic_auth — that was removed in favor of Access

Cost

  • Software: $0 (AGPL self-hosted)
  • Infrastructure: part of existing VPS
  • Cloud Access: free up to 50 users