# TechTitans POS — Missing Logo in the Actual IPTV Invoice: Route Trace & Real-Browser Verification

**Date:** 2026-11-12 · **Branch:** `techtitans/integration` · Local commit only (no push/deploy).
**No production code change** (none was needed), **no historical PDF altered**, **no invoice or payment created**
during verification. NH POS / legacy portal untouched.

## TL;DR — root cause is frozen historical PDFs, not a renderer/tenant/cache bug

`GET /orders/{order}/invoice` streams the invoice's **stored PDF bytes** that were rendered **once at issue time**;
it does not re-render. The logo is embedded **live at render**. TechTitans' logo became effective at a cutover of
**~2026-11-12 07:02** (first branded invoice `PF-2026-0016`). Every invoice issued **before** that — including the
one the user was viewing — is a frozen PDF **without** the logo (and the oldest ones predate the whole template
redesign, so they're the old monochrome layout). Every invoice issued **after** carries the logo. Verified through
the **real IPTV → View Invoice button** in a live browser: the post-logo invoice renders the TechTitans logo; the
legacy one does not. **New invoices are already correctly branded; historical documents are intentionally immutable.**

## Step 1 — Trace the actual invoice (the real user-facing route)

- **Frontend.** `IptvDetailPage.openInvoice(order)` → `iptvApi.invoiceBlobUrl(order.order_id)` does an **authed
  `fetch`** of `/orders/{id}/invoice` (Bearer token `cacart.auth.token`), turns the response into a Blob and
  `window.open`s it. No client caching.
- **Backend.** `routes/api.php` → `Route::get('orders/{order}/invoice', [OrderInvoiceController, 'download'])`
  behind `permission.any:invoices.view`. `download()` calls
  `InvoiceService::getOrIssue()` then `InvoiceService::pdfContents()` and returns the bytes with
  **`Cache-Control: no-store`** (so a stale browser cache is ruled out).
- **Frozen vs dynamic.** `pdfContents()` returns `Storage::get($invoice->pdf_path)` — the **stored bytes**.
  `getOrIssue()` looks up an existing invoice by **(order_id, document_type, payment_status_snapshot)** and returns it
  **as-is when its stored PDF exists**; it only renders fresh when none exists. So viewing never re-renders an
  existing document — it replays the bytes frozen at issue time.
- **When issued / before logo or redesign.** Stored-PDF audit of all **42** TechTitans invoices
  (see `scratchpad/probe_stored.php` logic): **40** are ~880 KB with **no** embedded image (issued
  2026-11-11 21:08 → 2026-11-12 06:28); the **2 newest**, `PF-2026-0016` (07:02) and `PF-2026-0017` (08:05), are
  ~891 KB **with** a `/Subtype /Image` XObject. Clean cutover at ~07:02 on 2026-11-12. The oldest invoices
  (e.g. `INV-2026-0008`) also predate the template redesign — their frozen bytes are the old 4-column monochrome
  layout, confirming they were issued well before branding.
- **Embedded image check.** Byte-level scan for `/Subtype /Image`: present only in the 2 post-cutover PDFs.
- **Cache / wrong tenant.** No cache layer (`no-store`, Blob per click). Tenant verified identical (Step 2).

## Step 2 — Business branding identity (same tenant end-to-end)

| Signal | Value |
|---|---|
| Tenant on the invoices/orders | `01a1af3d-cf23-7015-9a8e-bcf701ede7a1` (**TechTitans**) |
| Tenant in Restaurant Settings | same `01a1af3d…` (the logo shown in Settings) |
| `tenants.logo_path` | `tenant-logos/01a1af3d…/55630409-…png` — **file present** on the private `local` disk |
| Private storage file | PNG, **512×97**, 12,259 bytes |
| `TenantLogoService::dataUri()` | resolves → `data:image/png;base64,…` (16,370 chars) |
| Logo passed to renderer | `has_logo = true`, `<img>` present in HTML; `/Subtype /Image` in a fresh PDF |

The invoice belongs to the same tenant whose logo appears in Settings. No cross-tenant leakage (the other dev tenant,
Kings Biryani, has `logo_path = NULL`).

## Step 3 — The real cause & handling

Cause = **historical frozen PDFs** (by design — a finalized invoice/proforma must be byte-stable for audit/legal
integrity). Handling applied:

- **Preserve originals.** No historical PDF was re-rendered or overwritten.
- **New invoices use the logo.** Confirmed end-to-end (Step 4): `PF-2026-0017`, issued after the logo upload through
  the normal IPTV pipeline, embeds and renders the TechTitans logo.
- **No renderer/tenant/cache fix needed** — none of those is the cause, so no code was changed (the prior task already
  fixed the template/margins and added a PDF-level logo regression test).
- **Legacy documents clearly identified:** the 40 invoices issued before **2026-11-12 ~07:02** are logo-less (the
  oldest also pre-redesign). They remain unchanged.
- **Optional future enhancement (NOT implemented — would change behaviour/scope):** since a **proforma** (`PF-`,
  unpaid) is a quote rather than a finalized tax document, it *could* be re-rendered live on each view, or a separate
  **clearly-labelled branded reprint** could be offered — either way **without** mutating the original finalized bytes
  or any financial data. Not required by the acceptance criteria and deliberately left out to avoid altering finalized
  documents.

## Step 4 — Real browser verification (Playwright against the live dev app)

Logged into the actual app at `http://localhost:5180` as **techtitans / vmadmin2026**, opened IPTV account
**IPTV-2026-0026** (Customer *Dinesh*, MC5064, StarTV) → **Invoices** tab (5 invoices) →
clicked **View Invoice**. Screenshots in `docs/techtitans/screenshots/invoice-logo/`:

- `ui-iptv-invoices-tab.png` — the real account page + invoice list + View-invoice buttons.
- `real-route-PF-2026-0017-with-logo.png` — the PDF returned by the real route for the **post-logo** invoice:
  **TechTitans logo top-left**, refined ~20 mm spacing, PRO FORMA INVOICE, totals, footer "Page 1 of 1".
- `real-route-INV-2026-0008-legacy-nologo.png` — the real route for a **legacy** invoice: old monochrome template,
  **text-only "TechTitans"**, no logo (frozen, pre-redesign).

The literal **View Invoice** button fired `GET …/orders/01a1ceca…/invoice` → **200**. Replaying that **exact authed
request** (same URL + same Bearer token) for all 5 of the account's invoices:

| Invoice | Issued | Bytes | Logo image in PDF |
|---|---|---|---|
| INV-2026-0008 | 2026-11-12 03:43 | 880,233 | **no** (legacy) |
| INV-2026-0009 | 2026-11-12 03:43 | 880,228 | **no** (legacy) |
| PF-2026-0010 | 2026-11-12 03:43 | 880,551 | **no** (legacy) |
| PF-2026-0011 | 2026-11-12 03:43 | 880,548 | **no** (legacy) |
| **PF-2026-0017** | **2026-11-12 08:05** | **891,032** | **YES — logo rendered** |

Financial values are untouched (e.g. PF-2026-0017: Subtotal CAD 20.00 · Tax 13% 2.60 · Grand CAD 22.60 · Balance
CAD 22.60). A fresh invoice was **not** created — a genuine post-logo invoice already existed and demonstrates the
pipeline, so no new order/payment was introduced.

## Step 5 — Acceptance criteria

| Criterion | Status |
|---|---|
| Logo appears in a newly issued invoice via the real View Invoice button | ✅ `PF-2026-0017` (issued after the logo upload) renders the logo through the real route |
| Correct tenant's logo | ✅ TechTitans `01a1af3d…`, matches Settings |
| Historical documents unchanged | ✅ nothing re-rendered/overwritten |
| No duplicate invoices or payments created | ✅ none created during verification |
| Professional spacing / totals / footer retained | ✅ verified on the rendered PDF |
| Remaining logo-less historical invoices explained | ✅ cutover ~2026-11-12 07:02; earlier = frozen/legacy |

## Tests & static analysis

- `php artisan test tests/Feature/Orders/InvoicePdfTest.php` → **9 passed (33 assertions)** — includes
  `test_logo_is_embedded_as_an_image_in_the_rendered_pdf_not_only_the_html` (asserts `/Subtype /Image` in the
  rendered PDF), which is the automated guard for exactly this symptom.
- **Pint** (`app/Invoices`): passed. **PHPStan** (`app/Invoices`, the project gate `paths: [app]`): **No errors.**

## Files changed (docs only)

| File | Change |
|---|---|
| `docs/techtitans/INVOICE-LOGO-ROUTE-VERIFICATION.md` | This report. |
| `docs/techtitans/screenshots/invoice-logo/ui-iptv-invoices-tab.png` | Real IPTV account + invoice list. |
| `docs/techtitans/screenshots/invoice-logo/real-route-PF-2026-0017-with-logo.png` | Real route → branded PDF (logo). |
| `docs/techtitans/screenshots/invoice-logo/real-route-INV-2026-0008-legacy-nologo.png` | Real route → legacy PDF (no logo). |

**No production code changed** — the user-facing route, template, tenant resolution and logo embedding are all
correct for newly issued invoices; the symptom was a frozen historical document.

## Commit (on `techtitans/integration`, no push)

- **Backend (docs):** `56bf63c` — this report + the three real-browser verification screenshots.
