ci: fix port 5432 collision and include read-only-prisma helper
CI / Architecture Guardrails (push) Successful in 1m37s
CI / Assistant Split Regression (push) Failing after 4m58s
CI / Typecheck (push) Failing after 5m18s
CI / Build (push) Has been skipped
CI / E2E Tests (push) Has been skipped
CI / Fresh-Linux Docker Deploy (push) Has been skipped
CI / Lint (push) Successful in 6m18s
CI / Unit Tests (push) Failing after 5m16s
CI / Release Images (push) Has been skipped
CI / Architecture Guardrails (push) Successful in 1m37s
CI / Assistant Split Regression (push) Failing after 4m58s
CI / Typecheck (push) Failing after 5m18s
CI / Build (push) Has been skipped
CI / E2E Tests (push) Has been skipped
CI / Fresh-Linux Docker Deploy (push) Has been skipped
CI / Lint (push) Successful in 6m18s
CI / Unit Tests (push) Failing after 5m16s
CI / Release Images (push) Has been skipped
- Remove host port mappings from postgres/redis services in ci.yml; QNAP runner already occupies 5432. Use service DNS names (postgres/redis) instead of localhost for DB/Redis URLs. - Track packages/api/src/lib/read-only-prisma.ts which was imported by assistant-tools.ts but never committed, breaking check:imports.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Read-only Prisma proxy.
|
||||
*
|
||||
* Wraps a PrismaClient and blocks write operations at the application level.
|
||||
* Used to enforce read-only access for AI read-tools (EGAI 4.1.1.2 / IAAI 3.6.22).
|
||||
*/
|
||||
|
||||
import type { prisma } from "@capakraken/db";
|
||||
|
||||
type PrismaClient = typeof prisma;
|
||||
|
||||
const WRITE_METHODS = new Set([
|
||||
"create",
|
||||
"createMany",
|
||||
"createManyAndReturn",
|
||||
"update",
|
||||
"updateMany",
|
||||
"upsert",
|
||||
"delete",
|
||||
"deleteMany",
|
||||
]);
|
||||
|
||||
function readOnlyModelProxy(model: Record<string, unknown>, modelName: string): unknown {
|
||||
return new Proxy(model, {
|
||||
get(target, prop) {
|
||||
if (typeof prop === "string" && WRITE_METHODS.has(prop)) {
|
||||
return () => {
|
||||
throw new Error(
|
||||
`Write operation "${prop}" on "${modelName}" not permitted on read-only context`,
|
||||
);
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function createReadOnlyProxy(client: PrismaClient): PrismaClient {
|
||||
return new Proxy(client, {
|
||||
get(target, prop) {
|
||||
const value = Reflect.get(target, prop);
|
||||
// If accessing a model delegate (object with findMany, etc.), wrap it
|
||||
if (value && typeof value === "object" && "findMany" in (value as Record<string, unknown>)) {
|
||||
return readOnlyModelProxy(value as Record<string, unknown>, String(prop));
|
||||
}
|
||||
// Block $executeRaw and $executeRawUnsafe at the client level
|
||||
if (prop === "$executeRaw" || prop === "$executeRawUnsafe") {
|
||||
return () => {
|
||||
throw new Error(
|
||||
`Raw write operation "${String(prop)}" not permitted on read-only context`,
|
||||
);
|
||||
};
|
||||
}
|
||||
return value;
|
||||
},
|
||||
}) as PrismaClient;
|
||||
}
|
||||
Reference in New Issue
Block a user