// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // The web shell's stores of the mariadb and mongodb profiles (apps/web/src/server/dialect/) on the // real engines: the readiness probes answer, the migration level the migrate job wrote is what // readiness expects, the MongoDB store refuses a standalone server at boot (AT-D15), and the BullMQ // queue enqueues on Valkey under the app's own prefix. // // It needs ACCOUNT_TEST_MARIADB_URL, ACCOUNT_TEST_MONGODB_URL (a replica set) and ACCOUNT_TEST_REDIS_URL, // the databases test/dialect/account.test.ts migrated; without them each block is skipped by name. import { randomUUID } from "node:crypto" import { type AppEnv, expectedDialectMigrations, liveCaptureMigrations, loadAppEnv } from "@app/config" import { notes } from "@app/modules/notes" import { buildRegistry } from "@conusai-kit/core" import { entitiesOf } from "@conusai-kit/data" import { KIT_JOBS_ENTITIES } from "@conusai-kit/jobs-pgboss" import { Redis } from "ioredis" import { describe, expect, it } from "vitest" import { dialectStores, queueSlug } from "../../apps/web/src/server/dialect/stores" import { engineFor } from "../../apps/worker/src/dialect/runtime.js" import { freshDialectModules } from "./fixture.js" const redisUrl = process.env.ACCOUNT_TEST_REDIS_URL const platform = { NODE_ENV: "test", CONUSAI_API_URL: "https://api.example.test/api", CONUSAI_API_TOKEN: "token", CONUSAI_PROJECT_ID: "w06-stores", } const ENGINES = [ [ "mariadb", { MARIADB_URL: process.env.ACCOUNT_TEST_MARIADB_URL, DATABASE_URL: process.env.ACCOUNT_TEST_MARIADB_URL }, ], ["mongodb", { MONGODB_URL: process.env.ACCOUNT_TEST_MONGODB_URL }], ] as const for (const [profile, store] of ENGINES) { const registry = buildRegistry(freshDialectModules(profile)) const url = Object.values(store)[0] describe.skipIf(!url || !redisUrl)(`the web shell's ${profile} store`, () => { it("answers readiness at the migrate job's level and enqueues on its own BullMQ prefix", async () => { const raw = { ...platform, ...store, REDIS_URL: redisUrl } await engineFor(profile).migrate(raw, registry) const env: AppEnv = loadAppEnv("web", raw, profile) const stores = dialectStores( env, [...entitiesOf(registry, profile), ...KIT_JOBS_ENTITIES], liveCaptureMigrations(registry, profile), ) if (!stores) throw new Error("no dialect store") try { await stores.probes.boot() await stores.probes.store() const applied = await stores.probes.applied() for (const name of await expectedDialectMigrations(registry, profile)) expect(applied.has(name), name).toBe(true) // A request's enqueue reaches Valkey under this app's prefix. const id = await stores .queue() .enqueue( { level: "org", orgId: "00000000-0000-4000-8000-000000000001", actor: { userId: "u" } }, "files.recover", { probe: true }, ) expect(id).toBeTruthy() const redis = new Redis(redisUrl as string) try { const keys = await redis.keys(`kit-jobs-${queueSlug(env)}*`) expect(keys.length).toBeGreaterThan(0) } finally { await redis.quit() } // The live log: the migrate job prepared notes_note (MariaDB row triggers, MongoDB pre-images), // so a note written through the repository is in the log, ids only, in its own organization. { const log = stores.liveLog?.() if (!log) throw new Error(`the ${profile} store has no live log`) await log.start() const scope = { level: "project", orgId: randomUUID(), workspaceId: randomUUID(), projectId: randomUUID(), actor: { userId: randomUUID() }, } as const const since = profile === "mongodb" ? (await log.head(scope.orgId)).position : { txid: 0n, seq: 0n } const note = await stores.data .forScope(scope) .of(notes) .insert({ title: "live", body: "b", createdBy: scope.actor.userId }) let rows: Awaited>["final"] = [] for (let attempt = 0; attempt < 50 && rows.length === 0; attempt++) { const read = await log.read(scope.orgId, since, 10) rows = [...read.final, ...read.early] if (rows.length === 0) await new Promise((resolve) => setTimeout(resolve, 100)) } expect(rows.map((row) => [row.entity, row.id, row.op, row.scope.ws])).toEqual([ ["notes.note", note.id, "u", scope.workspaceId], ]) expect((await log.read(randomUUID(), since, 10)).final).toEqual([]) await log.close() } } finally { await stores.close() } }, 60_000) }) } describe.skipIf(!process.env.ACCOUNT_TEST_MONGODB_STANDALONE_URL)( "the web shell's mongodb store on a standalone server", () => { it("refuses to boot with the typed replica_set error (AT-D15)", async () => { const env = loadAppEnv( "web", { ...platform, MONGODB_URL: process.env.ACCOUNT_TEST_MONGODB_STANDALONE_URL, REDIS_URL: "redis://127.0.0.1:1" }, "mongodb", ) const registry = buildRegistry(freshDialectModules("mongodb")) const stores = dialectStores(env, entitiesOf(registry, "mongodb")) if (!stores) throw new Error("no dialect store") try { await expect(stores.probes.boot()).rejects.toMatchObject({ name: "MongoTopologyError", setting: "replica_set" }) } finally { await stores.close() } }, 60_000) }, )