fix(parties): skip nameless suppliers and customers in the party backfill (#2174)
* fix(parties): skip nameless suppliers and customers in the party backfill The substrate migration failed on prod at the backfill: three rows (one supplier, two customers) have an empty name and ensure_party refuses a nameless party. The file never applied there, so it is corrected in place rather than chased with a migration that could not run before it. Rows without a name keep party_id NULL; the suggestion pipeline names them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(parties): ensure_party writes only under the caller's own identity Authenticated callers must pass their own user id; the service role (auth.uid() NULL: migrations, MCP, cron) may act for another user. Same guard as apply_party_suggestions and decide_parties. Superagent P2 on #2172. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
Jakob Wennberg
parent
daeab67dca
commit
a24982463b
@@ -139,6 +139,24 @@ describe('parties substrate (pg)', () => {
|
||||
expect(visibleToStranger).toBe(0)
|
||||
})
|
||||
|
||||
it('ensure_party refuses a p_user_id that is not the authenticated caller', async () => {
|
||||
const mine = await seedCompany()
|
||||
const other = await seedCompany()
|
||||
await expect(
|
||||
withUserContext(mine.userId, (client) =>
|
||||
client.query(`SELECT public.ensure_party($1, $2, 'Spoofed AB', NULL, 'company', 'manual')`, [mine.companyId, other.userId]),
|
||||
),
|
||||
).rejects.toMatchObject({ code: '42501' })
|
||||
const own = await withUserContext(mine.userId, async (client) => {
|
||||
const { rows } = await client.query<{ id: string }>(
|
||||
`SELECT public.ensure_party($1, $2, 'Own AB', NULL, 'company', 'manual') AS id`,
|
||||
[mine.companyId, mine.userId],
|
||||
)
|
||||
return rows[0]!.id
|
||||
})
|
||||
expect(own).toMatch(/^[0-9a-f-]{36}$/)
|
||||
})
|
||||
|
||||
it('refuses to attach facts, identities, decisions, roles or merges to another company\'s party', async () => {
|
||||
const mine = await seedCompany()
|
||||
const theirs = await seedCompany()
|
||||
|
||||
Reference in New Issue
Block a user