feat: complete remaining Go backend modules

This commit is contained in:
zn-admin committed 2026-08-14 00:02:43 +08:00
1 parent cea2751dc5
commit aef5a97165
145 files changed
+18376 -199

No files matched your search

+12
View File
@@ -0,0 +1,12 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("Go legacy auth compatibility HTTP v1 contract", () => {
it("pins login, callback, and disabled captcha endpoints", async () => {
const fixture = JSON.parse(await readFile(new URL("../contracts/admin/http-auth-compat-v1.json", import.meta.url), "utf8"));
const source = await readFile(new URL("../backend/internal/httpapi/auth_compat.go", import.meta.url), "utf8");
expect(fixture.routes.map((route: { path: string }) => route.path)).toEqual(["/api/auth/login", "/api/auth/callback", "/api/auth/captcha"]);
expect(source).toContain("callback_failed");
expect(source).toContain("平台账号登录不使用外部验证码。");
});
});
+17
View File
@@ -0,0 +1,17 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("Go administration HTTP v1 contract", () => {
it("pins methods, authorization, and security projections", async () => {
const fixture = JSON.parse(await readFile(new URL("../contracts/admin/http-v1.json", import.meta.url), "utf8"));
const source = await readFile(new URL("../backend/internal/httpapi/admin.go", import.meta.url), "utf8");
expect(fixture.routes).toHaveLength(4);
expect(fixture.routes.filter((route: { path: string }) => route.path !== "/api/admin/accounts/groups").every((route: { requirement: string }) => route.requirement === "admin")).toBe(true);
expect(fixture.routes.find((route: { path: string }) => route.path === "/api/admin/accounts/groups")?.requirement).toBe("public-compatibility");
expect(source).toContain("PlatformAdmin");
expect(source).toContain("http.StatusGone");
const projection = source.slice(source.indexOf("func adminAccountProjection("));
for (const field of fixture.secretFields) expect(projection).not.toContain(`\"${field}\"`);
for (const field of fixture.accountProjection) expect(source).toContain(`\"${field}\"`);
});
});
+21
View File
@@ -0,0 +1,21 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("assets HTTP v1 compatibility contract", () => {
it("freezes route, limit, safe-error, and binary-cache semantics", async () => {
const contract = JSON.parse(await readFile(new URL("../contracts/assets/http-v1.json", import.meta.url), "utf8"));
expect(contract.version).toBe(1);
expect(contract.limits).toEqual({ jsonBytes: 1_048_576, uploadBytes: 20_971_520, remoteBytes: 20_971_520 });
expect(contract.routes.map((route: { path: string }) => route.path)).toEqual([
"/api/assets", "/api/assets/upload", "/api/assets/{id}", "/api/assets/{id}/download",
"/api/v1/assets", "/api/v1/assets/{id}", "/api/v1/assets/{id}/download",
"/uploads/{path...}", "/generated-results/{path...}"
]);
expect(contract.errors.internal.body).toEqual({ error: "Internal server error." });
expect(contract.methods).toEqual({ headExecutesGet: true, optionsStatus: 204, unsupportedStatus: 405, unsupportedBody: "empty" });
expect(contract.binary).toEqual({
downloadCacheControl: "private, no-store",
servedCacheControl: "public, max-age=31536000, immutable"
});
});
});
@@ -0,0 +1,17 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("Go password change v1 contract", () => {
it("pins the transactional password and replacement-cookie implementation", async () => {
const fixture = JSON.parse(await readFile(new URL("../contracts/auth/password-change-v1.json", import.meta.url), "utf8"));
const http = await readFile(new URL("../backend/internal/httpapi/auth_password_change.go", import.meta.url), "utf8");
const identity = await readFile(new URL("../backend/internal/identity/password_change.go", import.meta.url), "utf8");
const postgres = await readFile(new URL("../backend/internal/postgres/password_change.go", import.meta.url), "utf8");
expect(fixture).toMatchObject({ version: 1, path: "/api/auth/password/change", minimumPasswordLength: 8, incrementsSessionVersion: true });
expect(http).toContain("identity.SetSessionCookies");
expect(http).toContain("PlatformApp");
expect(identity).toContain("len(command.NewPassword) < 8");
expect(postgres).toContain("FOR UPDATE");
expect(postgres).toContain("session_version = session_version + 1");
});
});
+17
View File
@@ -0,0 +1,17 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("billing HTTP compatibility fixture", () => {
it("freezes routes, refreshed-session scope, money, and admin mutation rules", async () => {
const fixture = JSON.parse(await readFile("contracts/billing/http-v1.json", "utf8"));
expect(fixture).toMatchObject({
version: 1, currency: "CNY", moneyUnit: "fen",
statuses: { insufficientBalance: 402, idempotencyConflict: 409, unboundOrganization: 422, infrastructure: 500 },
pricePatch: { minimum: 1, maximum: 1000, precision: 4, tierPairRequired: true }
});
expect(fixture.routes).toEqual(expect.arrayContaining([
expect.objectContaining({ method: "GET", path: "/api/billing", organizationSource: "refreshed_session" }),
expect.objectContaining({ method: "PATCH", path: "/api/admin/billing/prices/{id}", requirement: "super_admin" })
]));
});
});
+3
View File
@@ -0,0 +1,3 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("Go jobs HTTP v1 contract", () => { it("freezes paths, methods, scope and statuses", async () => { const c=JSON.parse(await readFile(new URL("../contracts/jobs/http-v1.json",import.meta.url),"utf8")); expect(c.public.scope).toEqual(["ownerId","externalClientId"]); expect(c.public.statuses).toEqual({created:202,reused:200,conflict:409,notFound:404}); expect(c.platform.image.methods).toEqual(["GET","POST"]); expect(c.worker.auth).toBe("publicapi.AssertInternalWorker"); }); });
+26
View File
@@ -0,0 +1,26 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
const fixtureUrl = new URL("../contracts/logs/runtime-v1.json", import.meta.url);
describe("Go runtime logs compatibility fixture", () => {
it("freezes storage, bounds, ordering, and redaction behavior", async () => {
const fixture = JSON.parse(await readFile(fixtureUrl, "utf8"));
expect(fixture).toEqual({
version: 1,
fileName: "server-events.jsonl",
rotatedSuffix: ".1",
defaultLimit: 100,
minimumLimit: 1,
maximumLimit: 500,
maximumTextLength: 20000,
maximumDepth: 5,
maximumArrayItems: 50,
maximumObjectKeys: 80,
corruptLines: "skip",
order: "newest-first",
redactedValue: "[redacted]",
redactedJwt: "[jwt-redacted]"
});
});
});
+3
View File
@@ -0,0 +1,3 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("Go provider adapter contract",()=>{it("freezes bounded adapters and safe errors",async()=>{const c=JSON.parse(await readFile(new URL("../contracts/providers/http-v1.json",import.meta.url),"utf8"));expect(Object.keys(c.providers)).toEqual(["volcengine-visual","evolink","bailian","seedance","mock"]);expect(c.errors).toEqual({generic:true,secretSafe:true});expect(c.liveCallsInTests).toBe(false);});});
+21
View File
@@ -0,0 +1,21 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
const fixtureUrl = new URL("../contracts/settings/runtime-v1.json", import.meta.url);
describe("Go runtime settings compatibility fixture", () => {
it("freezes the editable whitelist and secret projection rules", async () => {
const fixture = JSON.parse(await readFile(fixtureUrl, "utf8"));
expect(fixture).toMatchObject({
version: 1,
fileName: ".env.local",
emptySecretInput: "preserve",
emptyNonSecretInput: "write-empty",
publicSecretValue: "blank",
runtimeApplication: "restart-required"
});
expect(fixture.allowedKeys).toContain("IMAGE_GENERATE_ENGINE");
expect(fixture.secretKeys).toContain("ALI_OSS_ACCESS_KEY_SECRET");
expect(fixture.allowedKeys).not.toContain("DATABASE_URL");
});
});
+15
View File
@@ -0,0 +1,15 @@
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";
describe("usage HTTP compatibility fixture", () => {
it("freezes personal/admin scope and filters", async () => {
const fixture = JSON.parse(await readFile("contracts/usage/http-v1.json", "utf8"));
expect(fixture).toMatchObject({
version: 1,
presets: ["today", "7d", "30d", "month"],
capabilities: ["image.generate", "video.generate"],
infrastructureStatus: 500
});
expect(fixture.routes).toContainEqual(expect.objectContaining({ path: "/api/admin/usage", requirement: "admin", organizationAdminScope: "refreshed_session" }));
});
});
+26 -7
View File
@@ -8,6 +8,8 @@ const schemaPaths = [
"../supabase/schema.sql"
];
const lifecycleMigrationPath = "../database/migrations/0002_generation_lifecycle_fencing.sql";
function readSchema(relativePath: string): string {
return readFileSync(fileURLToPath(new URL(relativePath, import.meta.url)), "utf8").replace(/\r\n/g, "\n");
}
@@ -47,12 +49,29 @@ describe.each(schemaPaths)("wallet SQL contract: %s", (schemaPath) => {
});
});
it("keeps the migration and Supabase compatibility snapshot synchronized", () => {
const migration = readSchema(schemaPaths[0]);
const snapshot = readSchema(schemaPaths[1]).replace(
/^-- Compatibility snapshot for existing Supabase deployments\.\r?\n-- New PostgreSQL\/RDS deployments must use `npm run db:migrate`; do not use this\r?\n-- file as an unversioned migration source\.\r?\n\r?\n/,
""
);
it("keeps the Supabase compatibility snapshot at the latest migrated schema", () => {
const baseline = readSchema(schemaPaths[0]);
const lifecycle = readSchema(lifecycleMigrationPath);
const snapshot = readSchema(schemaPaths[1]);
expect(snapshot).toBe(migration);
for (const fragment of [
"provider_dispatch_started_at timestamptz",
"dispatch_ready_at timestamptz",
"finalized_at timestamptz",
"generation_jobs_finalize_claim_idx",
"where dispatch_ready_at is not null",
"and finalized_at is null"
]) {
expect(lifecycle.toLowerCase()).toContain(fragment);
expect(snapshot.toLowerCase()).toContain(fragment);
}
for (const fragment of [
"create table if not exists assets",
"create table if not exists billing_ledger",
"billing_post_wallet_entry"
]) {
expect(baseline.toLowerCase()).toContain(fragment);
expect(snapshot.toLowerCase()).toContain(fragment);
}
expect(snapshot).toContain("Compatibility snapshot for existing Supabase deployments");
});