Business Logic
This page explains the business concepts behind the code. Use it before changing entities, endpoints, UI flows, tracking behavior, or billing rules.
Product Mental Model
Crimoo helps a customer operate GTM server-side without manually managing infrastructure. The customer configures GTMs, domains, capture rules, offline conversion rules, and billing from the dashboard. Crimoo then runs the control plane and data plane that receive, route, inspect, enrich, and store tracking events.
Users, Workspaces, and Access
A User can own or belong to one or more Workspace records through workspace membership. Most product data is scoped to a workspace so teams can manage separate customer accounts, GTMs, contacts, conversion rules, and billing state.
Developer rule: every backend read/write that exposes customer data should be checked for workspace scope and auth context.
GTM
A GTM in Crimoo is not just a Google Tag Manager identifier. It is the control-plane record that ties together:
- Workspace ownership.
- Server-side GTM container configuration.
- Primary and custom domains.
- VM assignment.
- Preview and tagging Docker containers.
- Ports and health.
- Custom loader and obfuscation settings.
- Certificate state.
- Logs, analytics, and usage reporting.
The UI creates and manages the GTM. node-api persists the GTM and calls gtm-fabric for runtime operations. gtm-fabric creates and manages Docker containers. gtm-proxy routes public traffic to the correct destination.
Domains and Certificates
Crimoo separates domain concerns:
- Primary domain: the default domain associated with a GTM.
- Custom domain: a customer-owned domain pointed to Crimoo.
- API domain:
api.crimoo.com, routed bygtm-proxytonode-api. - Tracking domain: any domain used by a customer site to send server-side tracking requests.
Certificate lifecycle:
- Customer points DNS at the expected target.
- Crimoo verifies DNS.
gtm-fabricruns ACME/Let's Encrypt flow when needed.node-apistores certificate data.gtm-proxyfetches certificate data over internal HTTP and caches anSslContextby SNI.- Renewal is orchestrated by
node-apiand executed bygtm-fabric.
Containers and VMs
A GTM can have preview and tagging containers. Containers run on the data-plane host and are managed by gtm-fabric.
Important runtime distinction:
- Normal tracking is asynchronous and optimized for speed.
- Preview/debug is synchronous and optimized for accurate GTM debugging responses.
Tracking Events
Tracking traffic enters through gtm-proxy.
Normal flow:
- Browser sends a request such as
/g/collect. gtm-proxyvalidates and resolves route.gtm-proxyreturns202 Acceptedquickly.gtm-proxypublishes a tagging event to Pub/Sub.gtm-fabricconsumes the event.gtm-fabricforwards to the GTM container.gtm-fabricparses, enriches, and writes analytics to ClickHouse.
Preview flow:
- Browser sends request with preview indicators.
gtm-proxydetects preview.gtm-proxyforwards synchronously to the GTM container.- Browser receives the full response needed by GTM debugger.
Custom Loader and Obfuscation
The custom loader lets Crimoo serve GTM-related JavaScript from a first-party/customer domain and avoid common ad-blocking patterns. The proxy can:
- Serve generated Crimoo loader JavaScript.
- Proxy the GTM script through a configured path.
- Restore obfuscated GA4 request paths.
- Decode obfuscated query parameters before publishing or forwarding events.
The business value is more reliable first-party tracking while preserving GTM server-side behavior.
CRM Capture
CRM capture connects browser identity, events, and configured field mappings to contacts and deals.
Core concepts:
- Identity cookies identify client and session.
- Capture rules define what browser events or forms should produce CRM data.
- Field definitions describe available CRM fields.
- Contacts aggregate identifiers, custom fields, and timeline activities.
- Deals represent pipeline opportunities.
- The inspector can help create rules from real page events and forms.
gtm-fabric can batch captured contacts back to node-api, which owns durable CRM persistence.
Offline Conversions
Offline conversion logic sends CRM/business events back to platforms such as Meta or Google when configured trigger rules fire.
Core concepts:
- Platform credentials store external platform access details.
- Trigger configs define business events that should produce conversions.
- Conversion events represent generated conversion jobs.
- Conversion deliveries track delivery attempts, status, and errors.
node-api owns credentials, triggers, events, delivery history, hashing, retries, and platform adapters.
Billing
Billing is owned by node-api and Stripe.
Core objects include:
- Plans.
- User plan state.
- Subscriptions.
- Checkout sessions.
- Stripe webhook events.
- Usage reporting from the data plane.
Developer rule: Stripe webhooks must be idempotent and signature-verified before mutating subscription state.
Copilot
Copilot is the AI assistant layer around GTM automation and product help.
There are two visible implementations in the workspace:
- Integrated Copilot session routes documented under
node-api. - Standalone
CrimooCopilot-BackendandCrimooCopilot-frontprojects.
Core ideas:
- Session creation and activation tokens.
- SSE state streaming.
- Gemini-backed reasoning.
- Google GTM API inspection and modification.
- DOM verification and iframe overlay behavior.
When changing Copilot behavior, first identify whether the active path is the integrated node-api flow or the standalone Copilot service.
Storage Boundaries
| Data | Primary storage |
|---|---|
| Users, workspaces, GTMs, domains, CRM, billing, conversion config | PostgreSQL via node-api |
| Tracking events and container logs | ClickHouse |
| Runtime route/cert/config cache | In-memory caches in gtm-proxy and gtm-fabric |
| Event transport | Google Pub/Sub |
| External billing truth | Stripe |
| External DNS/cert providers | Cloudflare and Let's Encrypt |
Business Invariants
- Customer data must be workspace-scoped.
gtm-fabricshould not become the source of truth for domain/config persistence.- Normal tracking should keep browser latency low by using async publish.
- Preview/debug must stay synchronous enough for GTM debugger behavior.
- Certificates must be fetched and cached without blocking Netty event loops.
- Internal service endpoints should stay internal and not become public product APIs.
- Analytics writes should tolerate spikes through batching and retries.