Implementa o MVP do Adaptador de Planilhas no Elo Pro.
O módulo usa a identidade Supabase, isola cada workspace e registra storage, TTL, runner e biblioteca XLSX como decisões ainda abertas. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
6e23f1533b
144 files changed
+19060
No files matched your search
@@ -0,0 +1,52 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createModel } from "@/server/spreadsheet-adapter/service";
|
||||
import { ctxOf, createReadyDb, depsOf, IDS } from "../helpers/world";
|
||||
|
||||
describe("RLS e permissões", () => {
|
||||
it("impede leitura e escrita entre workspaces", async () => {
|
||||
const db = await createReadyDb();
|
||||
const deps = depsOf(db);
|
||||
const ana = ctxOf("ana", "alpha", "owner", true);
|
||||
const diego = ctxOf("diego", "beta", "admin", false);
|
||||
await createModel(deps, ana, { name: "Somente Alpha", filename: "a.csv", bytes: Buffer.from("A\n1\n") });
|
||||
const asDiego = await db.withUser(IDS.diego, (query) => query.query(`select name from public.spreadsheet_models`));
|
||||
expect(asDiego).toHaveLength(0);
|
||||
const asAna = await db.withUser(IDS.ana, (query) => query.query(`select name from public.spreadsheet_models where workspace_id = $1`, [IDS.beta]));
|
||||
expect(asAna).toHaveLength(0);
|
||||
await expect(
|
||||
db.withUser(IDS.ana, (query) =>
|
||||
query.query(
|
||||
`insert into public.spreadsheet_models
|
||||
(workspace_id, name, original_filename, format, storage_key, content_sha256, header_row, columns_schema, created_by)
|
||||
values ($1,'Invasao','a.csv','csv','workspaces/x/models/y/original','abc',1,'[]'::jsonb,$2)`,
|
||||
[IDS.beta, IDS.ana],
|
||||
),
|
||||
),
|
||||
).rejects.toThrow(/row-level security/i);
|
||||
await expect(createModel(deps, { ...diego, moduleEnabled: true }, { name: "Beta", filename: "a.csv", bytes: Buffer.from("A\n1\n") })).rejects.toMatchObject({
|
||||
code: "FORBIDDEN",
|
||||
});
|
||||
const eva = ctxOf("eva", "beta", "agent", true, true);
|
||||
await expect(createModel(deps, eva, { name: "Super", filename: "a.csv", bytes: Buffer.from("A\n1\n") })).rejects.toThrow();
|
||||
await db.close();
|
||||
});
|
||||
|
||||
it("agent não altera configuração e owner altera", async () => {
|
||||
const db = await createReadyDb();
|
||||
const ana = ctxOf("ana", "alpha", "owner", true);
|
||||
const bruno = ctxOf("bruno", "alpha", "agent", true);
|
||||
await expect(
|
||||
db.withUser(bruno.userId, (query) =>
|
||||
query.query(`insert into public.spreadsheet_adapter_settings (workspace_id, allow_non_admin_model_upload) values ($1, true)`, [IDS.alpha]),
|
||||
),
|
||||
).rejects.toThrow(/row-level security/i);
|
||||
await db.withUser(ana.userId, (query) =>
|
||||
query.query(`insert into public.spreadsheet_adapter_settings (workspace_id, allow_non_admin_model_upload) values ($1, true)`, [IDS.alpha]),
|
||||
);
|
||||
const seen = await db.withUser(bruno.userId, (query) =>
|
||||
query.query<{ allow_non_admin_model_upload: boolean }>(`select allow_non_admin_model_upload from public.spreadsheet_adapter_settings`),
|
||||
);
|
||||
expect(seen[0].allow_non_admin_model_upload).toBe(true);
|
||||
await db.close();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user