mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-11-01 18:19:43 +00:00
feat(backend): add standalone data plane
Replace the Supabase application data plane with the Node/PostgreSQL API, migrate mobile, admin, web, and MCP callers, add controlled cutover tooling, and define hardened Dokploy infrastructure.
This commit is contained in:
1 parent
01bb8225ae
commit
006761d3b0
294 files changed
+16259
-6138
No files matched your search
@@ -0,0 +1,57 @@
|
||||
import { ApiError, apiRequest } from "@/lib/apiClient";
|
||||
import { authClient } from "@/lib/authClient";
|
||||
|
||||
function response(status: number, body?: unknown) {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
text: jest.fn(async () => body === undefined ? "" : JSON.stringify(body)),
|
||||
} as unknown as Response;
|
||||
}
|
||||
|
||||
describe("apiClient", () => {
|
||||
const fetchMock = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
global.fetch = fetchMock;
|
||||
(authClient.auth.getSession as jest.Mock).mockResolvedValue({
|
||||
data: { session: { access_token: "hosted-auth-token" } },
|
||||
error: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("injects the current Supabase access token", async () => {
|
||||
fetchMock.mockResolvedValue(response(200, { profile: { id: "user-1" } }));
|
||||
await apiRequest("/v1/me");
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
"http://127.0.0.1:3003/v1/me",
|
||||
expect.objectContaining({ headers: expect.any(Headers) }),
|
||||
);
|
||||
const headers = fetchMock.mock.calls[0][1].headers as Headers;
|
||||
expect(headers.get("Authorization")).toBe("Bearer hosted-auth-token");
|
||||
});
|
||||
|
||||
it("fails closed when there is no authenticated session", async () => {
|
||||
(authClient.auth.getSession as jest.Mock).mockResolvedValue({ data: { session: null }, error: null });
|
||||
|
||||
await expect(apiRequest("/v1/me")).rejects.toMatchObject({ status: 401 });
|
||||
expect(fetchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("preserves API status and error details", async () => {
|
||||
fetchMock.mockResolvedValue(response(403, {
|
||||
error: { message: "Couple access denied", code: "FORBIDDEN" },
|
||||
}));
|
||||
|
||||
await expect(apiRequest("/v1/me")).rejects.toEqual(
|
||||
expect.objectContaining<ApiError>({
|
||||
name: "ApiError",
|
||||
message: "Couple access denied",
|
||||
status: 403,
|
||||
details: { error: { message: "Couple access denied", code: "FORBIDDEN" } },
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user