# Why `marcaDaSaida()` Is the Only Safe Function Call Outside the DOM for Branding

> Discover why marcaDaSaida() is the sole safe function for branding outside the DOM. It guarantees execution in email workers, PDF generators, and push notifications without exceptions.

- Repository: [Rafael Melgaço/DeskcommCRM](https://github.com/melgarafael/DeskcommCRM)
- Tags: deep-dive
- Published: 2026-09-13

---

**`marcaDaSaida()` is the only branding accessor in DeskcommCRM that guarantees safe execution in non-DOM contexts such as email workers, PDF generators, and push notification handlers because it never throws exceptions, returns theme-agnostic values, and operates independently of the browser environment.**

In the DeskcommCRM codebase, separating UI-safe branding from server-safe branding is critical for background processes that must meet legal deadlines (such as LGPD SLA D+7) without risking crashes. While other branding functions like `marcaDaInstalacao()` or `resolverMarcaDaOrganizacao()` may depend on DOM-aware environments or raise exceptions, `marcaDaSaida()` in [`lib/branding/saida.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/saida.ts) provides a hardened contract specifically designed for Node.js workers and serverless functions.

## What Makes marcaDaSaida() Safe for Non-DOM Contexts

The function implements four defensive layers that make it the sole reliable choice when JavaScript runs without a browser environment.

### Guaranteed Error Handling Without Exceptions

Unlike other branding accessors, `marcaDaSaida()` never propagates errors to callers. Lines 15-33 and 155-162 of [`lib/branding/saida.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/saida.ts) wrap all resolution logic in try-catch blocks that fall back to `padraoDoProduto()` immediately upon failure. This ensures that critical background jobs—such as automated email delivery or legal data exports—continue executing even if the branding database is temporarily unreachable.

### Light Theme Consistency for Email Clients

Lines 24-30 of [`lib/branding/saida.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/saida.ts) hard-code the accent color to `REGUA_DO_PRODUTO.claro` (light theme). This design acknowledges that email clients cannot reliably interpret CSS media queries or client-side theme detection. By forcing a light-mode palette, the function prevents visual mismatches in transactional emails and PDF documents where dark-mode variables would otherwise render as invisible text.

### Single Source of Truth with Memoization

All branding data ultimately derives from the installation layer via `marcaDaInstalacao()`, but `marcaDaSaida()` exposes this through the resolution logic in [`lib/branding/resolve.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/resolve.ts). As implemented in lines 84-89 of [`saida.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/saida.ts), the result is memoized for 30 seconds. This caching layer prevents database thrashing across worker threads while maintaining consistency between the main application and background processes.

### Zero DOM Dependencies

The function refuses to import CSS-in-JS utilities, browser APIs, or React hooks. It operates purely on JavaScript primitives and database records. The only DOM-aware usage in the entire codebase occurs in `app/(public)/layout.tsx`, which deliberately calls `marcaDaSaida(null)` to maintain branding consistency across login flows without violating the function's server-safe contract.

## Implementation Details in lib/branding/saida.ts

The source file explicitly defines the seam between DOM and non-DOM usage in its header comments (lines 4-11). Internally, the function:

1. Accepts an optional `organization_id` parameter
2. Resolves the brand hierarchy: installation defaults → organization overrides → hard-coded fallbacks
3. Returns a strict interface containing `nome`, `logoUrl`, `corDestaque`, and `corTexto`
4. Logs errors to the monitoring system without throwing

This architecture allows the same function to power both the public login layout and headless LGPD export workers without environment detection logic.

## Practical Examples for Server-Side Branding

### Email Template Generation

When generating invitation emails server-side, calling `marcaDaSaida()` ensures the template receives valid brand assets even if the organization table is locked:

```typescript
import { marcaDaSaida } from '@/lib/branding/saida';
import { renderTemplate } from '@/lib/email/templates/invite';

export async function sendInviteEmail(orgId: string) {
  const brand = await marcaDaSaida(orgId);          // safe, never throws
  const html = renderTemplate({ brand, ...payload });
  await emailProvider.send({ html, to: payload.email });
}

```

### Push Notification Workers

Background handlers for push notifications use the function to inject the organization name and icon without accessing the DOM:

```typescript
import { marcaDaSaida } from '@/lib/branding/saida';
import { push } from '@/lib/notifications/push.handler';

export async function handleNewEvent(event) {
  const brand = await marcaDaSaida(event.organization_id);
  await push({
    title: `${brand.nome} – Novo evento`,
    body: `Confira a novidade`,
    icon: brand.logoUrl ?? undefined,
  });
}

```

### LGPD Export Compliance

The LGPD export worker runs in a pure-Node environment to generate PDF reports for data portability requests:

```typescript
import { marcaDaSaida } from '@/lib/branding/saida';

export async function exportLgpdData(orgId: string) {
  const brand = await marcaDaSaida(orgId);
  // brand is used in the PDF header/footer
  const pdf = await generatePdf({ brand, data: orgData });
  await storePdf(pdf);
}

```

## Why Other Branding Functions Fail Outside the DOM

**`marcaDaInstalacao()`** requires filesystem access and cache initialization that may throw if the installation manifest is malformed. **`resolverMarcaDaOrganizacao()`** depends on database transactions that can timeout and raise unhandled promise rejections. Only `marcaDaSaida()` wraps these dependencies in defensive error boundaries while providing static fallbacks, making it the mandatory choice for any code path that cannot afford runtime exceptions.

## Summary

- **`marcaDaSaida()`** is the only branding function in DeskcommCRM guaranteed to work in server-side, worker, and email contexts.
- It **never throws**—all errors route to logging and trigger the `padraoDoProduto()` fallback defined in lines 15-33 of [`lib/branding/saida.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/saida.ts).
- It **forces light-theme colors** (`REGUA_DO_PRODUTO.claro`) to ensure visibility in email clients and PDFs.
- It utilizes **30-second memoization** via [`lib/branding/resolve.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/resolve.ts) to reduce database load across concurrent workers.
- It has **zero dependencies** on the DOM, CSS-in-JS, or browser APIs, making it safe for cron jobs and LGPD compliance workers.

## Frequently Asked Questions

### Can I use marcaDaSaida() in React components?

Yes, but only for static or server-side rendered components. The function is safe to call in `app/(public)/layout.tsx` and other server contexts, but client-side components requiring reactive theme switching should use DOM-aware hooks instead.

### What happens if the database connection fails during marcaDaSaida() execution?

The function catches all exceptions in its internal try-catch blocks (lines 155-162) and immediately returns the static default brand from `padraoDoProduto()`. Your email or PDF generation continues without interruption, though the branding will show generic product defaults rather than organization-specific values.

### Why does marcaDaSaida() force light colors instead of respecting user preferences?

Email clients and PDF renderers cannot reliably access CSS media queries or user agent theme preferences. Hard-coding `REGUA_DO_PRODUTO.claro` ensures that banners, buttons, and text remain legible in all viewing environments, preventing scenarios where dark-mode text renders as invisible against transparent backgrounds.

### How long does marcaDaSaida() cache branding data?

The underlying resolution layer memoizes results for **30 seconds** as implemented in [`lib/branding/resolve.ts`](https://github.com/melgarafael/DeskcommCRM/blob/main/lib/branding/resolve.ts). This duration balances consistency across parallel worker processes with the need to pick up recent branding changes without excessive database queries.