fix(api): completedAt: null on non-complete states + OpenAPI timestamps & rate-limit headers (#29)

This commit is contained in:
2026-03-18 21:49:51 -04:00
parent b929e6d72f
commit ea4cddc2ad
2 changed files with 60 additions and 1 deletions

View File

@@ -309,6 +309,7 @@ router.get("/jobs/:id", async (req: Request, res: Response) => {
jobId: job.id, jobId: job.id,
state: job.state, state: job.state,
createdAt: job.createdAt.toISOString(), createdAt: job.createdAt.toISOString(),
completedAt: job.state === "complete" ? job.updatedAt.toISOString() : null,
}; };
switch (job.state) { switch (job.state) {
@@ -356,7 +357,6 @@ router.get("/jobs/:id", async (req: Request, res: Response) => {
case "complete": case "complete":
res.json({ res.json({
...base, ...base,
completedAt: job.updatedAt.toISOString(),
result: job.result ?? undefined, result: job.result ?? undefined,
...(job.actualCostUsd != null ? { ...(job.actualCostUsd != null ? {
costLedger: { costLedger: {

View File

@@ -319,24 +319,68 @@ paths:
responses: responses:
"200": "200":
description: Demo result description: Demo result
headers:
X-RateLimit-Limit:
schema:
type: integer
description: Maximum requests allowed per window (always 5)
X-RateLimit-Remaining:
schema:
type: integer
description: Requests remaining in the current window
X-RateLimit-Reset:
schema:
type: integer
description: Unix epoch seconds when the rate limit window resets
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/DemoResponse" $ref: "#/components/schemas/DemoResponse"
"400": "400":
description: Missing or invalid request param description: Missing or invalid request param
headers:
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
X-RateLimit-Reset:
schema:
type: integer
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"429": "429":
description: Rate limit exceeded description: Rate limit exceeded
headers:
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
description: Always 0 when rate limited
X-RateLimit-Reset:
schema:
type: integer
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"500": "500":
description: Server error description: Server error
headers:
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
X-RateLimit-Reset:
schema:
type: integer
content: content:
application/json: application/json:
schema: schema:
@@ -379,10 +423,15 @@ components:
type: object type: object
required: required:
- jobId - jobId
- createdAt
- evalInvoice - evalInvoice
properties: properties:
jobId: jobId:
type: string type: string
createdAt:
type: string
format: date-time
description: ISO 8601 timestamp of job creation
evalInvoice: evalInvoice:
$ref: "#/components/schemas/InvoiceInfo" $ref: "#/components/schemas/InvoiceInfo"
JobState: JobState:
@@ -451,11 +500,21 @@ components:
required: required:
- jobId - jobId
- state - state
- createdAt
properties: properties:
jobId: jobId:
type: string type: string
state: state:
$ref: "#/components/schemas/JobState" $ref: "#/components/schemas/JobState"
createdAt:
type: string
format: date-time
description: ISO 8601 timestamp of job creation (always present)
completedAt:
type: string
format: date-time
nullable: true
description: ISO 8601 timestamp of job completion; null when not yet complete
evalInvoice: evalInvoice:
$ref: "#/components/schemas/InvoiceInfo" $ref: "#/components/schemas/InvoiceInfo"
workInvoice: workInvoice: