BuiltEmail workspace

CFO AI welcome contract

Implementation: App\Mail\WelcomeCFOAIAccount, app/Mail/WelcomeCFOAIAccount.php. Original Markdown view: resources/views/emails/cfo-ai/welcome.blade.php. Referenced caller: app/Http/Controllers/Settings/ManagementReportSettingsController.php:21–37, store(). Static usage references do not establish current production delivery.

Subject: Welcome to Built CFO AI (existing exact subject).

Suggested preheader: Generate management reports with Built CFO AI. You can generate one report for free.

Portable placeholders

TokenExisting source / derivationHandling
{{logo_url}}Approved original Built app_name PNGOptional deployment override. Concrete HTTPS logo is already present; use approved absolute HTTPS or a real matching CID.
{{preheader}}Suggested fixed existing-purpose/one-report summary aboveRequired escaped text. Not a live credit-balance field or a timing promise.
{{cfo_url}}Original literal https://cfoai.built.africaRequired complete trusted HTTPS site-root URL. Button and fallback share this value. Preserve host/root; do not invent a report-generation, checkout or signup-completion endpoint.

The constructor takes no recipient/business/report data. Do not invent first_name, business_name, current_balance, report_count or expiry tokens. Recipient routing stays in the caller.

Trigger, recipient and delivery mode

routes/api.php:349–351 exposes POST management-reports/settings to ManagementReportSettingsController::store. The controller obtains request.user(), returns existing settings early when hasSetting(user.id), otherwise creates user_id, credits = 0 and tokens = 1, then calls Mail::to(user.email)->send(new WelcomeCFOAIAccount) at :35. This is a synchronous send(), not queue(); Queueable/SerializesModels on the class do not change that fact. Preserve the existing-settings no-repeat behavior. It is a CFO AI settings welcome, separate from GetStarted core-account signup and report-generated notifications.

The Mailable sets its fixed subject and Markdown view only. From/Reply-To follow existing mail configuration rather than a report owner or merchant identity; do not add invented header addresses. No PDF or other business attachment is configured. Shared footer PNGs need real CID embeddings or approved HTTPS hosting as described in docs/integration/shared-footer.md.

Preserved content and copy decisions

Preserve the original offer of one free report. The first-settings path allocates one token; ManagementReportSettings::hasEnoughTokens checks tokens > 0 and reduceTokens decrements one. The report controller requires sufficient tokens before dispatching generation. This supports the existing setup message, not an assurance of a still-unspent balance when the user reads the email. Re-check allocation/offer policy before adopting the text in another project or changing this caller.

Preserve both capabilities: generate management reports for businesses over periods of the user’s choice, and download/share reports. Remove the hardcoded source claim “within a few seconds” because the template does not have an actual duration value and generation uses asynchronous work. Add no trial period, unlimited reports, report accuracy/approval claim, billing promise or setup deadline.

The source’s Learn more action becomes Open Built CFO AI, with a visible fallback and site-destination explanation. It opens the same site root; it does not itself generate a report or consume a token. Feature cards/decorative external fonts are replaced by compact readable text using the approved system-font shell and shared medium button.

States, safety and integration

Two populated states share the same fixed content: standard welcome and a long inert URL robustness sample. The latter is not a production route/state. The existing-settings early return sends no email and is not represented as a new notification template.

Portable {{placeholder_name}} values are not automatically Blade variables. Use the existing Mailable with a complete HTML Blade view and an explicitly registered text view. Keep its native subject, synchronous send behavior and caller guards. Do not nest this complete document in mail::message or introduce another template framework.

Escape text and attributes. Validate cfo_url separately for the approved HTTPS host/root before escaping; bind the same value to button and fallback. There are no legacy duplicate action fields. If string replacement is used, use one pass so inserted token-shaped text remains text and never becomes raw markup. Relative local explanation URLs belong only to previews.

The shared footer contract supplies the PNG badges, current company/contact details and CID/HTTPS requirements. The Built logo source remains assets/brand/built-logo.png. Browser/inline reviews embed local images; downloads retain the portable asset policy. Do not treat embedded browser images as production MIME attachment validation.

Files: public/ready/cfo-ai-welcome.html and .txt; public/previews/cfo-ai-welcome-*.html/.txt. No separate project-owned text alternative was found for the original Markdown body; the .txt is proposed equivalent content.

No real account, settings, token, report, mail or external service is created or called here. Browser checks do not establish Gmail/Outlook/iOS Mail compatibility, actual delivery or generation performance. Open integration decisions: target-project offer parity, HTML/text registration, asset embedding/hosting and client approval. API-authored welcome content stays in scope; externally authored CRM campaigns do not.