Two items from Narong's "Random Bugs (Unrelated to Development Phase)" page. Both were verified to still reproduce on live staging before any code was written — the previous sweep found 3 of 5 ❌ marks were already stale, so these were checked first. Neither was stale. No migration.
#2 — "A member invited through NIX Cafe can see both products (NIX POS & NIX OS when NIX OS is activated for the user)."
#3 — "Remove Odoo Integration Indicators (dashboard)."
The Launchpad rendered one card per tenant subscription, never consulting the user's
entitlement. Both product apps already reject non-entitled users server-side — nix-cafe's auth() and
Outdoor's ensureBridgeForTenantUser each require an explicit nix_user_product_roles row for
non-owners — so this was never an access hole. It was the portal offering a member a product that would bounce them.
The fix needed no new data: /tenant/auth/me already returns the correct per-user
productRoles (owners get an implicit role on every active product; everyone else gets their
explicit rows, filtered to active subscriptions). The grid simply wasn't using it.
Two follow-ons came out of the same reasoning. The inactive-subscriptions list was the one other place a non-entitled product still appeared, so it's now owner-only — owners keep the billing signal, members don't see NIX OS listed as "cancelled". And a member with no assignments used to land on "Your tenant doesn't have any active product subscriptions — contact NIX Sales", which is the wrong destination for what is an access problem their own admin fixes; that case now has its own copy.

posuser@lumiere-coffee.com — a real cafe-only member over real SSO. One card. Before the fix this same account saw an Outdoor Sales card too.

The amber "Odoo is not linked" banner is gone, and the component is deleted. Narong's note said "(dashboard)", but the banner was one shared component rendered on four pages — Dashboard, Settings, Reports and Reports > Order Analysis — so removing it from only the screen he happened to screenshot would have left the identical banner on three others. 35 deletions, no additions.
Worth stating plainly: this was the only in-app signal that Odoo sync had stopped. After this change a Pro merchant whose link breaks sees nothing in the merchant app — the remaining surface is Cpanel. That matches the intent of not showing merchants internal integration plumbing, but it is a deliberate trade rather than a free removal.

demo.staging — a Pro tenant with Odoo genuinely unlinked, asserted in the test itself so the removal can't be proven against a tenant that never showed the banner.


The staging suite is written against the post-fix state, so it was run once before deploying. Same file, same assertions, both runs:
| Staging run | Result | What it shows |
|---|---|---|
| Before the deploy | 6/11 | both bugs reproduce on the live stack; all 3 preconditions valid; the owner control already green |
| After the deploy | 11/11 | the 5 failures cleared, nothing else moved |
✗ no "Odoo is not linked" banner on dashboard: odoo-unlinked-banner still present ✗ no "Odoo is not linked" banner on settings: odoo-unlinked-banner still present ✗ no "Odoo is not linked" banner on reports: odoo-unlinked-banner still present ✗ no "Odoo is not linked" banner on order analysis: odoo-unlinked-banner still present ✗ member sees ONLY the NIX Cafe card (bug #2): member still sees 1 Outdoor Sales card/link
The local suite has its own control: reverting only the entitlement filter while keeping every testid — so failures isolate behaviour rather than missing selectors — drops it to 4/8, failing on exactly the four entitlement assertions and reproducing Narong's bug verbatim:
✗ Cafe-only member sees ONLY the NIX Cafe card (bug #2): expected ["nix_cafe"], got ["nix_cafe","outdoor_sales"]
Every "banner is absent" and "product is absent" check is anchored on something that must be present first — the cafe card, a rendered page body — because an absence assertion passes happily on a blank page.
| Suite | Result |
|---|---|
Local — real Vue app on vite with /tenant/auth/me stubbed per entitlement shape (+ negative control) | 8/8 |
| Staging — real SSO on the deployed Worker + Pages, asserted against Neon | 11/11 |
| Staging smoke (SSO, cross-tenant guard, Starter login, no-session redirect) | 5/5 |
tsc --noEmit (cafe) · vite build (commerce) · unescaped-@ locale sweep | clean |
Zero prod users are adversely affected — no account would lose a card it can currently use, and there
are no legacy admin-role users who would fall through the owner shortcut. The inverse is the interesting
part: get-coffee's live cafe-only member currently does see a NIX OS card they cannot open, so this fixes a
real annoyance on production the moment it promotes.
nix-cafe staging cf483c0 (Worker f8e538a3) · nix-commerce staging
892a18b (Pages deployed). No migration — adds nothing to the six already parked. Parked for the scheduled
prod promote.