Skip to content

Commit 330c056

Browse files
brownjuly2003-codeJuliaEdomclaude
authored
feat(ops): stuck-orders worklist + SLA-stage contract block (D3) (#145)
New GET /v1/ops/stuck-orders (ops-surfaces-spec.md §3): the catalog gains an optional `stages:` ladder on order.yaml (§1.5), a new QueryEngine bulk read (fetch_orders_by_status) fetches open orders in one query, and the stage clock/breach arithmetic that D2 inlined in the timeline handler is factored into a shared src/serving/semantic_layer/stage_clock.py used by both surfaces (I2). Widens the I1 structural ratchet to cover routers/ops.py and bumps the reviewed B608 nosec count for the new bulk-read site. Co-authored-by: JuliaEdom <uedomskikh@gmail.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 45418ac commit 330c056

17 files changed

Lines changed: 923 additions & 51 deletions

‎contracts/entities/order.yaml‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,20 @@ fields:
1111
created_at: Order creation timestamp
1212
relationships:
1313
user: user_id
14+
stages:
15+
- name: pending
16+
sla_minutes: 30
17+
description: Confirmation SLA — marketplace orders auto-confirm within
18+
minutes; a pending order older than this needs a payment/CRM decision
19+
- name: confirmed
20+
sla_minutes: 1440
21+
description: Ship-by SLA — FBS marketplace shipping deadlines drive the
22+
24h budget for warehouse handover
23+
- name: shipped
24+
sla_minutes: 7200
25+
description: Delivery SLA — 5 days courier/pickup before a customer
26+
contact is due
27+
- name: delivered
28+
terminal: true
29+
- name: cancelled
30+
terminal: true

‎docs/agent-tools/claude-tools.json‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,44 @@
844844
]
845845
}
846846
},
847+
{
848+
"name": "get_stuck_orders_v1_ops_stuck_orders_get",
849+
"description": "Get Stuck Orders",
850+
"input_schema": {
851+
"type": "object",
852+
"properties": {
853+
"stage": {
854+
"anyOf": [
855+
{
856+
"type": "string"
857+
},
858+
{
859+
"type": "null"
860+
}
861+
],
862+
"title": "Stage"
863+
},
864+
"include_within_sla": {
865+
"type": "boolean",
866+
"default": false,
867+
"title": "Include Within Sla"
868+
},
869+
"page": {
870+
"type": "integer",
871+
"minimum": 1,
872+
"default": 1,
873+
"title": "Page"
874+
},
875+
"page_size": {
876+
"type": "integer",
877+
"maximum": 100,
878+
"minimum": 1,
879+
"default": 50,
880+
"title": "Page Size"
881+
}
882+
}
883+
}
884+
},
847885
{
848886
"name": "search_v1_search_get",
849887
"description": "Search",

‎docs/agent-tools/openai-tools.json‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,47 @@
940940
}
941941
}
942942
},
943+
{
944+
"type": "function",
945+
"function": {
946+
"name": "get_stuck_orders_v1_ops_stuck_orders_get",
947+
"description": "Get Stuck Orders",
948+
"parameters": {
949+
"type": "object",
950+
"properties": {
951+
"stage": {
952+
"anyOf": [
953+
{
954+
"type": "string"
955+
},
956+
{
957+
"type": "null"
958+
}
959+
],
960+
"title": "Stage"
961+
},
962+
"include_within_sla": {
963+
"type": "boolean",
964+
"default": false,
965+
"title": "Include Within Sla"
966+
},
967+
"page": {
968+
"type": "integer",
969+
"minimum": 1,
970+
"default": 1,
971+
"title": "Page"
972+
},
973+
"page_size": {
974+
"type": "integer",
975+
"maximum": 100,
976+
"minimum": 1,
977+
"default": 50,
978+
"title": "Page Size"
979+
}
980+
}
981+
}
982+
}
983+
},
943984
{
944985
"type": "function",
945986
"function": {

‎docs/openapi.json‎

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,88 @@
17751775
}
17761776
}
17771777
},
1778+
"/v1/ops/stuck-orders": {
1779+
"get": {
1780+
"tags": [
1781+
"ops"
1782+
],
1783+
"summary": "Get Stuck Orders",
1784+
"operationId": "get_stuck_orders_v1_ops_stuck_orders_get",
1785+
"parameters": [
1786+
{
1787+
"name": "stage",
1788+
"in": "query",
1789+
"required": false,
1790+
"schema": {
1791+
"anyOf": [
1792+
{
1793+
"type": "string"
1794+
},
1795+
{
1796+
"type": "null"
1797+
}
1798+
],
1799+
"title": "Stage"
1800+
}
1801+
},
1802+
{
1803+
"name": "include_within_sla",
1804+
"in": "query",
1805+
"required": false,
1806+
"schema": {
1807+
"type": "boolean",
1808+
"default": false,
1809+
"title": "Include Within Sla"
1810+
}
1811+
},
1812+
{
1813+
"name": "page",
1814+
"in": "query",
1815+
"required": false,
1816+
"schema": {
1817+
"type": "integer",
1818+
"minimum": 1,
1819+
"default": 1,
1820+
"title": "Page"
1821+
}
1822+
},
1823+
{
1824+
"name": "page_size",
1825+
"in": "query",
1826+
"required": false,
1827+
"schema": {
1828+
"type": "integer",
1829+
"maximum": 100,
1830+
"minimum": 1,
1831+
"default": 50,
1832+
"title": "Page Size"
1833+
}
1834+
}
1835+
],
1836+
"responses": {
1837+
"200": {
1838+
"description": "Successful Response",
1839+
"content": {
1840+
"application/json": {
1841+
"schema": {
1842+
"$ref": "#/components/schemas/StuckOrdersResponse"
1843+
}
1844+
}
1845+
}
1846+
},
1847+
"422": {
1848+
"description": "Validation Error",
1849+
"content": {
1850+
"application/json": {
1851+
"schema": {
1852+
"$ref": "#/components/schemas/HTTPValidationError"
1853+
}
1854+
}
1855+
}
1856+
}
1857+
}
1858+
}
1859+
},
17781860
"/v1/search": {
17791861
"get": {
17801862
"tags": [
@@ -3724,6 +3806,159 @@
37243806
],
37253807
"title": "SearchResult"
37263808
},
3809+
"StuckOrderItem": {
3810+
"properties": {
3811+
"order_id": {
3812+
"type": "string",
3813+
"title": "Order Id"
3814+
},
3815+
"user_id": {
3816+
"anyOf": [
3817+
{
3818+
"type": "string"
3819+
},
3820+
{
3821+
"type": "null"
3822+
}
3823+
],
3824+
"title": "User Id"
3825+
},
3826+
"status": {
3827+
"type": "string",
3828+
"title": "Status"
3829+
},
3830+
"entered_at": {
3831+
"anyOf": [
3832+
{
3833+
"type": "string",
3834+
"format": "date-time"
3835+
},
3836+
{
3837+
"type": "null"
3838+
}
3839+
],
3840+
"title": "Entered At"
3841+
},
3842+
"in_stage_seconds": {
3843+
"anyOf": [
3844+
{
3845+
"type": "number"
3846+
},
3847+
{
3848+
"type": "null"
3849+
}
3850+
],
3851+
"title": "In Stage Seconds"
3852+
},
3853+
"sla_minutes": {
3854+
"anyOf": [
3855+
{
3856+
"type": "integer"
3857+
},
3858+
{
3859+
"type": "null"
3860+
}
3861+
],
3862+
"title": "Sla Minutes"
3863+
},
3864+
"overshoot_ratio": {
3865+
"anyOf": [
3866+
{
3867+
"type": "number"
3868+
},
3869+
{
3870+
"type": "null"
3871+
}
3872+
],
3873+
"title": "Overshoot Ratio"
3874+
},
3875+
"clock": {
3876+
"type": "string",
3877+
"enum": [
3878+
"journal",
3879+
"fallback"
3880+
],
3881+
"title": "Clock"
3882+
},
3883+
"total_amount": {
3884+
"anyOf": [
3885+
{
3886+
"type": "number"
3887+
},
3888+
{
3889+
"type": "null"
3890+
}
3891+
],
3892+
"title": "Total Amount"
3893+
},
3894+
"currency": {
3895+
"anyOf": [
3896+
{
3897+
"type": "string"
3898+
},
3899+
{
3900+
"type": "null"
3901+
}
3902+
],
3903+
"title": "Currency"
3904+
}
3905+
},
3906+
"type": "object",
3907+
"required": [
3908+
"order_id",
3909+
"status",
3910+
"clock"
3911+
],
3912+
"title": "StuckOrderItem"
3913+
},
3914+
"StuckOrdersResponse": {
3915+
"properties": {
3916+
"items": {
3917+
"items": {
3918+
"$ref": "#/components/schemas/StuckOrderItem"
3919+
},
3920+
"type": "array",
3921+
"title": "Items"
3922+
},
3923+
"summary": {
3924+
"$ref": "#/components/schemas/StuckOrdersSummary"
3925+
},
3926+
"pagination": {
3927+
"additionalProperties": {
3928+
"type": "integer"
3929+
},
3930+
"type": "object",
3931+
"title": "Pagination"
3932+
}
3933+
},
3934+
"type": "object",
3935+
"required": [
3936+
"items",
3937+
"summary",
3938+
"pagination"
3939+
],
3940+
"title": "StuckOrdersResponse"
3941+
},
3942+
"StuckOrdersSummary": {
3943+
"properties": {
3944+
"open_by_stage": {
3945+
"additionalProperties": {
3946+
"type": "integer"
3947+
},
3948+
"type": "object",
3949+
"title": "Open By Stage"
3950+
},
3951+
"breached_by_stage": {
3952+
"additionalProperties": {
3953+
"type": "integer"
3954+
},
3955+
"type": "object",
3956+
"title": "Breached By Stage"
3957+
}
3958+
},
3959+
"type": "object",
3960+
"title": "StuckOrdersSummary"
3961+
},
37273962
"ValidationError": {
37283963
"properties": {
37293964
"loc": {

‎src/serving/api/main.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from src.serving.api.routers.contracts import router as contracts_router
4242
from src.serving.api.routers.deadletter import router as deadletter_router
4343
from src.serving.api.routers.lineage import router as lineage_router
44+
from src.serving.api.routers.ops import router as ops_router
4445
from src.serving.api.routers.search import router as search_router
4546
from src.serving.api.routers.slo import router as slo_router
4647
from src.serving.api.routers.stream import router as stream_router
@@ -333,6 +334,7 @@ async def demo_mode_guard(request: Request, call_next: RequestResponseEndpoint)
333334
app.include_router(contracts_router, prefix="/v1")
334335
app.include_router(deadletter_router)
335336
app.include_router(lineage_router)
337+
app.include_router(ops_router)
336338
app.include_router(search_router, prefix="/v1")
337339
app.include_router(slo_router)
338340
app.include_router(stream_router)

0 commit comments

Comments
 (0)