2.7 KiB
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_URLMUST be set to the public URL (e.g. https://crm.debtrecoveryexperts.com)REACT_APP_SERVER_BASE_URLMUST matchSERVER_URL— injected into frontend build at runtimeENCRYPTION_KEYgenerated on first deployPG_DATABASE_PASSWORDset on first deploy
API Access
- API key stored in ~/.hermes/.env as
TWENTY_CRM_API_KEY - GraphQL endpoint: POST https://crm.debtrecoveryexperts.com/graphql (standard queries)
- Metadata endpoint: POST https://crm.debtrecoveryexperts.com/metadata (schema mutations)
- REST endpoint: POST https://crm.debtrecoveryexperts.com/rest/{object}
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
- Visit https://crm.debtrecoveryexperts.com
- Click "Continue with Email" — magic link sent to inbox
- Create workspace → admin account is the first workspace member
- 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