@teamscala/service-boot 0.23.498 → 0.23.500

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.
package/package.json CHANGED
@@ -1130,5 +1130,5 @@
1130
1130
  "repository": "https://github.com/teamgbg/service-boot",
1131
1131
  "sideEffects": false,
1132
1132
  "type": "module",
1133
- "version": "0.23.498"
1133
+ "version": "0.23.500"
1134
1134
  }
@@ -18,6 +18,15 @@
18
18
  * co-branded proposal. The partner is still branding-first; this is the one
19
19
  * access edge it carries.
20
20
  *
21
+ * The partner clause casts to ::uuid because the two sides disagree in the
22
+ * database: client_database.company_id is `uuid` while proposals.partner_id is
23
+ * `text`. Postgres resolves operators at PLAN time, so `uuid = text` raises
24
+ * "operator does not exist" for EVERY proposal — including ones with no partner
25
+ * — the catch below swallows it, and the fail-closed empty Set then denies
26
+ * access to everyone. Measured 2026-09-10: no proposal could be unlocked by any
27
+ * email. The cast is correct once partner_id becomes `uuid` too (a no-op then);
28
+ * the column type is the real fix and is tracked separately.
29
+ *
21
30
  * Uses $queryRaw (raw SQL) deliberately: the per-service Prisma client is scoped
22
31
  * to that service's own models, so the proposals service's client has no
23
32
  * `member`/`user` model methods — but $queryRaw runs against the shared DB
@@ -48,7 +57,7 @@ export async function resolveProposalAuthorizedEmails(
48
57
  UNION
49
58
  SELECT lower(cd.primary_email) AS email
50
59
  FROM client_database cd
51
- WHERE cd.company_id = (SELECT partner_id FROM proposals WHERE id = ${proposalId})
60
+ WHERE cd.company_id = (SELECT partner_id FROM proposals WHERE id = ${proposalId})::uuid
52
61
  AND cd.primary_email IS NOT NULL
53
62
  ` as { email: string }[];
54
63
  return new Set(
@@ -127,7 +127,18 @@ export function singlePageData(
127
127
  pageMetaTitle,
128
128
  templateTitle: (meta.title as string) || undefined,
129
129
  websiteName: (website.name as string) || undefined,
130
- organisationName: (brand.companyName as string) || undefined,
130
+ // FRIENDLY NAME FIRST, matching region-slots-page-data and
131
+ // public-shell-page-data. This was the only one of the four call
132
+ // sites reading companyName alone, and the tab title is where it
133
+ // showed: a white-labelled quiz served brand_name "launcha" with
134
+ // the Launcha favicon while Chrome's tab read "GMG APAC: …" — the
135
+ // TENANT's registered name on a client-facing page. companyName is
136
+ // the legal/registered name; companyFriendlyName is what the brand
137
+ // presents as, so it is what a public tab must show.
138
+ organisationName:
139
+ (brand.companyFriendlyName as string) ||
140
+ (brand.companyName as string) ||
141
+ undefined,
131
142
  pageName: pageName ?? ((pageRoot?.title as string) || undefined),
132
143
  entityTitle: entityTitle || undefined,
133
144
  },