feat(invoice): DW Tailored Systems brand + PDF attachment via SendGrid - #43
Merged
Merged
Conversation
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)
|
🔥 Firebase Hosting preview: https://open-ten99--pr-43-fl6ckcwy.web.app |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Sending an invoice was off-brand: the email went out from a hardcoded
noreply@example.comas "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— extractedbuildChangeOrderPdfBytes()(raw bytes);buildChangeOrderPdf()kept as a backward-compatible blob-URL wrapper (WorkItemDetail call sites unchanged). Brand palette, serif wordmark,DW Tailored Systems · dwtailored.comfooter.EmailComposer.tsx— brand From/signature/footer, solid teal header (removed navy gradient), attaches the PDF + CC for invoices, tabular-nums currency.sendCompletionEmail.ts— contractor-only auth gate (was any authed user; portal clients could send from the verified sender), CC + PDF attachment support, PII-safe error logging.utils.ts—uint8ToBase64()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 -bclean, 59/59 vitest pass (incl. newinvoiceBranding.test.ts), changed files lint-cleanfunctions:npm run build(tsc) cleanDW Tailored Systems <devin@dwtailored.com>, CC delivered,Invoice-*.pdfattached and openableSENDGRID_API_KEYset in Firebase Secret Manager anddevin@dwtailored.comverified as a SendGrid sender (confirmed by owner).