fix: restore mobile report scrolling and published product edits
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled

Report pages now scroll inside the chat shell lock, and admin product save forks a draft or retires a published plan instead of rejecting with a generic constraint error.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-18 17:28:22 +08:00
co-authored by Cursor
parent 3c9b0bb32b
commit f4a2ba86ae
13 changed files with 398 additions and 8 deletions
+9 -1
View File
@@ -37,7 +37,11 @@ const publishSchema = z.object({
action: z.literal("publish"),
id: z.string().uuid(),
}).strict();
const mutationSchema = z.discriminatedUnion("action", [saveSchema, publishSchema]);
const deleteSchema = z.object({
action: z.literal("delete"),
id: z.string().uuid(),
}).strict();
const mutationSchema = z.discriminatedUnion("action", [saveSchema, publishSchema, deleteSchema]);
type ProductRow = {
id: string; code: string; version: number; name: string; description: string;
@@ -92,6 +96,10 @@ export async function POST(request: Request) {
const rows = await queryAdminRows<{ id: string }>("select public.admin_publish_product($1,$2,$3,$4) id", [session.user.id, body.data.id, "admin_console_publish_product", rid]);
return NextResponse.json({ data: { id: rows[0]!.id, requestId: rid } });
}
if (body.data.action === "delete") {
const rows = await queryAdminRows<{ id: string }>("select public.admin_delete_product($1,$2,$3,$4) id", [session.user.id, body.data.id, "admin_console_delete_product", rid]);
return NextResponse.json({ data: { id: rows[0]!.id, requestId: rid } });
}
const value = body.data;
const rows = await queryAdminRows<{ id: string }>(`
select public.admin_save_product_draft($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14::jsonb,$15,$16) id
+4 -2
View File
@@ -1756,7 +1756,7 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
.payment-qr-badge svg { display: block; width: 100%; height: 100%; }
/* Global report centre — quiet archive, independent from chat sessions. */
.report-center-shell { width: 100%; min-height: 100dvh; overflow-x: hidden; padding: 0 clamp(20px, 5vw, 72px) 72px; background: var(--color-canvas-soft); color: var(--color-ink); }
.report-center-shell { width: 100%; height: 100%; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 0 clamp(20px, 5vw, 72px) 72px; background: var(--color-canvas-soft); color: var(--color-ink); }
.report-center-topbar { max-width: 1080px; min-height: 64px; display: flex; align-items: center; justify-content: space-between; gap: 20px; margin: 0 auto; border-bottom: 1px solid var(--color-border); color: var(--color-ink-tertiary); font-size: 12px; }
.report-center-back { min-height: 44px; display: inline-flex; align-items: center; gap: 7px; color: var(--color-ink-secondary); font-size: 14px; font-weight: 500; text-decoration: none; }
.report-center-back:hover { color: var(--color-action); }
@@ -1808,11 +1808,13 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
--report-paper: #f8f5ee;
--report-rule: #c9c2b7;
width: 100%;
height: 100dvh;
height: 100%;
min-height: 0;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
touch-action: pan-y;
scrollbar-gutter: stable;
background: var(--report-paper);
}