import type { Manifest } from "./manifest.js"; import { type OrphanedForeignKey } from "./orphaned-foreign-keys.js"; /** * 演练里的 Auth 校验(2.10.0 起,附加模式)。 * * 在演练照旧做完、通过与否已经定下之后,在同一个沙箱里:把 auth.dump 的两张表建出来、灌数据, * 补上之前因为沙箱没有 auth 表而跳过的外键,建可以自动恢复的触发器,再以 GoTrue 的身份模拟一次注册。 * 结果只写进报告的 auth 一节,**不改变演练结论**,自己出错也只记在这一节里——上线初期先观察, * 是否计入结论由以后决定(PRD 增补 §0.1 第 5 条)。 */ export interface AuthDrillReport { /** verified:全部对上;problems:有对不上的地方(见 summary);not_checked:这次没能检查 */ status: "verified" | "problems" | "not_checked"; /** 一句给人看的结论 */ summary: string; users?: number; identities?: number; /** 指向 auth 表的外键:建成的条数、源库本来就有孤儿行(建成 NOT VALID)的、建不出来的 */ foreignKeys?: { created: number; orphaned: OrphanedForeignKey[]; failed: string[]; }; triggers?: { created: string[]; failed: string[]; }; /** 不会自动恢复、要人手处理的对象 */ manual?: string[]; /** 没验证到的部分,例如触发器还响应模拟注册之外的事件 */ notes?: string[]; /** 模拟注册:ran=false 时说明为什么没跑 */ signup?: { ran: boolean; ok?: boolean; detail?: string; }; } export interface AuthDumpForDrill { /** 下载到本地的 auth.dump;下载失败时为空,error 说明原因 */ path?: string; error?: string; } /** SQLSTATE → 固定说法 + 代码本身;不是合法的 SQLSTATE 就说"意外错误"。恢复端写 Auth 数据出错时也用它 */ export declare function describeSqlstate(code: unknown): string; export declare function runAuthDrill(sandboxConnString: string, manifest: Manifest, mainDumpPath: string, authDump: AuthDumpForDrill, signal?: AbortSignal): Promise; /** * 终止 Auth 这一节在沙箱里开的会话(按 application_name 认),别人的会话不动。 * 整个过程(连接、查询、断开)有硬时限:到点直接销毁 socket,沙箱没回应也挂不住进程 */ export declare function stopAuthSessions(sandboxConnString: string, deadlineMs?: number): Promise; /** Auth 这一节最多花多久(下载等待 + 恢复两张表 + 外键 + 触发器 + 模拟注册);到点记 not_checked */ export declare const AUTH_DRILL_LIMITS: { totalMs: number; }; /** * 演练里调用:任何异常、超时都收进报告,绝不让演练因为 Auth 这一节抛错或拖住。 * authDump 是个 Promise:下载和正式演练同时进行,这里才等它。到点就不等了,沙箱随后照常销毁, * 还在跑的 pg_restore 跟着断开 */ export declare function authDrillSection(sandboxConnString: string, manifest: Manifest, mainDumpPath: string, authDump: Promise | undefined, stopDownload?: () => void, /** * 托管 worker:begin 在开始前告诉它进入 Auth 阶段(被拒绝就不做这一节);stop 是它叫停这一节的信号。 * 两者都只影响这一节,演练结论不变 */ runner?: { begin?: () => Promise; stop?: AbortSignal; }): Promise;