Skip to content

feat(invoice): DW Tailored Systems brand + PDF attachment via SendGrid - #43

Merged
Dev869 merged 2 commits into
mainfrom
feat/invoice-dw-brand-sendgrid
May 18, 2026
Merged

Dev869 merged 2 commits into
mainfrom
feat/invoice-dw-brand-sendgrid

Conversation

@Dev869

@Dev869 Dev869 commented May 18, 2026

Copy link
Copy Markdown
Owner

Why

Sending an invoice was off-brand: the email went out from a hardcoded noreply@example.com as "Open TEN99" with a navy-gradient "Open TEN99" header, and no PDF was attached. SendGrid was already wired — the problem was branding + a missing attachment.

What

When a contractor sends an invoice, the client now receives a polished DW Tailored Systems-branded HTML email with the invoice PDF attached, sent from the verified devin@dwtailored.com.

  • web/src/lib/brand.ts (new) — single source of truth for DW identity + teal-on-cream palette (hex + pdf-lib RGB) + slug().
  • buildPdf.ts — extracted buildChangeOrderPdfBytes() (raw bytes); buildChangeOrderPdf() kept as a backward-compatible blob-URL wrapper (WorkItemDetail call sites unchanged). Brand palette, serif wordmark, DW Tailored Systems · dwtailored.com footer.
  • EmailComposer.tsx — brand From/signature/footer, solid teal header (removed navy gradient), attaches the PDF + CC for invoices, tabular-nums currency.
  • sendCompletionEmail.tscontractor-only auth gate (was any authed user; portal clients could send from the verified sender), CC + PDF attachment support, PII-safe error logging.
  • utils.tsuint8ToBase64() helper.

Scope intentionally limited to invoice documents — no app-wide rebrand.

Review notes

Addressed a HIGH from code review (portal-client auth bypass on sendCompletionEmail) and 2 MEDIUM contrast findings (PDF footer + retainer color now AA, unified with the email amber). All 7 web-design-guideline contrast pairs pass WCAG AA.

Test plan

  • web: tsc -b clean, 59/59 vitest pass (incl. new invoiceBranding.test.ts), changed files lint-clean
  • functions: npm run build (tsc) clean
  • Manual: open a work item → Send Invoice → verify branded preview, From = DW Tailored Systems <devin@dwtailored.com>, CC delivered, Invoice-*.pdf attached and openable
  • Manual: View PDF in WorkItemDetail still renders (no regression)

⚠️ Requires SENDGRID_API_KEY set in Firebase Secret Manager and devin@dwtailored.com verified as a SendGrid sender (confirmed by owner).

Dev869 added 2 commits May 18, 2026 15:28
Rework invoice sending: send from verified devin@dwtailored.com as
DW Tailored Systems, re-skin the invoice email + PDF to the teal-on-cream
brand, and attach the invoice PDF copy to the email.

- new web/src/lib/brand.ts: single source of truth for identity + palette
- buildPdf.ts: split out buildChangeOrderPdfBytes() (backward-compatible
  blob-URL wrapper kept); brand palette, serif wordmark, DW footer
- EmailComposer.tsx: brand From/signature/footer, solid teal header
  (removed navy gradient), attach PDF + cc for invoices
- sendCompletionEmail.ts: contractor-only gate, cc + PDF attachment,
  PII-safe error logging
- utils.ts: uint8ToBase64 helper; tabular-nums on currency cells
- tests: slug, uint8ToBase64, PDF bytes/wrapper (59 pass)
@github-actions

github-actions Bot commented May 18, 2026

Copy link
Copy Markdown

🔥 Firebase Hosting preview: https://open-ten99--pr-43-fl6ckcwy.web.app
(expires in 7 days)

@Dev869
Dev869 merged commit fee89cb into main May 18, 2026
3 checks passed
@Dev869
Dev869 deleted the feat/invoice-dw-brand-sendgrid branch May 18, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant