Compare commits
2 Commits
fix/prod-c
...
fix/api-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53b9561a54 | ||
| 7e9c20d4bf |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "calendar-run-backend",
|
"name": "calendar-run-backend",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ export function createApp(): express.Express {
|
|||||||
|
|
||||||
app.use(healthRouter);
|
app.use(healthRouter);
|
||||||
app.use(racesRouter);
|
app.use(racesRouter);
|
||||||
|
// Тот же API под /api/* — если прокси не снимает префикс или запрос идёт напрямую на порт бэкенда с /api.
|
||||||
|
app.use("/api", healthRouter);
|
||||||
|
app.use("/api", racesRouter);
|
||||||
|
|
||||||
app.use((err: unknown, _req: Request, res: Response, _next: NextFunction) => {
|
app.use((err: unknown, _req: Request, res: Response, _next: NextFunction) => {
|
||||||
if (err instanceof SyntaxError && "body" in err) {
|
if (err instanceof SyntaxError && "body" in err) {
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ test("GET /health returns ok", async () => {
|
|||||||
assert.ok(res.body.version.length > 0);
|
assert.ok(res.body.version.length > 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("GET /api/health returns ok (prefix without proxy strip)", async () => {
|
||||||
|
const res = await request(app).get("/api/health").expect(200);
|
||||||
|
assert.equal(res.body.status, "ok");
|
||||||
|
});
|
||||||
|
|
||||||
test("GET /ready succeeds with mock database", async () => {
|
test("GET /ready succeeds with mock database", async () => {
|
||||||
const res = await request(app).get("/ready").expect(200);
|
const res = await request(app).get("/ready").expect(200);
|
||||||
assert.equal(res.body.status, "ready");
|
assert.equal(res.body.status, "ready");
|
||||||
@@ -34,6 +39,11 @@ test("GET /races accepts year and month", async () => {
|
|||||||
assert.ok(Array.isArray(res.body));
|
assert.ok(Array.isArray(res.body));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("GET /api/races mirrors GET /races", async () => {
|
||||||
|
const res = await request(app).get("/api/races?year=2026&month=5").expect(200);
|
||||||
|
assert.ok(Array.isArray(res.body));
|
||||||
|
});
|
||||||
|
|
||||||
test("GET /races/:id returns not_found", async () => {
|
test("GET /races/:id returns not_found", async () => {
|
||||||
const res = await request(app).get("/races/does-not-exist").expect(404);
|
const res = await request(app).get("/races/does-not-exist").expect(404);
|
||||||
assert.equal(res.body.error, "not_found");
|
assert.equal(res.body.error, "not_found");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "calendar-run-frontend",
|
"name": "calendar-run-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -35,10 +35,15 @@ export async function requestJson<T>(path: string, init?: RequestInit): Promise<
|
|||||||
|
|
||||||
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
||||||
try {
|
try {
|
||||||
|
const defaultHeaders: Record<string, string> = {};
|
||||||
|
if (method !== "GET" && method !== "HEAD") {
|
||||||
|
defaultHeaders["Content-Type"] = "application/json";
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(buildUrl(path), {
|
const response = await fetch(buildUrl(path), {
|
||||||
...init,
|
...init,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
...defaultHeaders,
|
||||||
...(init?.headers ?? {}),
|
...(init?.headers ?? {}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -55,25 +60,6 @@ export async function requestJson<T>(path: string, init?: RequestInit): Promise<
|
|||||||
await delay(80 * attempt);
|
await delay(80 * attempt);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// #region agent log
|
|
||||||
fetch("http://127.0.0.1:7488/ingest/a18f912f-72c6-4a58-866b-17810a6b89d2", {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "587ee5" },
|
|
||||||
body: JSON.stringify({
|
|
||||||
sessionId: "587ee5",
|
|
||||||
hypothesisId: "H-http-not-ok",
|
|
||||||
location: "http.ts:requestJson",
|
|
||||||
message: "HTTP error response",
|
|
||||||
data: {
|
|
||||||
path,
|
|
||||||
status: response.status,
|
|
||||||
contentType: response.headers.get("content-type"),
|
|
||||||
payloadIsObject: payload !== null && typeof payload === "object",
|
|
||||||
},
|
|
||||||
timestamp: Date.now(),
|
|
||||||
}),
|
|
||||||
}).catch(() => {});
|
|
||||||
// #endregion
|
|
||||||
throw toApiError(response.status, payload);
|
throw toApiError(response.status, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user