fix(api): completedAt: null on non-complete states + OpenAPI timestamps & rate-limit headers (#29)
This commit is contained in:
@@ -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: {
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user