import { afterAll, beforeEach, describe, expect, it } from "vitest"; import { bootstrapAlphaSilo } from "../../src/deployment/bootstrap-silo.js"; import { requireSiloOrganization } from "../../src/deployment/silo.js"; import { prisma, testSecretEnvelope } from "./helpers.js"; const input = { organization: { id: "org_alpha", slug: "alpha", name: "Alpha School" }, owner: { openId: "ou_owner", displayName: "Owner" }, feishu: { appId: "cli_alpha", appSecret: "feishu-secret", botOpenId: "ou_bot" }, provider: { providerId: "openrouter", baseUrl: "https://openrouter.ai/api", authToken: "provider-secret", }, teams: [{ slug: "teachers", name: "Teachers" }], } as const; describe("Alpha Silo bootstrap", () => { beforeEach(async () => { await prisma.$executeRawUnsafe(`TRUNCATE TABLE "Organization" RESTART IDENTITY CASCADE`); await prisma.organization.create({ data: { id: "org_default", slug: "legacy-default", name: "Legacy Default Organization", projectSettings: { create: { membersCanCreateProjects: true } }, folders: { create: { id: "folder_inbox_2b99350e0db97ad0cbcb55c20ee8bafa", name: "Inbox", sortKey: "000000", }, }, }, }); }); afterAll(async () => { await prisma.$disconnect(); }); it("creates one scoped Organization and is idempotent", async () => { const probes = { feishu: async () => {}, provider: async () => {} }; const first = await bootstrapAlphaSilo(prisma, testSecretEnvelope, input, probes); const second = await bootstrapAlphaSilo(prisma, testSecretEnvelope, input, probes); expect(first).toMatchObject({ organizationId: "org_alpha", initialized: true, providerConfigured: true }); expect(second).toMatchObject({ organizationId: "org_alpha", initialized: false, providerConfigured: true }); await expect(requireSiloOrganization(prisma, "org_alpha")).resolves.toMatchObject({ slug: "alpha" }); expect(await prisma.organization.count()).toBe(1); expect(await prisma.organizationMembership.count({ where: { role: "OWNER", revokedAt: null } })).toBe(1); expect(await prisma.feishuUserIdentity.count()).toBe(1); expect(await prisma.team.count({ where: { slug: "teachers", archivedAt: null } })).toBe(1); expect(await prisma.teamMembership.count({ where: { revokedAt: null } })).toBe(1); expect(await prisma.organizationProviderConnection.count({ where: { status: "ACTIVE" } })).toBe(1); await expect(prisma.organizationAgentRole.findMany({ where: { organizationId: "org_alpha", disabledAt: null }, orderBy: { sortOrder: "asc" }, select: { roleId: true, label: true }, })).resolves.toEqual([ { roleId: "draft", label: "草稿" }, { roleId: "review", label: "审校" }, ]); const persisted = JSON.stringify({ feishu: await prisma.feishuApplicationCredentialVersion.findMany(), provider: await prisma.providerCredentialVersion.findMany(), }); expect(persisted).not.toContain("feishu-secret"); expect(persisted).not.toContain("provider-secret"); }); it("rejects a configured Organization that does not match the database", async () => { await bootstrapAlphaSilo(prisma, testSecretEnvelope, input, { feishu: async () => {}, provider: async () => {}, }); await expect(requireSiloOrganization(prisma, "org_other")).rejects.toThrow("Silo Organization mismatch"); }); it("does not delete a legacy migration Organization that contains tenant data", async () => { await prisma.project.create({ data: { organizationId: "org_default", folderId: "folder_inbox_2b99350e0db97ad0cbcb55c20ee8bafa", name: "Legacy Project", workspaceDir: "legacy-project", }, }); await expect(bootstrapAlphaSilo(prisma, testSecretEnvelope, input, { feishu: async () => {}, provider: async () => {}, })).rejects.toThrow("bootstrap database is not the configured single-Organization Silo"); await expect(prisma.organization.findUnique({ where: { id: "org_default" } })).resolves.not.toBeNull(); }); });