# BigQuery changelog (/docs/bigquery-changelog)



This log covers the **customer-scoped BigQuery views**, not the [REST API changelog](/docs/changelog). An entry describes an observed schema or a verified source-model change; a source migration date is **not** a promise that every customer view was refreshed on that date. Check your own environment's `INFORMATION_SCHEMA.COLUMNS` before depending on a new field. New nullable fields and view changes can appear at different times in development, staging, and production. The [BigQuery guide](/docs/bigquery) explains how to export safely; the [field reference](/docs/bigquery-fields) records a dated example of the available views.

## 2026-10-26 — Ledger tabs: purchase lines say price, discount and net (source code, not deployed) [#2026-10-26--ledger-tabs-purchase-lines-say-price-discount-and-net-source-code-not-deployed]

* **Status:** a source-model and code change under review, not applied in any environment.
* **Changed, `purchase_line_items` on ledger tabs** (`tabs.ledger_account_id` set):
  * `total_amount_cents`: the price of the units the payment covers before every discount (was: after discounts given before payment).
  * `applied_total_discount_amount_cents`: every discount on those units for the payment, given before payment (staff discounts, price changes, loyalty-integration discounts, vouchers on the order) or at it (was: the payment-time discount only).
  * `pre_discount_vat_amount_cents`: the VAT of `total_amount_cents`.
* **Unchanged:** `total_amount_cents - applied_total_discount_amount_cents`, `final_amount_cents`, the VAT columns, `purchase_vats`, purchase amounts, refunds, and every line outside the ledger.
* **Action:** on ledger tabs, read gross sales as `SUM(total_amount_cents)` and discounts as `SUM(applied_total_discount_amount_cents)`. Ledger lines written before this release keep the earlier meaning. This replaces the purchase-line points of the 2026-10-22 entry.

## 2026-10-22 — Tab ledger: what the release changes in your data (source code, not deployed) [#2026-10-22--tab-ledger-what-the-release-changes-in-your-data-source-code-not-deployed]

* **Status:** a source-model and code change under review. It is not applied in development, staging, or production, and no customer view of the new tables exists yet. This entry describes the release as it will ship and replaces the tab-ledger and voucher entries of October 19–21. A later entry will record each environment, and each customer view once it is checked.
* **Which tabs:** a location turns the tab ledger on through a location feature, location by location. Only tabs **created** after that get a ledger account. Tabs that already exist, open or closed, are not backfilled and finish as before. Everything below marked "ledger tabs" applies only to tabs with a ledger account.
* **New nullable UUID columns** on existing views:
  * `tabs.ledger_account_id`: the tab's ledger account.
  * `purchases.discharge_id`: set when a payment on a ledger tab is confirmed.
  * `purchase_refunds.discharge_id`: set when a refund on a ledger tab is confirmed.
  * Setting `discharge_id` also advances `updated_at`.
  * A payment's `discharge_id` changes again only if the purchase leaves `confirmed`, or its payer moves to another tab.
* **A tab can leave the ledger.** When the ledger cannot record a change, the change still goes through and the tab continues on the previous calculation.
  * `tabs.ledger_account_id` becomes NULL, and that account's ledger rows stop growing.
  * Later payments have a NULL `discharge_id`.
  * Treat a ledger account as complete only while a tab still points at it.
* **Planned tables** (not in any customer view yet; fields in the [field reference](/docs/bigquery-fields)):
  * The ledger: `ledger_accounts`, `ledger_charges`, `item_charges`, `fee_charges`, `charge_tax_rates`, `ledger_reductions`, `ledger_discharges`, `ledger_allocations`.
  * Applied discounts: `account_discounts` (name, kind, value) and `discount_reductions`.
  * The sources of those discounts: `manual_discounts` (given by staff) and `voucher_discounts` (one discount per redeemed Karma voucher).
  * `tab_purchase_discounts`: the payment attempt each discount came with, and its `scope`. `payment` means bound to that payment, in its lines' `applied_total_discount_amount_cents`. `order` means given on the items before payment.
  * Every table is append-only: a correction is a new row with `reverses_id`, never an edit.
  * Identifiers are time-ordered UUIDs (version 7).
  * The tables have no `location_id`; the planned views scope them through the owning tab.
  * `account_discounts` holds applied discounts and is unrelated to the `discounts` definitions view.
  * Integration-specific discount detail, partner redemption records, and the ledger's internal planning and failure tables are not planned as customer views.
* **Purchase lines on ledger tabs.** The meaning of every column is unchanged, and the paid line is still `total_amount_cents - applied_total_discount_amount_cents`. What is new:
  * **No discount entries in `applied_modifications`.** Vouchers and other discounts no longer appear there with a negative `priceAdjustmentCents`. A discount's name and source are in the ledger tables.
  * **Amount payments** (a guest paying part of a tab by amount) are `type = 'product'` lines carrying the share's `quantity_cents`, which can be fractional. They are not `type = 'amount'` lines.
  * **Line VAT:** `total_vat_amount_cents` is the VAT of the line's net total. It can differ from per-unit VAT times quantity by at most one minor unit per unit. `pre_discount_vat_amount_cents` is always written. `purchase_vats` is the sum of the lines' VAT per rate.
* **Discounts given before payment** are already in the kitchen line's `price` and in the purchase line's `total_amount_cents`, as before. On ledger tabs this covers staff discounts, price changes and loyalty-integration discounts. The ledger writes `kitchen_dispatch_items.price`, `discount` and `allocated_*`. Nothing is written to `kitchen_dispatch_items.discount_details`.
* **Tab columns on ledger tabs:**
  * `paid_amount_cents` and `paid_amount` are payments net of refunds, plus the discounts bound to those payments.
  * A purchase that leaves `confirmed` lowers paid at once.
  * `remaining_balance_cents` is `total_amount_cents - paid_amount_cents`, never below zero.
  * Report sales from purchases and refunds, not from tab columns.
* **Marketplace orders, on every tab:**
  * The intake writes the prepaid purchase's lines before confirming it, so the tab shows the purchase amount as paid from intake: goods plus booked marketplace fee lines, minus the merchant-funded discount. Previously it stayed 0 until a later update.
  * Fee lines are not part of the tab total, so paid can exceed `total_amount_cents`.
  * A repeated delivery of the same external order creates nothing.
  * On ledger tabs, the merchant-funded discount is `applied_total_discount_amount_cents` on the food lines, with no negative `marketplace_discount` line. Tabs outside the ledger keep the negative line.
  * Some marketplace purchases stay `pending` for a moment between intake and confirmation.
* **Value vouchers of a POS integration** are a payment of their own, on every tab:
  * A voucher that pays a whole order is one purchase with a new provider value in `purchases.psp`.
  * A voucher that pays part makes two purchases on the tab: the voucher's, then the rest paid by the guest's method.
  * Neither purchase's lines carry the voucher as a discount.
  * Promotion codes of that integration are applied discounts, as Karma vouchers are.
* **`discounts` view:**
  * Stored value is a gift card, never a voucher. A source migration sets `enabled = false` on every enabled `GIFT_CARD` voucher that is not a template.
  * New vouchers hold no balance (`balance_mode = 'NONE'`), and `remaining_balance_cents` is no longer deducted on redemption. Existing balances stay as recorded.
  * Gift-card templates are unchanged.
* **Voucher rules at payment**, on every payment path:
  * Loyalty enrollment and tier are checked against the paying guest.
  * Per-person limits count each guest on a shared tab separately.
  * Two vouchers that cannot be combined are not both accepted.
  * A refused code refuses the payment's other codes.
  * User, e-mail, phone and segment restrictions are not checked at payment, as before.
  * On ledger tabs, each voucher is its own applied discount, named by the voucher's public title or `Voucher: <code>`, and is sized on what the paying guest pays.
* **Breaking: `kitchen_dispatch_items.discount_details` is dropped.** A source migration that runs after the deploy removes it. A replicated column can linger with its old values, and the customer view loses it at its next refresh. Stop selecting it before then. An integration's internal tab-lock and receipt tables, which no customer view exposes, are dropped too.
* **Unchanged:** every tab outside the ledger keeps today's lines, VAT and tab columns, apart from the marketplace, value-voucher and voucher-rule changes above.
* **Validation:**
  * Replaying 189,985 production tabs through the ledger: 189,959 reproduced their recorded money. 24 (0.013 %) would leave the ledger, for documented reasons: 17 items paid above their current price, and 7 overpayments. 2 differ because of concurrent payments the stored rows cannot reproduce.
  * The ledger's line builder against 4,854 recorded purchases: 0 differences in total, discount, quantity, rate or line count.
  * 41 end-to-end payment flows: no tab left the ledger.
* **Consumer action:**
  * Stop selecting `discount_details`.
  * Do not expect discount entries in `applied_modifications` or `type = 'amount'` lines for tabs with a `ledger_account_id`.
  * Treat an unknown `purchases.psp` value as a payment, not as card revenue.
  * To report discounts by name and source, plan to read `account_discounts` with `tab_purchase_discounts` once a later entry announces the views in your environment.

## 2026-10-20 — Development source changes; customer-view availability remains separate [#2026-10-20--development-source-changes-customer-view-availability-remains-separate]

The October 19–20 development-source review adds per-item voucher rates,
receipt-specific item/variant names and loyalty identifiers to the release
preview. This review performs no customer-view refresh, replication check or
warehouse backfill and announces no new production BigQuery columns or views.

* **Mixed voucher rates:** checkout carries the matched rate of each participating line through discount and VAT allocation, including amount-mode partial payments. For sales reporting, use the recorded line and purchase amounts; a single blanket percentage cannot reproduce every mixed-rate bill. Existing restrictions, excluded nested amounts and maximum discounts remain relevant.
* **Receipt names:** the source adds optional API `receiptTitle` values and saved purchase-line receipt text. A guest-facing receipt label is distinct from the internal/reporting item title. Do not assume `receipt_title` is selectable from a customer view until that view's metadata confirms it.
* **Loyalty and usage details:** unique guest fields, program identifiers and AI request-cost estimates do not by themselves establish advertised warehouse fields. Historical AI estimates and gross request costs are not final invoice amounts or a sales-ledger backfill.
* **Reporting fixes:** configured organisation numbers appear in application PDF headers; Caspeco staff attribution and payment recovery fixes do not announce a new customer-view schema or a historical data rewrite.

The previously checked price-cluster view availability and its development/test
scope remain unchanged. See the [API changelog](/docs/changelog) for the source
contracts and the [BigQuery guide](/docs/bigquery) for the verified warehouse
contract.

## 2026-10-19 — Upcoming dev changes with reporting implications [#2026-10-19--upcoming-dev-changes-with-reporting-implications]

Source review compares `dev` with the production branch, `main`, on October 19.
These changes are pending on `main`.
&#x2A;*This source review itself performs no customer-view refresh, production replication check or historical backfill.** The separately recorded October 19 price-cluster sync below is the latest development/staging customer-view update on `dev`; the older field reference remains a dated snapshot. Check your dataset before changing an export.

* **Historical refunds and Save service fees:** the dev refund flow supports eligible historical purchases and returns the refundable Save service-fee portion. The REST purchase response exposes fee/refund details, including `serviceFeeRefundAmountCents`; that camel-case response property is not a verified customer-view column. Reconcile confirmed refunds, their product allocations and any service-fee return separately; do not assume a product-line sum includes the entire provider refund. Existing nullable `purchase_refund_line_items.quantity_cents` semantics remain unchanged: explicit units use hundredths, while amount-only and historical rows need not have a quantity. No quantity backfill is announced.
* **Remakes and supplements:** the dev order model introduces `ambulance_kind` with `charged` and `supplement` values. Charged remakes retain their price; supplements and their children are forced to zero and handled separately on kitchen tickets/KDS. The application requires central database migrations, but this review does not establish a corresponding customer-view column, its BigQuery type or its null behavior. Do not substitute `zero_ticket` for a remake classification or infer one from a zero amount. The follow-up also exposes nullable `ambulanceKind` on REST purchase lines and labels remakes in merchant history; this property comes from the linked kitchen dispatch item and does not establish a new purchase-line column in BigQuery.
* **Inventory, recipes and history:** the optional ingredient/recipe model, reviewed stocktakes and `inventory_item_versions` configuration journal are source/application additions. No ingredient, recipe, stocktake or version-history customer views were verified for this entry. Recipe-derived purchase cost, nutrition and current shared/cluster prices are configuration or estimates; they do not rewrite recorded purchase-line prices, VAT or historical cost. Inventory configuration history excludes stock-only changes and starts with the first captured baseline.
* **Current prices and table grouping:** Foodora, Wolt and Uber Eats publication uses the shared pricing implementation with location/channel overrides; this changes current menu publication, not the historical sale ledger. The reporting API's `hasTable` distinction separates OTC sales from tables without a group; it is not an announced BigQuery column. For warehouse reporting, use only table relationships actually present in your authorized views.
* **Receipt presentation and storefront settings:** dev receipt rendering replaces voucher-code labels with public discount names or a generic label and masks codes in voucher payment summaries. This does not establish changes to stored discount/voucher data, customer-view columns or historical rows. The storefront ratings toggle and confirmation-content editor are presentation changes, not warehouse schema additions.
* **Caspeco corrections:** the dev exporter sends confirmed refunds for already-exported sales as deduplicated correction tickets, booked on the refund's day and linked to the original receipt. This is an integration export behavior, not a new BigQuery refund schema or an independent refund payout-method field. It does not change the original purchase's sale date or state. Refund corrections default on and can be date-restricted or disabled in the integration settings.

## 2026-10-12–18 — Production-branch reporting fixes [#2026-10-1218--production-branch-reporting-fixes]

These direct commits and cherry-picks were recorded on `main` during October
12–18 in Europe/Stockholm. They describe application behavior in that branch;
deployment, Datastream replication and customer-view availability are separate.

* **October 12 — Per-location reporting days:** combined SIE/CSV/PDF exports, Fortnox vouchers and purchase summaries apply each included location's calendar/business-day setting. The exporting location honors the requested setting; children use their own saved setting, defaulting to calendar day. A warehouse reconciliation must reproduce those per-location windows rather than apply the parent's window to every child. This changes export selection, not the meaning or type of `purchases.purchased_at`, and announces no data backfill.
* **October 12–13 — State and configuration fixes:** nearest-parent pricing and inherited course names resolve correctly, stock reports honor their filters, and verified late-authorization cancellations are reconciled. Continue filtering finalized sales/refunds by their recorded confirmed state; an authorization or cancellation is not itself a finalized sale or refund. No new customer-view column or historical rewrite is established by these commits.
* **October 12–15 — Operational and commercial reporting:** Adyen report-cost processing is batched and bounded. Team Pulse/progression uses verified daily activity and transaction revenue, including Swish totals checked against the canonical intent, with corrected contributor attribution, deduplication and Stockholm daily limits. These internal reporting fixes do not add customer-scoped BigQuery views or alter the warehouse payment/refund contract.
* **Other production-only fixes:** saved-card CVC capability, scheduled article visibility, refund receipt labels, voucher reset, the HOLD banner and the October 17 POS touch-quantity cherry-pick are included in the [release notes](/docs/changelog). They announce no customer-view schema change.

## 2026-10-19 — Price-cluster sync enabled in development and staging [#2026-10-19--price-cluster-sync-enabled-in-development-and-staging]

* Added `price_clusters`, `price_cluster_entries`, `price_cluster_locations`, and `price_cluster_applications` to the existing PostgreSQL publications and Datastream streams in development and staging/beta. All four backfills completed in each environment, and both streams reported running without stream errors.
* Created and authorized the four customer-scoped views in development `customer_location_5182` and staging `customer_location_1500000000`. Each dataset now advertises **449 columns across 30 views**, with matching table/column/type inventories. Cluster ownership is restricted through the existing `location_members`; location/application rows also require an in-scope target location.
* All four views are queryable. The checked EH scopes currently return zero rows, matching the scoped source data; this is not missing replication. Existing dataset permissions were preserved. Connectors should refresh their view inventory and metadata.
* These views describe current pricing configuration, not historical charged prices. Use recorded purchase lines for past sales. This operation did not change or verify production customer views.

## 2026-10-12 — Reporting clarification and dev/test parity recheck [#2026-10-12--reporting-clarification-and-devtest-parity-recheck]

* Rechecked the existing development `customer_location_5182` and staging `customer_location_1500000000` view inventories: **429 advertised columns across 26 views**, with identical table/column/type tuples. `zero_ticket` is `BOOL`, refund-line `quantity_cents` is `INT64`, and `printer_jobs.rendered_content` is absent. No top-level `BYTES` column is advertised in either checked inventory. This is a recheck, not a new deployment or a production/customer-wide availability claim; the customer's connector run must be verified separately.
* Clarified that sales-line `item_type` is extensible text. The guide lists current goods/non-goods classifications and adds an unknown-value preflight before irreversible uploads. Inventory catalogue `itemType` and legacy item-type references are separate contracts.
* Added the checked multi-purchase tab example, fractional product allocations, flat split-bill modifier limitations and the kitchen-link article fallback. These explain recorded data; no corrected marketplace price split, modifier parent-link repair or historical backfill is announced.
* Documented historical pre-discount line VAT and purchase/line rounding differences. Current discount writers calculate post-discount line VAT, but the example observations do not establish an exact rollout timestamp or repair older rows. Use recorded purchase-level VAT for purchase reporting.
* Documented partner-specific tab member lookup and its mutable tab scope. Confirm the integration's actual JSON key with Karma. An immutable per-payment member export, independent refund payout method and returns without an original Karma sale are not supplied by the checked customer-view contract. These are explicit limitations, not new fields.

## 2026-10-08 — Development/staging customer-view schema convergence [#2026-10-08--developmentstaging-customer-view-schema-convergence]

* Refreshed the existing customer views in the checked development (`customer_location_5182`) and staging (`customer_location_1500000000`) datasets. Afterward, each advertises **429 top-level columns across 26 views**, with identical table/column/type tuples. The existing location filters and authorized-view grants were preserved; this is **not** a claim about production datasets or every customer's separate dataset.
* `kitchen_dispatch_items.zero_ticket` is now advertised as `BOOL` in both views (KAR-150). `printer_jobs.rendered_content` (`BYTES`) is removed from both customer views (KAR-149); the upstream operational table still contains it. `rendered_at` and `rendered_media_type` are advertised in both customer views. Connectors should re-probe view metadata, not the raw source table.
* `purchase_refund_line_items.quantity_cents` is now advertised as `INT64` in **both** checked customer views. Historical and amount-only allocations remain nullable; no quantity backfill is asserted. Previously hidden source columns in `items`, `kitchen_dispatch_items`, `kitchen_dispatches`, and `purchase_line_items` were refreshed into both views; consult the [field reference](/docs/bigquery-fields) for the newly observed fields.
* Dev-only `purchase_line_items.pre_discount_value_cents` and `purchases.processed_by_retailer_user_id` were removed **from the dev customer views**: neither exists in the checked development PostgreSQL source, although both linger in its replicated BigQuery source tables. The dev-only `kitchen_dispatch_items.is_surplus` customer-view column was also removed to match staging: it exists in dev PostgreSQL but not staging PostgreSQL, and is **not** interchangeable with `item_type = 'surplus'` (seven mismatches in a checked recent dev sample). For a sold-line surplus flag, use `purchase_line_items.is_surplus`. None of these three changes deletes source data.
* The parity check compared stored `INFORMATION_SCHEMA.COLUMNS`, not just a `SELECT *` sample. After the view refresh, no table/column/type difference remained between the two checked customer datasets. Raw Datastream tables can still differ from live PostgreSQL when dropped columns linger; do not treat this view parity as upstream CDC cleanup.

## 2026-10-06 — Production source release; customer-view availability is separate [#2026-10-06--production-source-release-customer-view-availability-is-separate]

* The October 6 production release applied the refund-control and price-cluster source migrations, including linked cluster pricing, hidden refund reasons and descendant prepaid-account export settings. This supersedes the earlier source-branch availability check below; it does **not** verify production Datastream replication or customer-view provisioning.
* Product refund allocations can record nullable `purchase_refund_line_items.quantity_cents` in hundredths of a unit: **100 means one unit**. Amount-only and historical refunds can remain `NULL`; no quantity backfill is announced. Check your customer view's metadata before selecting it. The October 8 observation above verifies the column in the checked development and staging views only.
* Price clusters describe current menu-price configuration, not the historical price charged. For historical sales use the recorded purchase lines. No production customer-view availability is asserted for the four price-cluster tables or the refund-settings tables.

### Earlier October 6 preparation check [#earlier-october-6-preparation-check]

* A source migration defines `price_clusters`, `price_cluster_entries`, `price_cluster_locations`, and `price_cluster_applications` for current grouped-price configuration. The migration was **not in the checked remote database `dev` branch** on October 6; this is not an announcement of replicated tables or customer views.
* Customer-scoped, authorized views for all four tables have been prepared. They require the owner location to be in the customer's `location_members`; location/application rows additionally require their target location to be in scope. Do not query them until replication, customer-view provisioning, and dataset metadata are verified for your environment. These tables are not a historical sale-price ledger.

## 2026-10-05 — Discounts in development/staging; refund quantity in development [#2026-10-05--discounts-in-developmentstaging-refund-quantity-in-development]

* The `discounts` PostgreSQL source was **already included** in the running main Datastream streams in development, staging, and production, with completed backfill objects and replicated `analytics_eupublic.discounts` tables in all three. No stream inclusion change was needed. The separate legacy production stream does not own this dataset and was left untouched.
* Customer-scoped `discounts` views were created and authorized in the existing development and staging customer datasets on October 5. Each filters `discounts.location_id` through that dataset's `location_members`; the checked staging view returned 13 rows and zero out-of-scope rows. There was **no production customer dataset** in the checked production project, so this entry does not claim a production customer view or customer access. The view reports current discount/voucher definitions, including gift-card configuration, **not** an applied-discount or redemption ledger. The [field reference](/docs/bigquery-fields) records 34 view columns observed in staging.
* `purchase_refund_line_items.quantity_cents` is now present in the development upstream BigQuery table and advertised as `INT64` by the refreshed development customer view. It remains absent from the checked staging upstream table and customer view; production upstream metadata also does not advertise it, and no production customer dataset was available to check. It is not included in the staging inventory. Amount-only and historical refunds still lack a recorded quantity; no backfill is announced. Before selecting the column, confirm its presence in **your** customer view.

## 2026-10-04 — Refund quantities in remote `dev` source model (not yet in customer views) [#2026-10-04--refund-quantities-in-remote-dev-source-model-not-yet-in-customer-views]

* The database `dev` branch adds nullable, positive-integer `purchase_refund_line_items.quantity_cents`. The purchase service's `dev` branch writes it when an explicit product quantity is selected for a refund: **100 means one unit**, and 150 means 1.5 units. This is the quantity on a refund allocation to the original purchase line, not a currency amount and not the original sale's `purchase_line_items.quantity_cents`.
* An amount-only refund leaves the new field `NULL`; older refunds also have no recorded refunded quantity. Do **not** infer returned units from monetary allocations or treat `NULL` as zero returned units. Continue using `total_amount_cents` for the refunded monetary magnitude and restrict financial reporting to confirmed refunds.
* **Availability check (October 4):** Neither the development nor staging customer view advertises this column in `INFORMATION_SCHEMA.COLUMNS`; it was also absent from the checked development upstream BigQuery table. No customer-view column addition or backfill is announced. Before selecting it, check your own view metadata and confirm it is queryable. The [field reference](/docs/bigquery-fields) retains its September 28 inventory and notes this pending field separately.
* The same source migration adds location refund settings and reason definitions; no corresponding customer views were observed. Other recent source additions (including gift-card details and location seasonality) were not observed as newly advertised columns in the checked customer views. They are **not** part of this customer-view schema announcement.

## 2026-09-28 — Staging schema inventory [#2026-09-28--staging-schema-inventory]

* A staging customer dataset exposed **25 views and 380 advertised top-level columns** when the field reference was prepared. This is a **snapshot, not a versioned promise** about other customer datasets or production.
* Confirmed reporting interpretation: `purchases.id` identifies the purchase within an environment; `purchases.purchased_at` is the UTC sale time represented as a BigQuery `TIMESTAMP`; `purchase_refunds.purchase_id` ties refunds back to the original purchase. `purchases.cr_receipt_id` is a separate, nullable fiscal reference and not a universal export key.
* A confirmed sale remains `confirmed` after a refund; a technical zero-refund may instead reference a failed purchase. Only `confirmed` purchases count as finalized sales, and only `confirmed` refunds count as finalized refund records. For an article export, `purchase_line_items.type = 'product'` is the starting filter, with non-goods `item_type` exclusions and separate treatment of tips and amount payments.
* **Known schema mismatch:** `kitchen_dispatch_items.zero_ticket` exists and resolves as `BOOL` when queried in the staging customer view, but that view's stored schema and `INFORMATION_SCHEMA.COLUMNS` do not yet list it. Inferring the type from one nullable row can produce a false string/boolean mismatch. A view-schema refresh and connector recheck are needed; this log does **not** claim the fix has been deployed.
* **Known connector limitation:** `printer_jobs.rendered_content` is `BYTES` in the staging view. Connectors that cannot ingest binary data from `SELECT *` must omit it or use a deliberate Base64 `STRING` projection. No customer-view type change is announced here; confirm whether you need the payload before changing an established column.

## 2026-09-22 — Variants in development and staging [#2026-09-22--variants-in-development-and-staging]

The customer-scoped `variants` view and its read authorization were verified in development and staging. It restricts variants through the owning variant group's location and the customer's `location_members`. A variant's optional `item_id` is **not** the ownership filter. This does not assert that every production customer dataset already has the view; check your dataset's view list before integrating.

## 2026-09-18 — Prepaid reporting code in the source model [#2026-09-18--prepaid-reporting-code-in-the-source-model]

The purchase payment-method model gained nullable `prepaid_type_code`: the configured prepaid reporting code snapshotted at payment time. The same purchase-method record also carries a Karma `payment_method_id` and a human-readable `brand`. The code is the stable choice for an agreed customer reporting mapping; the label is not. The column was observed in the staging customer view in the September 28 inventory. Previously replicated rows may lack detail; do not treat `NULL` as a failed payment. Card-provider enrichment fields also remain nullable.

## 2026-09-15 — Zero-ticket flag in the source model [#2026-09-15--zero-ticket-flag-in-the-source-model]

`kitchen_dispatch_items.zero_ticket` was added as a source-side boolean for an item recorded on the tab but already prepared elsewhere. Its **staging customer-view metadata remains stale as of September 28** (see the known mismatch above). Source schema additions and customer-view schema visibility are separate steps.

## 2026-08-13 — Rendered printer payload in the source model [#2026-08-13--rendered-printer-payload-in-the-source-model]

`printer_jobs.rendered_content` was added as a binary payload. In the September 28 staging inventory, the customer view exposes it as BigQuery `BYTES`. A generic `SELECT *` export can fail in connectors without binary support; select the columns you use or agree a transformed customer view before ingesting it.

## 2026-06-26 — Fiscal refund registration fields in the source model [#2026-06-26--fiscal-refund-registration-fields-in-the-source-model]

Refund records gained nullable `cr_receipt_id` and `cr_registered_at` for the **refund's** later fiscal cash-register booking. Both fields were observed in the staging customer view in the September 28 inventory. They do not replace `purchase_refunds.purchase_id`, `purchase_refunds.id`, or the original sale's `purchased_at`.

## Maintaining this log [#maintaining-this-log]

When a customer-visible BigQuery field or view changes, record **the environment, date observed, view/column, old and new types/meaning, null/backfill behavior, and any required consumer action**. Do not call a source migration “available to customers” until the customer view and its metadata have been checked. Customer dataset access and production rollout are verified separately from the source schema.
