mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 18:41:08 +02:00
fix(website): publish failed with uuid type error on Better-Auth ids
published_by, created_by, and space_id were declared as uuid, but Mana user + space ids are Better-Auth nanoids stored as text. The insert into website.published_snapshots raised `invalid input syntax for type uuid` and Hono swallowed it as a generic 500. Changes: - schema.ts: uuid -> text on the three columns - 0003_fix_id_types.sql: ALTER COLUMN on existing installs - publish.ts: replace UUID regex on X-Mana-Space with a nanoid-shaped check (it was silently nulling valid space ids) - publish.ts: log + return the actual error message on the 500 path so the next unhandled failure is visible instead of opaque Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
645993db01
commit
c404db5b6e
3 changed files with 31 additions and 6 deletions
18
apps/api/drizzle/website/0003_fix_id_types.sql
Normal file
18
apps/api/drizzle/website/0003_fix_id_types.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
-- Website module — fix id column types.
|
||||
--
|
||||
-- `published_by`, `created_by`, and `space_id` were originally declared
|
||||
-- as `uuid`, but Mana user ids (auth.users.id) and space ids
|
||||
-- (auth.organizations.id) are Better-Auth nanoids stored as `text`.
|
||||
-- Publishing failed with `invalid input syntax for type uuid`.
|
||||
--
|
||||
-- Apply with:
|
||||
-- psql "$DATABASE_URL" -f apps/api/drizzle/website/0003_fix_id_types.sql
|
||||
|
||||
ALTER TABLE "website"."published_snapshots"
|
||||
ALTER COLUMN "published_by" TYPE text;
|
||||
|
||||
ALTER TABLE "website"."published_snapshots"
|
||||
ALTER COLUMN "space_id" TYPE text;
|
||||
|
||||
ALTER TABLE "website"."custom_domains"
|
||||
ALTER COLUMN "created_by" TYPE text;
|
||||
|
|
@ -70,7 +70,10 @@ routes.post('/sites/:id/publish', async (c) => {
|
|||
// embed the active space in JWT claims). Nullable — full membership
|
||||
// check lands in M6; M2 stores whatever the client declares.
|
||||
const spaceIdHeader = c.req.header('X-Mana-Space');
|
||||
const spaceId = spaceIdHeader && /^[0-9a-f-]{36}$/i.test(spaceIdHeader) ? spaceIdHeader : null;
|
||||
// Better-Auth nanoid format: 32 URL-safe base64 chars. Keep this lax
|
||||
// (no hard length) so it doesn't drift if nanoid config changes.
|
||||
const spaceId =
|
||||
spaceIdHeader && /^[A-Za-z0-9_-]{16,64}$/.test(spaceIdHeader) ? spaceIdHeader : null;
|
||||
const siteId = c.req.param('id');
|
||||
|
||||
if (!siteId) {
|
||||
|
|
@ -177,7 +180,10 @@ routes.post('/sites/:id/publish', async (c) => {
|
|||
}
|
||||
websitePublishTotal.inc({ result: 'error' });
|
||||
publishTimer();
|
||||
throw err;
|
||||
console.error('[website/publish] unhandled error', err);
|
||||
return errorResponse(c, err instanceof Error ? err.message : 'Publish failed', 500, {
|
||||
code: 'PUBLISH_FAILED',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ export const publishedSnapshots = websiteSchema.table(
|
|||
/** True for the row served to the public. Exactly one per slug. */
|
||||
isCurrent: boolean('is_current').notNull().default(false),
|
||||
publishedAt: timestamp('published_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
/** User who pressed the publish button. */
|
||||
publishedBy: uuid('published_by').notNull(),
|
||||
/** User who pressed the publish button. Better-Auth nanoid, not UUID. */
|
||||
publishedBy: text('published_by').notNull(),
|
||||
/**
|
||||
* Space the site belongs to. Nullable in M2 because mana-auth
|
||||
* doesn't yet thread the active space into JWT claims — the
|
||||
* client can pass it via `X-Mana-Space`, but we don't hard-require
|
||||
* it until server-side membership check lands (M6).
|
||||
*/
|
||||
spaceId: uuid('space_id'),
|
||||
spaceId: text('space_id'),
|
||||
},
|
||||
(table) => [
|
||||
index('published_snapshots_site_idx').on(table.siteId, table.publishedAt),
|
||||
|
|
@ -121,7 +121,8 @@ export const customDomains = websiteSchema.table(
|
|||
verifiedAt: timestamp('verified_at', { withTimezone: true }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
createdBy: uuid('created_by').notNull(),
|
||||
/** Better-Auth nanoid, not UUID. */
|
||||
createdBy: text('created_by').notNull(),
|
||||
},
|
||||
(table) => [index('custom_domains_site_idx').on(table.siteId, table.status)]
|
||||
// A partial unique index on (hostname) WHERE status='verified' lives
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue