Rebuild atomcms-next foundation on Prisma (align to habbo-next reference)
Replace the superseded Drizzle monorepo scaffold with a single-app Prisma 7 data layer, mirroring the proven habbo-next approach to the shared Arcturus emulator DB (introspect/conform only, idempotent SQL migrations via a custom runner; never migrate-diff). - prisma/schema.prisma: User, UsersCurrency (composite PK), Ban, WebsiteSetting mapped to AtomCMS's default.sql columns; client generated to src/generated/prisma - src/lib/prisma.ts: PrismaMariaDb adapter singleton; src/env.ts zod env - src/lib/services: siteSettings (cached setting() equivalent) + CurrencyType enum - prisma/migrations + scripts/apply-migrations.ts: idempotent CMS-table runner Verified: prisma generate OK, tsc --noEmit exit 0, vitest 6/6 pass.
This commit is contained in:
1 parent
7bd4f2b28e
commit
b5bc7f6daf
44 files changed
+1279
-511
No files matched your search
@@ -0,0 +1,46 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { findMany } = vi.hoisted(() => ({ findMany: vi.fn() }));
|
||||
vi.mock("@/lib/prisma", () => ({
|
||||
prisma: { websiteSetting: { findMany } },
|
||||
}));
|
||||
|
||||
import { siteSettings } from "./site-settings";
|
||||
|
||||
beforeEach(() => {
|
||||
findMany.mockReset();
|
||||
siteSettings.reload();
|
||||
});
|
||||
|
||||
describe("siteSettings", () => {
|
||||
it("returns a value by key", async () => {
|
||||
findMany.mockResolvedValue([{ key: "hotel_name", value: "AtomHotel" }]);
|
||||
expect(await siteSettings.get("hotel_name")).toBe("AtomHotel");
|
||||
});
|
||||
|
||||
it("returns the fallback when key is missing", async () => {
|
||||
findMany.mockResolvedValue([]);
|
||||
expect(await siteSettings.get("missing", "fallback")).toBe("fallback");
|
||||
expect(await siteSettings.get("missing")).toBeNull();
|
||||
});
|
||||
|
||||
it("coerces '1'/'0' string booleans", async () => {
|
||||
findMany.mockResolvedValue([
|
||||
{ key: "maintenance_enabled", value: "1" },
|
||||
{ key: "radio_enabled", value: "0" },
|
||||
]);
|
||||
expect(await siteSettings.getBool("maintenance_enabled")).toBe(true);
|
||||
expect(await siteSettings.getBool("radio_enabled")).toBe(false);
|
||||
expect(await siteSettings.getBool("missing", true)).toBe(true);
|
||||
});
|
||||
|
||||
it("fetches once and caches until reload", async () => {
|
||||
findMany.mockResolvedValue([{ key: "hotel_name", value: "AtomHotel" }]);
|
||||
await siteSettings.get("hotel_name");
|
||||
await siteSettings.getBool("hotel_name");
|
||||
expect(findMany).toHaveBeenCalledTimes(1);
|
||||
siteSettings.reload();
|
||||
await siteSettings.get("hotel_name");
|
||||
expect(findMany).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user