import type { IsolationTenant } from "@conusai-kit/testing" import { describe, expect, it, vi } from "vitest" import { simulatedBusinessAdmission } from "../../../test/helpers/business-admission.js" import type { LedgerService } from "../core/ports.js" import { ledgerApp } from "./app.js" import { ledgerIsolationFixtures } from "./isolation.js" const fixtureInput = (name: string, tenant: IsolationTenant) => { const fixture = ledgerIsolationFixtures[name] if (!fixture) throw new Error("missing isolation fixture") return fixture.input(tenant) } const resultAccount = { accountId: "acc_00000000-0000-4000-8000-000000000001", code: "SYNTHETIC", name: "Operational", currency: "EUR", type: "asset", normalBalance: "debit", allowNegative: false, status: "active", revision: "1", } as const const resultTransaction = { transactionId: "txn_00000000-0000-4000-8000-000000000001", revision: "1", effectiveAt: "2026-11-03T00:00:00Z", description: "Synthetic", reference: null, reverses: null, status: "pending", entries: [], } as const const fake = () => ({ accounts: vi.fn(async () => ({ rows: [] })), verify: vi.fn(async () => ({ checkedAccounts: 0, drift: [] })), createAccount: vi.fn(async () => resultAccount), updateAccount: vi.fn(async () => resultAccount), record: vi.fn(async () => ({ ...resultTransaction, entries: [] })), transition: vi.fn(async () => ({ ...resultTransaction, entries: [] })), }) as unknown as LedgerService describe("Ledger actual caller with synthetic admission/port", () => { it("refuses all 13 procedures with wrong-tenant slugs before service access", async () => { const s = fake() const app = ledgerApp(s) const a = await app.tenant("alpha") const b = await app.tenant("beta") const tenant = { orgSlug: b.orgSlug } as IsolationTenant expect(Object.keys(ledgerIsolationFixtures)).toHaveLength(13) for (const [name, fixture] of Object.entries(ledgerIsolationFixtures)) { await expect(a.call.callByName(name, fixture.input(tenant))).rejects.toHaveProperty("problem.status", 404) } expect(s.accounts).not.toHaveBeenCalled() }) it("allows viewer reads, refuses viewer writes and separates member writer from account/reversal admin", async () => { const app = ledgerApp(fake()) const t = await app.tenant("alpha") const viewer = await app.member(t, "viewer@alpha.test", "viewer") const member = await app.member(t, "writer@alpha.test", "member") expect(await viewer.callByName("ledger.accounts.list", { org: t.orgSlug })).toEqual({ rows: [] }) const tenant = { orgSlug: t.orgSlug } as IsolationTenant for (const name of [ "ledger.accounts.create", "ledger.accounts.update", "ledger.transactions.record", "ledger.transactions.post", "ledger.transactions.void", "ledger.transactions.reverse", ]) { await expect(viewer.callByName(name, fixtureInput(name, tenant))).rejects.toHaveProperty("problem.status", 404) } for (const name of ["ledger.accounts.create", "ledger.accounts.update", "ledger.transactions.reverse"]) await expect(member.callByName(name, fixtureInput(name, tenant))).rejects.toHaveProperty("problem.status", 404) }) it("refuses unregistered default-off module and missing readiness/binding", async () => { for (const [enabled, ready] of [ [false, true], [true, false], ]) { const s = fake() const app = ledgerApp(s, enabled, ready) const t = await app.tenant("alpha") await expect(t.call.callByName("ledger.accounts.list", { org: t.orgSlug })).rejects.toThrow() expect(s.accounts).not.toHaveBeenCalled() } }) it("refuses missing approved service scopes and Convex before any adapter call", async () => { for (const readiness of [ { ...simulatedBusinessAdmission, observe: async () => ({ ...(await simulatedBusinessAdmission.observe({} as never, {} as never)), authorized: false, }), }, { ...simulatedBusinessAdmission, profile: "convex" as const }, ]) { const s = fake() const app = ledgerApp(s, true, readiness) const t = await app.tenant("alpha") await expect(t.call.callByName("ledger.accounts.list", { org: t.orgSlug })).rejects.toHaveProperty( "problem.code", readiness.profile === "convex" ? "service_profile_unsupported" : "service_permission_missing", ) expect(s.accounts).not.toHaveBeenCalled() } }) it("allows member financial writes and owner account/reversal administration through the real caller", async () => { const service = fake() const app = ledgerApp(service) const t = await app.tenant("alpha") const member = await app.member(t, "writer@alpha.test", "member") const tenant = { orgSlug: t.orgSlug } as IsolationTenant for (const name of ["ledger.transactions.record", "ledger.transactions.post", "ledger.transactions.void"]) { expect(await member.callByName(name, fixtureInput(name, tenant))).toHaveProperty( "transactionId", resultTransaction.transactionId, ) } for (const name of ["ledger.accounts.create", "ledger.accounts.update"]) { expect(await t.call.callByName(name, fixtureInput(name, tenant))).toHaveProperty( "accountId", resultAccount.accountId, ) } expect( await t.call.callByName("ledger.transactions.reverse", fixtureInput("ledger.transactions.reverse", tenant)), ).toHaveProperty("transactionId", resultTransaction.transactionId) }) it("requires explicit financial confirmation and refuses extra body-selected authority", async () => { const service = fake() const app = ledgerApp(service) const t = await app.tenant("alpha") const input = fixtureInput("ledger.transactions.record", { orgSlug: t.orgSlug } as IsolationTenant) as Record< string, unknown > for (const invalid of [ { ...input, confirmed: false }, { ...input, appTenantId: "forged", platformOrg: "beta" }, ]) { await expect(t.call.callByName("ledger.transactions.record", invalid)).rejects.toHaveProperty( "problem.status", 422, ) } expect(service.record).not.toHaveBeenCalled() }) })