How DeskcommCRM Handles Branding in Non-DOM Contexts: Email & MFA Rendering

DeskcommCRM isolates visual identity for non-DOM outputs into a dedicated "output branding" layer centered around the marcaDaSaida function, ensuring emails and MFA screens always display consistent logos, accent colors, and readable contrast ratios even when database lookups fail.

DeskcommCRM is an open-source CRM that must render branded content in environments without a Document Object Model, such as transactional emails, MFA screens, and support footers. The repository implements a deterministic, fault-tolerant branding API that guarantees legal-required communications never break due to configuration errors. This article examines the TypeScript architecture in lib/branding/saida.ts and its integration with email templates to deliver reliable visual identity across all non-DOM contexts.

The Core Architecture: Output Branding Layer

The system separates DOM-dependent theming from static output branding. While the web interface relies on CSS variables and React context, non-DOM contexts consume a frozen snapshot of brand attributes resolved at render time.

Single Entry Point: marcaDaSaida

The async function marcaDaSaida(organizationId: string | null) in lib/branding/saida.ts serves as the sole gateway for resolving brand assets. It returns an object containing the organization name, logo URL, accent color, and contrast-adjusted foreground color.

The function first retrieves the installation-wide brand via marcaDaInstalacao(), then conditionally merges organization-specific settings if an ID is provided. This layered resolution ensures that global defaults from environment variables can be overridden by tenant-specific configurations without coupling email rendering logic to database schemas.

Robust Fallback Strategy

If database connections fail, color values are malformed, or organization rows are missing, marcaDaSaida logs a single warning via avisarUmaVez and returns the product-default brand defined as padraoDoProduto (lines 15-24 of lib/branding/saida.ts). This guarantees that LGPD compliance emails and critical security notifications always render with valid branding rather than throwing runtime errors.

Color Management for Email Rendering

Emails are always rendered in a light theme regardless of recipient client preferences, requiring deterministic color calculations that work without JavaScript or CSS media queries.

Theme-Independent Accent Colors

The accent color for email buttons derives from the product ruler constant REGUA_DO_PRODUTO, specifically ACCENT_DO_PRODUTO (lines 90-93). To ensure accessibility, the system computes a contrast-adjusted foreground color (accentFg) using the melhorFrenteSobre utility, returning black or white depending on the accent's luminance.

Neutral Palette for Email Body

The constant NEUTROS_DE_SAIDA provides a standardized set of greys for backgrounds, text, borders, and subtle elements (lines 4-13). These values are pulled directly from the product ruler, ensuring that all email templates share the same visual language without hardcoding hex values in individual templates.

Implementation in Email Templates

The invite email template at lib/email/templates/invite.ts demonstrates consumption of the branding API. It receives a MarcaDeSaida object and applies its fields to generate HTML:

  • Logo URL: Conditionally renders an <img> tag when present
  • Accent: Applies to button backgrounds via inline styles (style="background:${opts.marca.accent}")
  • Contrast foreground: Sets button text color using color:${opts.marca.accentFg}

The template imports NEUTROS_DE_SAIDA to style surrounding text blocks, maintaining consistent spacing and typography without external stylesheets.

Support Email Configuration

For legal and support footers, the function emailDeSuporte() (lines 37-39 of lib/branding/saida.ts) reads the env.SUPPORT_EMAIL environment variable. When undefined, it returns an empty string rather than a placeholder address, preventing invalid contact information from appearing in production emails.

Performance and Caching

To prevent database saturation during high-volume email campaigns, the installation brand resolution is memoized with a 30-second TTL in lib/branding/instalacao.ts. This per-process cache allows branding updates to propagate quickly while eliminating redundant queries during batch operations. If an administrator updates branding via the API, the memoization invalidates on the next cycle, ensuring subsequent renders fetch fresh values.

Code Examples

Resolving Brand for Login/MFA Screens

When rendering authentication pages where no organization context exists yet:

import { marcaDaSaida } from "@/lib/branding/saida";

const brand = await marcaDaSaida(null);
// Returns: { name, logoUrl, accent, accentFg, origens }

Building Organization-Specific Invite Emails

For tenant-branded transactional emails:

import { marcaDaSaida } from "@/lib/branding/saida";
import { buildInviteEmail } from "@/lib/email/templates/invite";

async function sendInviteEmail(userId: string, orgId: string) {
  const brand = await marcaDaSaida(orgId);
  const email = buildInviteEmail({
    inviterName: "Ana",
    orgName: "Acme Corp",
    acceptUrl: "https://example.com/accept?token=xyz",
    role: "admin",
    expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60_000),
    marca: brand,
  });
  // Send via your mailer implementation
}

Retrieving Support Email Addresses

For consistent footer rendering:

import { emailDeSuporte } from "@/lib/branding/saida";

const supportEmail = emailDeSuporte(); 
// Returns env.SUPPORT_EMAIL or empty string

Summary

  • Centralized API: The marcaDaSaida function in lib/branding/saida.ts provides a single, async interface for resolving brand assets in non-DOM contexts.
  • Fault Tolerance: Failed database lookups automatically degrade to the padraoDoProduto default brand, ensuring critical emails never fail to render.
  • Accessibility First: The melhorFrenteSobre utility computes contrast-adjusted foreground colors (accentFg) to guarantee readable button text against custom accent colors.
  • Light-Theme Enforcement: All emails use the NEUTROS_DE_SAIDA palette and ACCENT_DO_PRODUTO constant, ignoring client-side theme preferences for consistent rendering.
  • Performance Optimization: Installation branding is memoized with a 30-second TTL to minimize database load during bulk email operations.

Frequently Asked Questions

What is the main function used to resolve branding in DeskcommCRM emails?

The marcaDaSaida(organizationId) function in lib/branding/saida.ts serves as the primary entry point. It resolves the organization name, logo URL, accent color, and contrast-adjusted foreground by first checking installation-wide settings and optionally merging organization-specific overrides when an ID is provided.

How does DeskcommCRM ensure email buttons remain readable with custom accent colors?

The system calculates a contrast-adjusted foreground color using the melhorFrenteSobre utility function. This returns either black or white text depending on the luminance of the accent color defined in ACCENT_DO_PRODUTO, ensuring WCAG-compliant contrast ratios without requiring CSS variables or client-side JavaScript.

What happens if the database is offline when rendering a branded email?

If database connections fail or configuration rows are missing, marcaDaSaida catches the error, logs a single warning via avisarUmaVez, and returns the padraoDoProduto default brand object. This fault-tolerant design guarantees that legal-required communications like LGPD compliance emails render successfully even during infrastructure outages.

Where is the support email address configured for non-DOM contexts?

The support email address is read from the SUPPORT_EMAIL environment variable via the emailDeSuporte() function in lib/branding/saida.ts. If the variable is undefined, the function returns an empty string rather than a placeholder, preventing invalid contact information from appearing in email footers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →