Columbia Games / CCM v2 / 20 October 2026
After the support sprint came the hardening: Columbia Games releases, entitlements and Game Dollars
Since the previous Columbia Games diary, we shipped session-aware retailer recommendations, Unicode rendering fixes, dependency updates and admin configuration guards. We executed and retired a one-time customer-region migration, simplified CI, and reinforced Game Dollars checkout limits with 23 targeted test cases. Production deployment and post-deploy QA passed, while genuine retailer UAT remains a separate acceptance step.

Situation
The October 19 worklog described how fragmented Columbia Games support emails became an evidence-based engineering backlog: retailer shipping and configuration, PayPal, digital entitlements, PDFs, media caches, PostgreSQL imports and production diagnostics. That entry was about establishing what was actually broken, what had been fixed, and what still needed a business decision. From the evening of October 19 into the morning of October 20, the focus moved from triage to releases and operational hardening: session-scoped recommendations, Unicode rendering, admin scope integrity, dependency security, CI cost, migration lifecycle and Game Dollars checkout boundaries. This is the next chapter rather than a repeat of the previous support inventory.
Approach
We split the work into narrowly scoped pull requests, reproducible regressions and separate production releases. GitHub main and production history, PR diffs, CI checks, deployment logs and post-deploy QA were treated as independent evidence. Database changes required recoverable backups and an audit trail; code-level defects received isolated tests without customer data writes wherever possible. Nine stories show how that approach turned an intense support day into safer releases and a cleaner engineering process.
1. Retailer recommendations must follow the customer, not just the cart
Earlier retailer catalog filters did not fully address checkout recommendation caching. Under internal CCM Ticket #88, recommendation keys were found to depend mainly on cart SKUs. The same cart under a different authenticated customer or storefront configuration could therefore carry stale suggestions. PR #374 now keys recommendations to customer ID, storefront scope and cart SKU, quantity and price across all eleven storefront variants. Responses from superseded requests are discarded, and personalized API endpoints set `Cache-Control: private, no-store` with `Vary: Cookie`. Focused regressions cover consumer versus retailer membership, eligible prices, missing related-product mappings, forged scope parameters and legacy cart cleanup. Production PR #375 shipped the change. the client's final acceptance still requires a real logged-in retailer browser session: automated coverage does not replace hands-on business UAT.
2. Hârn Unicode: a small visual defect with two rendering paths
Internal Ticket #96 exposed literal HTML entities such as `Hârn` where customers should have seen Hârn or Hârnica. The problem involved different treatment of plain text by React and by JavaScript-free HTML prerendering; it was not evidence that the database itself had been corrupted. The fix decodes safe named and numeric entities on plain-text paths only, then keeps proper escaping in the rendered output. Tests exercise accents, combining Unicode, double encoding and unsafe markup. PR #373 merged the rendering change and PR #376 released it. No blanket database rewrite was implied, and targeted content-owner verification remains useful.
3. Admin configuration: accidentally saving the wrong scope is a data-integrity bug
The earlier worklog reported a fix for preserving `cg/default` versus `cg/retailer` selection during navigation. A deeper defect remained in the checkout-rule editor: fetched form data contained its own `merchantId` and `configId`, which could override a more recently selected scope on save. An out-of-order fetch could recreate the same hazard. PR #377 makes the current selected scope authoritative, rejects stale responses and blocks editing or saving until the correct scope and rule are loaded. PR #379 deployed this as an isolated admin backport. Read-only investigation also confirmed PayPal/Net 30 shipping parity for the four tested retailer methods. None of this silently approves tax or free-shipping policy: those remain commercial decisions, not technical defaults.
4. Security debt: controlled frontend upgrades and restored HTTP headers
A frontend dependency review found 14 advisory records: five high, nine moderate, none critical. The remediation upgraded React Router to 7.18.4, Vite to 6.4.4 and esbuild to 0.25.12 alongside affected transitive packages and the deterministic lockfile. Clean installs, TypeScript checks, bundles and `npm audit` passed on Node 20 and 22, with zero reported vulnerabilities in that tested dependency set. PR #363 was followed by production PR #372. Separately, missing security-header behavior on static storefront routes was addressed through release #371 and main backmerge #380. Header assertions were retained in the consolidated QA gates instead of reviving redundant standalone workflows. Interactive navigation, sign-in, admin and checkout checks still matter after a major frontend upgrade.
5. US states, Canadian provinces and an actually one-time migration
Address normalization now maps supported US state and Canadian province names to canonical two-letter values across profile edits, admin writes, imports, checkout and the PayPal shipping boundary. Historical data needed a distinct, guarded production step. Deployment evidence records three verified database backups followed by one transaction updating 606 region fields across 331 customers: 299 shipping and 307 billing values. The migration ledger and restricted rollback audit were retained. Once execution was confirmed, PR #370 retired the single-use migration code and temporary workflow without removing the generic runner, ledger, backups or rollback evidence; PR #404 documented the archive and retention warning. This is the important lifecycle distinction: a one-off data correction should not become an automatic operation on every future release.
6. GitHub Actions: spend fewer runs, retain meaningful proof
The CI cleanup in #378 and #381 removed five redundant workflows and folded prerender, SEO, Unicode and deploy regressions into existing checks. Production now uses one post-deploy QA workflow, including storefront and security-header smoke, followed by a single local Lighthouse measurement of the mobile homepage. There are no automatic retries, broad page crawls or PageSpeed Insights API calls. One measurement scored 84/100; a single measurement is a snapshot, not an enduring performance guarantee. We also repaired the authorization failure that had blocked automatic production-to-main backmerge PR creation: #382 introduced a dedicated-token path, an allowed fallback and manual retry, with a subsequent successful workflow run. The goal was not 'less testing' but fewer duplicate jobs per actual release.
7. Game Dollars: wallet balance is not the maximum redemption for this order
On October 20, checkout Game Dollars rules became the next major focus. A customer's points balance and the maximum whole Game Dollars redeemable against the merchandise in a specific order are not equivalent. PR #406 calculates and validates the genuine order-specific limit, shows that limit in checkout and distinguishes requested from applied points. It deliberately preserves the existing fractional-redemption policy. The regression suite adds 16 calculator boundary cases and seven offline checkout-level quote and validation cases. Across the eleven storefront variants, we also corrected references to the real `CartItem.unitPrice` field instead of a nonexistent `price` property. Local quality and frontend checks passed, the PR CI was green, and release PR #407 merged into production. GitHub subsequently reported a successful deployment and successful QA tied to that production SHA. No real customer payment or PayPal purchase is implied by those tests.
8. PRINT/PDF markers: a simple checkbox can silently break fulfilment
A morning order investigation uncovered a subtler admin issue. The product editor treated `freebie` as a boolean even though the underlying allowed codes include blank, `Y`, `PRINT` and `PDF`. Saving a print-plus-download product could erase the `PRINT` marker and affect later discounts or shipping classification. PR #405 replaced the checkbox with an explicit selector, constrained the server-side normalizer to supported codes and added GET-to-form-to-PUT round-trip regression coverage. The change reached main and the morning production release. It does not retroactively modify an already paid customer order; any data correction must remain a separate, reviewed operation.
9. Cleanup: branches, migrations and recovery evidence have different lifecycles
The release was followed by repository housekeeping rather than a growing pile of abandoned technical artifacts. Thirty-seven obsolete remote feature and agent branches were deleted while main, production and active work were retained. The completed one-off migration stopped being an ever-present executable step, while hashed backups and rollback evidence remained available. CI followed the same principle: remove disposable diagnostics, keep sustainable regression gates. The result is not just a smaller branch list; it is a system where the next production investigation has fewer ambiguous paths and better evidence.
Outcome
Since the previous diary, production releases have delivered session-scoped retailer recommendations, correct plain-text Hârn rendering, admin checkout-rule scope protection, frontend dependency remediation and static-route header hardening. The one-time region backfill completed with recoverability evidence, then obsolete migration and CI tasks were retired. Game Dollars order limits and PRINT/PDF admin marker preservation reached production in the October 20 release, followed by successful deployment and post-deploy QA. This entry is therefore about closing verified edge cases and streamlining operations, not merely organizing support emails. Real retailer browser UAT, final shipping/tax policy decisions and selected content checks must not be marked complete by inference.