{ "openapi": "3.1.0", "info": { "title": "hs-data API", "description": "Group-buy (拼团) funnel service over ads_trd_group_funnel_daily (single day, full history) + ads_trd_group_funnel_rolling (7d/30d).", "version": "0.1.0" }, "paths": { "/api/funnels/query": { "post": { "tags": [ "funnels" ], "summary": "Query Funnel", "description": "Compute UV and conversion metrics for the group-buy funnel over a period.\n\nThe ``period`` enum is validated by Pydantic (bad value -> 422). For\n``period=day``, a ``snapshot_dt`` later than yesterday (today/future) is\nrejected with 422 (data is T+1).", "operationId": "query_funnel_api_funnels_query_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FunnelQueryRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FunnelQueryResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/health": { "get": { "tags": [ "meta" ], "summary": "Health", "description": "Liveness probe. Does not touch the database.", "operationId": "health_health_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "additionalProperties": { "type": "string" }, "type": "object", "title": "Response Health Health Get" } } } } } } } }, "components": { "schemas": { "DataStatus": { "type": "string", "enum": [ "ready", "missing" ], "title": "DataStatus", "description": "Data completeness status for a query result (docs/02 §5 v3).\n\nready - the target row exists and the period's columns are non-null.\nmissing - no target row, or the period columns are NULL. Never zero-filled." }, "FunnelQueryRequest": { "properties": { "period": { "$ref": "#/components/schemas/Period" }, "snapshot_dt": { "anyOf": [ { "type": "string", "format": "date" }, { "type": "null" } ], "title": "Snapshot Dt", "description": "Optional ISO date (YYYY-MM-DD). Only meaningful for period=day; ignored for last_7d/last_30d. Must be <= yesterday." } }, "type": "object", "required": [ "period" ], "title": "FunnelQueryRequest", "description": "Funnel query request body.\n\n``snapshot_dt`` (ISO ``YYYY-MM-DD``) is optional and only meaningful for\n``period=day``: omitted -> latest daily row; given -> that historical day\n(must be <= yesterday). For ``last_7d`` / ``last_30d`` it is ignored." }, "FunnelQueryResponse": { "properties": { "period": { "$ref": "#/components/schemas/Period" }, "snapshot_dt": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Snapshot Dt", "description": "dt (yyyyMMdd) of the row actually used; for day = that day, for 7d/30d = the rolling row's as-of dt. null when missing." }, "results": { "items": { "$ref": "#/components/schemas/FunnelStepResult" }, "type": "array", "title": "Results" }, "data_status": { "$ref": "#/components/schemas/DataStatus" } }, "type": "object", "required": [ "period", "results", "data_status" ], "title": "FunnelQueryResponse", "description": "Funnel query response body." }, "FunnelStepResult": { "properties": { "step_index": { "type": "integer", "minimum": 1.0, "title": "Step Index", "description": "1-based step index" }, "name": { "type": "string", "title": "Name", "description": "Chinese display name of the step" }, "event_key": { "type": "string", "title": "Event Key", "description": "Stable step key (start/show/...)" }, "uv": { "type": "integer", "minimum": 0.0, "title": "Uv" }, "conversion_rate": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "title": "Conversion Rate", "description": "uv[i] / uv[i-1]; null for step 1 or when uv[i-1] == 0" }, "dropoff_rate": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "title": "Dropoff Rate", "description": "1 - conversion_rate; null when conversion_rate is null" } }, "type": "object", "required": [ "step_index", "name", "event_key", "uv" ], "title": "FunnelStepResult", "description": "Computed UV and conversion metrics for one fixed step." }, "HTTPValidationError": { "properties": { "detail": { "items": { "$ref": "#/components/schemas/ValidationError" }, "type": "array", "title": "Detail" } }, "type": "object", "title": "HTTPValidationError" }, "Period": { "type": "string", "enum": [ "day", "last_7d", "last_30d" ], "title": "Period", "description": "Supported periods (docs/02 §5 v3).\n\nRouting:\n day -> table ads_trd_group_funnel_daily (single day, full history).\n last_7d -> table ads_trd_group_funnel_rolling, columns uv_*_7d.\n last_30d -> table ads_trd_group_funnel_rolling, columns uv_*_30d.\n\nAny other value is rejected with HTTP 422." }, "ValidationError": { "properties": { "loc": { "items": { "anyOf": [ { "type": "string" }, { "type": "integer" } ] }, "type": "array", "title": "Location" }, "msg": { "type": "string", "title": "Message" }, "type": { "type": "string", "title": "Error Type" }, "input": { "title": "Input" }, "ctx": { "type": "object", "title": "Context" } }, "type": "object", "required": [ "loc", "msg", "type" ], "title": "ValidationError" } } } }