Paliad ships firm-agnostic per CLAUDE.md ("survives firm renames") but
landing copy, email templates, page titles, and form placeholders still
hard-coded "Hogan Lovells" / "HL Patents". Replaces every user-facing
firm reference with a single source of truth: internal/branding.Name on
the server and frontend/src/branding.ts in the bundle, both reading
FIRM_NAME at startup/build time and defaulting to "HLC".
Server: branding package + boot log; auth, invite, admin_users error
strings; courts/offices/models comments; mail templates thread
{{.Firm}} via injected payload default. Files handler keeps the
upstream "HL Patents Style.dotm" path (must match mWorkRepo's blob
name) but renders the user-visible DownloadName from branding.Name.
Frontend: branding.ts read via Bun.build define so process.env.FIRM_NAME
is statically substituted into client bundles (no runtime process
reference); index/login/downloads/kostenrechner/Sidebar/ProjectFormFields
and every i18n.ts string templated against ${FIRM}.
ALLOWED_EMAIL_DOMAINS whitelist intentionally untouched — email
domains and display name rotate independently.
Verified: go build/vet/test clean; bun run build clean; FIRM_NAME=Acme
override produces "Acme" in HTML and JS bundles end-to-end.
32 lines
1.8 KiB
TypeScript
32 lines
1.8 KiB
TypeScript
// frontend/src/branding.ts — single source of truth for the firm name
|
|
// Paliad's UI renders. Mirrors internal/branding/firm.go on the server.
|
|
//
|
|
// At build time this resolves twice:
|
|
// 1. In the server-side render path (build.ts → renderXxx() returning HTML)
|
|
// Bun is running under Node, so process.env.FIRM_NAME is the real env
|
|
// var the deployer set; this file is loaded as a regular ESM module.
|
|
// 2. In the bundled client modules (e.g. client/i18n.ts) Bun.build replaces
|
|
// `process.env.FIRM_NAME` with a string literal via the `define` option
|
|
// configured in build.ts. Browsers never see process.env — every
|
|
// reference is statically substituted before the bundle is emitted.
|
|
//
|
|
// Both paths default to "HLC" when FIRM_NAME is unset.
|
|
//
|
|
// IMPORTANT: do NOT guard the read with `typeof process !== "undefined"` or
|
|
// any check on `process` itself. The minifier rewrites that guard into a
|
|
// short-string lexical comparison (`typeof process < "u"`) which evaluates
|
|
// false in the browser and would short-circuit the value back to "HLC" even
|
|
// when define has substituted the env var. The bare `process.env.FIRM_NAME`
|
|
// reference is only safe because build.ts's `define` rewrites it away
|
|
// completely for browser bundles.
|
|
//
|
|
// Why a runtime constant rather than i18n placeholder substitution: every
|
|
// Paliad surface (HTML title, hero headline, email body, PDF footer) has the
|
|
// firm name baked in literally; threading {{firm}} placeholders + a
|
|
// formatter through every t() call would be a far larger churn for the same
|
|
// firm-agnostic outcome. Re-deploying with FIRM_NAME=Acme rebuilds every
|
|
// asset with the new name in one step.
|
|
|
|
const RAW: string = (process.env.FIRM_NAME ?? "").trim();
|
|
export const FIRM: string = RAW !== "" ? RAW : "HLC";
|