记录CEO财务兜底生产收口(07-28-ceo-finance-fallback)

这个提交包含在:
2026-07-28 15:00:35 +08:00
父节点 a74cba1112
当前提交 0c779ab4f9
共修改 10 个文件,包含 76 行新增和 22 行删除
@@ -23,6 +23,58 @@ QA script patterns over new abstractions.
- `cd server && ./scripts/regression-workflow-actions.sh`
- `cd server && ./scripts/regression-all.sh`
## Scenario: Prisma Client Defaults In Raw SQL
### 1. Scope / Trigger
- Trigger: a script or route uses `$queryRaw`, `pg` or handwritten `INSERT` SQL against a Prisma-managed table whose schema declares `@default(uuid())` or another client-side default.
### 2. Signatures
- Prisma signature: `id String @id @default(uuid()) @db.Uuid`.
- Database signature may still be `id UUID NOT NULL` without a database `DEFAULT`.
- Raw insert must include `id` and bind an explicit UUID, for example `$1::uuid`.
### 3. Contracts
- Prisma schema defaults are not assumed to exist in PostgreSQL; inspect the applied migration or live column default before omitting a raw-SQL field.
- Raw audit inserts generate a fresh UUID in application code and keep the audit insert in the same transaction as the protected write.
- Dry-run may exercise audit inserts, but it must roll the transaction back and report zero committed audit rows.
### 4. Validation & Error Matrix
- Raw insert omits a required client-default field with no DB default -> PostgreSQL not-null failure; transaction rolls back.
- Explicit UUID has invalid syntax -> PostgreSQL cast failure; transaction rolls back.
- Audit insert fails after the business update -> the complete transaction rolls back; no partial rule update is allowed.
### 5. Good/Base/Bad Cases
- Good: explicit UUID, request ID, actor, target and JSON audit payload are bound and tested position by position.
- Base: Prisma Client `create()` may rely on the Prisma default because the client supplies it.
- Bad: infer from `@default(uuid())` that handwritten PostgreSQL may omit `id`.
### 6. Tests Required
- Assert the raw SQL column list contains the required ID and the bound value is a valid UUID.
- Assert every parameter position maps to its intended DB type.
- Assert dry-run begins a serializable transaction and executes `ROLLBACK`; audit failure paths must remain fail-closed.
### 7. Wrong vs Correct
#### Wrong
```sql
INSERT INTO audit_logs (request_id, actor_id, extra)
VALUES ($1, $2::uuid, $3::jsonb);
```
#### Correct
```sql
INSERT INTO audit_logs (id, request_id, actor_id, extra)
VALUES ($1::uuid, $2, $3::uuid, $4::jsonb);
```
## Scenario: Local Regression Migration Drift
### 1. Scope / Trigger