toga-ai 1.0.133 → 1.0.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  | Doc | Summary | Files |
4
4
  |-----|---------|-------|
5
5
  | [_underscore Framework Architecture](architecture.md) | `_underscore` is the shared PHP backend framework for **all 2.0 applications**. | _underscore/_underscore.php, _underscore/Loader.php, _underscore/Framework.php, _underscore/Model.php, _underscore/Database.php, _underscore/Query.php, _underscore/Route.php, _underscore/Component.php |
6
- | [Carrier Shipping Labels (UPS/FedEx) & NetSuite Item Fulfillment](features/carrier-shipping-labels.md) | Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracki | _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Client/ItemFulfillments/TrackingNumber.php, _underscore/Component/Library/Carriers/Ups/Ups.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Trait/Netsuite/SalesOrder.php, _underscore/Component/Library/NetSuite/NetSuite.php, _underscore/Model/Client/TrackingNumber.php, _underscore/Model/Client/ShippingMethod.php, _underscore/Model.php, _underscore/Cloud.php |
6
+ | [Carrier Shipping Labels (UPS/FedEx) & NetSuite Item Fulfillment](features/carrier-shipping-labels.md) | Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracki | _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Client/ItemFulfillments/TrackingNumber.php, _underscore/Component/Library/LabelPdf/LabelPdf.php, _underscore/Component/Library/Carriers/Ups/Ups.php, _underscore/Component/Library/Carriers/Fedex/Fedex.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Trait/Netsuite/SalesOrder.php, _underscore/Component/Library/NetSuite/NetSuite.php, _underscore/Model/Client/TrackingNumber.php, _underscore/Model/Client/ShippingMethod.php, _underscore/Model.php, _underscore/Cloud.php |
7
7
  | [Client Email Template Sending](features/email-template-sending.md) | `_Model_Client_EmailTemplate` sends a stored, client-defined email template by UUID. | _underscore/Model/Client/EmailTemplate.php, _underscore/Model/Client/EmailTemplateOutgoingEmailAddress.php, _underscore/Email.php |
8
8
  | [Per-Client Database Connections & the Local Logs Trap](features/per-client-database-connections.md) | When `_underscore` serves a request for a client it opens **three distinct per-client database connections**, not one. | _underscore/Database.php, _underscore/ApiRequest.php, _underscore/Model/Client/Logs/Api.php |
9
9
  | [Recursive Item Fulfillments (upstream mirroring)](features/recursive-item-fulfillments.md) | In a multi-tier supply chain a sales order (SO) spawns a purchase order (PO) that becomes another SO downstream, and so on. | _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Client/ItemFulfillmentItem.php, _underscore/Model/Client/ItemFulfillmentItemUnit.php, _underscore/Model/Client/ItemFulfillmentPackage.php, _underscore/Model/Compass/AdvanceShippingNotice.php, dbchanges2/Core/2026-02-13 - 75601 - RecursiveItemFulfillmentCreation.sql, dbchanges2/Core/2026-06-04 - RecursiveItemFulfillmentPut.sql |
@@ -6,12 +6,14 @@ project: _Underscore
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-06-16
9
+ updated: 2026-06-18
10
10
  owners: [mhammontree]
11
11
  files:
12
12
  - _underscore/Model/Client/ItemFulfillment.php
13
13
  - _underscore/Model/Client/ItemFulfillments/TrackingNumber.php
14
+ - _underscore/Component/Library/LabelPdf/LabelPdf.php
14
15
  - _underscore/Component/Library/Carriers/Ups/Ups.php
16
+ - _underscore/Component/Library/Carriers/Fedex/Fedex.php
15
17
  - _underscore/Trait/Netsuite/ItemFulfillment.php
16
18
  - _underscore/Trait/Netsuite/SalesOrder.php
17
19
  - _underscore/Component/Library/NetSuite/NetSuite.php
@@ -29,21 +31,26 @@ related:
29
31
 
30
32
  Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label
31
33
  (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracking
32
- number and label attached. Includes the **authoritative label-storage architecture
33
- decision** (dev lead Jeff, June 2026) that supersedes what the code currently does.
34
+ number and label attached. As of 2026-06 the label is requested + stored as a raw
35
+ **PNG** and the printable PDF is **generated on demand** via `_Component_Library_LabelPdf`
36
+ (FPDF) — superseding the old Labelary ZPL→PDF approach.
34
37
 
35
38
  ## Key files / entry points
36
39
 
37
40
  - `upsShipmentApi` / `fedexShipmentApi` (scripted APIs on
38
- `Model/Client/ItemFulfillment.php`): build the carrier request, call the carrier,
39
- (currently) convert ZPL→PDF via Labelary, save the PDF to NetSuite File Cabinet +
40
- the DB storage field, return `{ trackingNumber, pdfLabel, fileInternalId }` or
41
- `{ error, trackingNumber }`. UPS path now checks `$shipmentResponse->success` and
42
- fast-fails on an empty service code (it previously swallowed UPS errors and surfaced
43
- a misleading "Failed to save PDF to NetSuite"). These methods (plus `fulfill` and
44
- `createNetsuiteItemFulfillment`'s package-detail query) resolve the tracking record by
41
+ `Model/Client/ItemFulfillment.php`): build the carrier request **requesting a PNG label**,
42
+ store the raw PNG on `TrackingNumbers.labelPdfFile`, generate a printable PDF via
43
+ `_Component_Library_LabelPdf`, save that PDF to the NetSuite File Cabinet, and return
44
+ `{ trackingNumber, pdfLabel, fileInternalId }` or `{ error, trackingNumber }`. UPS path
45
+ checks `$shipmentResponse->success` and fast-fails on an empty service code (it previously
46
+ swallowed UPS errors → misleading "Failed to save PDF to NetSuite"). These methods (plus
47
+ `fulfill` and `createNetsuiteItemFulfillment`'s package query) resolve the tracking record by
45
48
  joining **`ItemFulfillments_TrackingNumbers`** (the bridge); they previously joined the
46
49
  dropped `ItemFulfillmentPackages` table — see Gotchas.
50
+ - `_Component_Library_LabelPdf::buildFromPngLabels($labels)`
51
+ (`Component/Library/LabelPdf/LabelPdf.php`): builds a multi-page 4x6 PDF from raw PNG label
52
+ images (one per page, optional "Return Label" caption) via FPDF; returns the PDF as a binary
53
+ string. Built to take N pages so a combined shipping + return label is one print-once PDF.
47
54
  - `_Component_Library_Carriers_Ups::submitShipmentRequest`
48
55
  (`Component/Library/Carriers/Ups/Ups.php`): returns `{ success, errorMessage,
49
56
  trackingNumber, encodedLabel }`.
@@ -58,21 +65,24 @@ decision** (dev lead Jeff, June 2026) that supersedes what the code currently do
58
65
  (`_Model_Growrk_ItemFulfillment extends _Model_Client_ItemFulfillment`), not the base
59
66
  model.
60
67
 
61
- ## Label-storage architecture (AUTHORITATIVE — dev lead Jeff, 2026-06)
68
+ ## Label-storage architecture (implemented 2026-06; dev lead Jeff)
62
69
 
63
- Supersedes the Labelary-PDF + manual-S3 approach:
70
+ The label is **stored as the raw carrier PNG** (not a Labelary PDF) and the printable PDF is
71
+ **generated on demand** server-side:
64
72
 
65
- 1. **Do NOT touch S3 by hand.** The model's `FIELD_STORAGE` abstraction, accessed via
66
- the 2.0 API, already handles label fetch + storage.
67
- 2. **Store the raw carrier response as a GIF**, not a Labelary-converted PDF.
68
- 3. **Generate the printable PDF on demand**, combining the shipping label AND the
69
- return label into one PDF (the browser print dialog handles one file at a time).
70
- Leaning **backend** generation — `pdf-lib` (client-side) cannot embed GIF.
73
+ 1. **Carrier returns PNG.** UPS via `[ups] label_format = "PNG"` config (the client's
74
+ `getLabelFormat()` reads it; defaults ZPL); FedEx via `$shipmentRequest->labelImageType =
75
+ 'PNG'` + `labelStockType = 'PAPER_4X6'`. Labelary is gone.
76
+ 2. **Store the raw PNG** on `TrackingNumbers.labelPdfFile` (a `FIELD_STORAGE` field; the name is
77
+ retained though it now holds a PNG) via the model/S3 mechanism — never touch S3 by hand.
78
+ 3. **Generate the PDF on demand** with `_Component_Library_LabelPdf::buildFromPngLabels([...])`
79
+ — FPDF, one label image per 4x6 page, optional "Return Label" caption — for the immediate
80
+ display + the NetSuite File Cabinet copy.
71
81
 
72
- Not yet implemented. Open questions before building: backend vs frontend for the
73
- GIF→PDF step; which existing 2.0 label-fetch/storage calls to build on. Combining
74
- shipping + return also depends on the return-label flow existing — outbound-only can
75
- come first.
82
+ Jeff approved **PNG over GIF**: a PDF lib embeds PNG with **no extra extension** (FPDF parses
83
+ non-alpha PNG in pure PHP — no GD/Imagick). Remaining wiring: the reprint/return-label combine
84
+ (frontend calls a backend generate endpoint instead of the client-side `pdf-lib` merge), and
85
+ the return-label generation itself.
76
86
 
77
87
  ## `FIELD_STORAGE` mechanics (reference)
78
88
 
@@ -119,8 +129,33 @@ attempted.
119
129
  bridge-linked `TrackingNumbers` row shows `number = NULL` after a "successful" ship. Backend
120
130
  change — only effective once deployed to beta. Worth grepping `ItemFulfillmentPackage::TABLE`
121
131
  across `_underscore`/`api2`/`library` for the same staleness elsewhere.
132
+ - **FPDF is a Composer dep, and `_Loader` throws on it.** `setasign/fpdf` lives in api2's
133
+ `vendor/` (not an `_underscore` Component library), so the framework autoloader throws
134
+ "could not find source file for 'FPDF'". `LabelPdf` wraps `new \FPDF()` with
135
+ `_Loader::setThrowExceptionInAutoloaderIfClassNotFound(false)` (restored after) so the chain
136
+ falls through to Composer's autoloader — same pattern as `Model/Client/TableView.php`.
137
+ - **Commit `composer.lock`.** EB runs `composer install` (installs strictly from the lock). If
138
+ `composer.json` declares `setasign/fpdf` but the lock wasn't committed, the dep never installs
139
+ → runtime `Class "FPDF" not found`. Verify `vendor/setasign/fpdf/` exists after deploy.
140
+ - **FedEx tracking-cred config fallback.** `_Config::fedex('tracking_client_id')` **throws** when
141
+ the key is missing; the intended `?:` fallback to the ship `client_id`/`client_secret` only
142
+ works with the no-throw second arg: `_Config::fedex('tracking_client_id', false) ?: …` (same as
143
+ the UPS client). Without it, FedEx shipping dies with "Configuration parameter
144
+ 'tracking_client_id' … has not been defined".
145
+ - **`labelPdfFile` (`FIELD_STORAGE`) write can silently skip** when set on a lazy
146
+ `new _Model_Client_TrackingNumber($id)` (never loaded): `number` (a real column) saves but the
147
+ storage write is skipped (no error, no S3 object — and `copyFileToS3` re-throws, so a skip ≠ a
148
+ failed write). Likely needs `->load()` before setting `labelPdfFile`. **Open issue** — the S3
149
+ label save was still not landing as of 2026-06-18.
150
+ - **FPDF can't embed alpha-channel or interlaced PNG** — carrier label PNGs must be flat raster.
151
+ If one isn't, `buildFromPngLabels` throws; fix = GD normalize (flatten/de-interlace) or TCPDF.
152
+ - **UPS shipper number must match the endpoint.** Beta hits the UPS **CIE test** endpoint
153
+ (`wwwcie.ups.com`); a production account number there returns `120100`/`120121`
154
+ ("missing/invalid shipper number" / "cannot be used"). Use a CIE-enabled shipper number for
155
+ test, or point at prod UPS. `SHIPPER_NUMBER` is a hardcoded constant in the UPS client.
122
156
 
123
157
  ## Change history
158
+ - 2026-06-18 — Implemented the label-storage rework: request PNG from UPS/FedEx, store the raw PNG, generate the printable PDF on demand via the new `_Component_Library_LabelPdf` (FPDF); dropped Labelary. Added the FedEx tracking-cred config-fallback fix and the `_Loader`→Composer FPDF autoloader toggle. Open: the `labelPdfFile` S3 write still skips on a lazy-model save. (mhammontree)
124
159
  - 2026-06-16 — Repointed the carrier-label/NS-IF tracking-number queries (`upsShipmentApi`, `fedexShipmentApi`, `fulfill`, `createNetsuiteItemFulfillment`) from the dropped `ItemFulfillmentPackages` table to the `ItemFulfillments_TrackingNumbers` bridge — they had been saving the label/`number` to the wrong/null record (reprint `labelPdfFile` null; NS IF missing tracking). Confirmed working on beta. (mhammontree)
125
160
  - 2026-06-10 — Documented carrier shipping label mechanics (UPS/FedEx) + the authoritative GIF label-storage decision and NetSuite IF attachment. (mhammontree)
126
161
 
@@ -6,8 +6,8 @@ project: API
6
6
  client: shared
7
7
  type: workflow
8
8
  status: active
9
- updated: 2026-06-16
10
- owners: ["jcardinal"]
9
+ updated: 2026-06-18
10
+ owners: ["jcardinal", "mhammontree"]
11
11
  files: []
12
12
  related: []
13
13
  ---
@@ -68,6 +68,27 @@ anything repo-specific. The AWS CLI cannot introspect the GitHub App installatio
68
68
  account proves it is not a GitHub/repo/branch problem — connections and App installations are
69
69
  per-account, so the fault is local to the failing account's connection.
70
70
 
71
+ ### Gotcha: a terminated EB instance must be manually re-registered with the load balancer
72
+ We do **not** pay for EB-managed (auto) registration of instances on the load balancer. When you
73
+ terminate an instance — e.g. to force a clean redeploy / fresh `composer install` — the
74
+ **replacement instance is NOT automatically added as an LB target**. Until you register it by
75
+ hand (EC2 → the new instance → add it as a target in the environment's target group), the LB
76
+ keeps routing to the old/healthy target (or none), so your freshly-deployed code **never serves
77
+ traffic** and the deploy looks like it "didn't take" / the bug looks unfixed. After terminating:
78
+ grab the new instance ID, register it as a target, wait for it to go healthy, then test. This
79
+ masquerades as deploy-lag — confirm the LB is actually pointing at the new instance before
80
+ debugging the code. (Seen 2026-06-18 chasing a "missing FPDF / old code still running" loop on
81
+ beta that was really the LB still pointing at a terminated instance's replacement that was never
82
+ registered.)
83
+
84
+ ### On-instance composer install (when a dep is missing post-deploy)
85
+ If a Composer dep is missing on the running instance (e.g. `Class "FPDF" not found` because
86
+ `composer.lock` wasn't committed), you can install it on the box over SSH/PuTTY — but
87
+ `composer require setasign/fpdf:^1.8` must have **no space** after the colon (`fpdf: ^1.8`
88
+ parses `^1.8` as a separate package and errors), and run it as the web app user / `chown` the
89
+ result so the webserver can read `vendor/`. The real fix is to **commit `composer.lock`** so EB's
90
+ `composer install` picks it up — the on-instance install is a stopgap that a redeploy wipes.
91
+
71
92
  ### CloudShell triage commands (read-only)
72
93
  ```bash
73
94
  PIPELINE="<pipeline-name>"; REGION="us-east-1"
@@ -82,6 +103,7 @@ aws codeconnections get-connection --connection-arn "<CONN_ARN>" --region "$REGI
82
103
  ```
83
104
 
84
105
  ## Change history
106
+ - 2026-06-18 — Added two EB-instance gotchas surfaced during the TOGa Supply beta/prod label deploys: (1) terminated instances must be **manually re-registered** as LB targets (we don't pay for auto-registration) — until then the new code never serves traffic and looks like deploy-lag; (2) on-instance `composer require` stopgap syntax (no space after the colon, fix root cause by committing `composer.lock`). (mhammontree)
85
107
  - 2026-06-16 — Documented after a pipeline (API-QC-Security, account 975050298201) failed every
86
108
  run at Source with "[GitHub] GitHub returned an Internal Error"; connection was AVAILABLE and
87
109
  IAM was correct — root cause was a pending GitHub App access-request approval in the
@@ -3,5 +3,5 @@
3
3
  | Doc | Summary | Files |
4
4
  |-----|---------|-------|
5
5
  | [TOGa Supply (toga2-supply) Architecture](architecture.md) | `toga2-supply` is the **React + Vite frontend** for TOGa Supply — warehouse fulfillment tooling (shipment selection, fulfill & ship against carrier APIs, NetSui | toga2-supply/src/api/toga.ts, toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx |
6
- | [Fulfill & Ship](features/fulfill-and-ship.md) | Fulfill & Ship lets a warehouse user select sales-order line items, enter serials, pick a carrier/method, and in one action: create the Item Fulfillment records | toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
6
+ | [Fulfill & Ship](features/fulfill-and-ship.md) | Fulfill & Ship lets a warehouse user select sales-order line items, enter serials, pick a carrier/method, and in one action: create the Item Fulfillment records | toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, toga2-supply/src/pages/FulfilledShipments/view/FulfilledShipmentsPage.tsx, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
7
7
  | [AWS Amplify Build & Deploy (non-prod environments)](workflows/amplify-build-and-deploy.md) | How `toga2-supply` (React + Vite) builds and deploys on **AWS Amplify**. | toga2-supply/amplify.yml, toga2-supply/.gitattributes, toga2-supply/.github/workflows/sync-stage-environments.yml, toga2-supply/.env.qc-security |
@@ -6,15 +6,17 @@ project: TOGa Supply
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-06-16
9
+ updated: 2026-06-18
10
10
  owners: [mhammontree]
11
11
  files:
12
12
  - toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx
13
13
  - toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx
14
14
  - toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx
15
15
  - toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts
16
+ - toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx
16
17
  - toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx
17
18
  - toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts
19
+ - toga2-supply/src/pages/FulfilledShipments/view/FulfilledShipmentsPage.tsx
18
20
  - _underscore/Model/Client/ItemFulfillment.php
19
21
  - _underscore/Trait/Netsuite/ItemFulfillment.php
20
22
  - _underscore/Component/Library/Carriers/Ups/Ups.php
@@ -57,13 +59,18 @@ GroWrk, June 2026); FedEx + UPS both need verification before prod.
57
59
  `saveShipmentToNetsuite` → `createNetsuiteItemFulfillment`, which attaches the label
58
60
  to the IF **after** creating it (the IF doesn't exist yet when the label is bought).
59
61
 
60
- ## Reprint (first pass — being reworked)
62
+ ## Reprint (being rewired to the backend)
61
63
 
62
- Fulfilled-shipments view: multi-select shipments, merge each stored label into one
63
- multi-page PDF with `pdf-lib`, print once. **Superseded by the label-storage decision**
64
- (see the carrier-shipping-labels doc): labels will be stored as raw carrier GIFs and
65
- the combined PDF generated on demand — note `pdf-lib` cannot embed GIF, so generation
66
- likely moves to the backend.
64
+ Fulfilled-shipments view (`FulfilledShipmentsPage` → `ShipmentsCardTableForm` with
65
+ `isFulfilledShipmentsView`): multi-select shipments, merge each stored label into one
66
+ multi-page PDF, print once. The label-storage rework (see the carrier-shipping-labels doc)
67
+ now stores the raw carrier **PNG** on `TrackingNumbers.labelPdfFile` and builds the PDF on the
68
+ **backend** (`_Component_Library_LabelPdf`/FPDF). So the current client-side `pdf-lib` merge —
69
+ which reads `labelPdfFile` expecting a base64 **PDF** — is now **stale**: it receives a PNG.
70
+ Reprint must be rewired to call a backend generate endpoint that returns the combined
71
+ (shipping + return) PDF; until then it won't produce a printable label even when one is stored.
72
+ The reprint reference was also corrected from `shipment.itemFulfillmentPackages` to
73
+ `itemFulfillmentTrackingNumbers` (bridge migration).
67
74
 
68
75
  ## Gotchas / known issues
69
76
 
@@ -117,11 +124,24 @@ likely moves to the backend.
117
124
  `item-fulfillment-tracking-numbers` bridge requires the bridge record's ACL logic-group
118
125
  chain to exist for the user's role, or it 403s and `itemFulfillmentTrackingNumbers` returns
119
126
  `null` (so reprint has no label). See the tracking-number-bridges doc's ACL gotcha + fix.
127
+ - **Two separate page components + a scroll/clip trap.** `/shipments` renders `ShipmentsPage`;
128
+ `/fulfilled-shipments` renders `FulfilledShipmentsPage` — **separate components** (a fix to one
129
+ does NOT touch the other; the shared list is `ShipmentsCardTableForm`). Both pages used
130
+ `overflow-scroll` across nested containers — Tailwind `overflow-scroll` forces *always-visible*
131
+ scrollbars (the "scrollbars everywhere" look) — and `FulfilledShipmentsPage`'s outer had
132
+ `h-full min-h-full max-h-full` with **no overflow**, so its content (incl. the Reprint button
133
+ below the `min-h-[862px]` form) was clipped by `AuthLayout`'s `overflow-hidden` with no way to
134
+ scroll to it — the button was only reachable when zoomed out. Layout chain: `AuthLayout`'s
135
+ content area is `h-[calc(100vh-80px)]` inside `overflow-hidden`, so **each page's outer must own
136
+ its own scroll** (`h-full overflow-auto`). Fix (2026-06-18): `overflow-scroll` → `overflow-auto`
137
+ everywhere (and `overflow-y-auto` on the `max-h-[530px]` card list in `ShipmentsCardTableForm`),
138
+ and the fulfilled-page outer → `h-full overflow-auto`.
120
139
 
121
140
  ## Remaining work
122
141
 
123
- - Label storage + reprint rework per the carrier-shipping-labels doc (raw GIF +
124
- on-demand combined PDF).
142
+ - Reprint rewire: call the backend `LabelPdf` generate endpoint (PNG → combined PDF) instead
143
+ of the stale client-side `pdf-lib` merge (per the carrier-shipping-labels doc). The backend
144
+ half (PNG store + on-demand PDF) is done.
125
145
  - Return-label flow: `returnTrackingNumberId` (nullable) on `ItemFulfillmentItemUnits`;
126
146
  "needs return label" checkbox; return-address editable combo ("Rolodex pattern" of
127
147
  client locations, overridable, validated); "return label" text on return pages of the
@@ -138,5 +158,6 @@ not the base `_Model_Client_ItemFulfillment`. Tested with GroWrk; UPS support wa
138
158
  for Compass and is not yet in prod.
139
159
 
140
160
  ## Change history
161
+ - 2026-06-18 — PNG label-storage rework reflected on the frontend: labels now store as PNG and the PDF is built on the backend (`LabelPdf`), so the client-side `pdf-lib` reprint is stale and must be rewired to a backend generate endpoint. Fixed the Fulfilled Shipments responsiveness/clip bug (Reprint button unreachable at 100% zoom) — `overflow-scroll` → `overflow-auto` and gave `FulfilledShipmentsPage`'s outer its own scroll; documented the `/shipments` vs `/fulfilled-shipments` two-component trap and the `AuthLayout overflow-hidden` clip. (mhammontree)
141
162
  - 2026-06-16 — Drove the full beta flow green for UPS/GroWrk. Updated the save step to the `/item-fulfillment-tracking-numbers` bridge (FE commit `b5c16592d`, key `itemFulfillmentTrackingNumbers`). Added gotchas: local-FE↔deployed-beta-BE skew, `dtSubmitted` fulfilled/pending gating, `createNetsuiteItemFulfillment` orderLine fragility on partial/already-fulfilled orders, and the bridge-ACL 403 that nulls tracking/labels (reprint). (mhammontree)
142
163
  - 2026-06-10 — Documented the Fulfill & Ship flow (SO sync, label purchase, NetSuite IF creation, success gating, reprint). Driven green on beta for UPS/GroWrk; FedEx + prod verification pending. (mhammontree)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.133",
3
+ "version": "1.0.134",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",