openapi.json 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. {
  2. "openapi": "3.1.0",
  3. "info": {
  4. "title": "hs-data API",
  5. "description": "Group-buy (拼团) funnel service over ads_trd_group_funnel_daily (single day, full history) + ads_trd_group_funnel_rolling (7d/30d).",
  6. "version": "0.1.0"
  7. },
  8. "paths": {
  9. "/api/funnels/query": {
  10. "post": {
  11. "tags": [
  12. "funnels"
  13. ],
  14. "summary": "Query Funnel",
  15. "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).",
  16. "operationId": "query_funnel_api_funnels_query_post",
  17. "requestBody": {
  18. "content": {
  19. "application/json": {
  20. "schema": {
  21. "$ref": "#/components/schemas/FunnelQueryRequest"
  22. }
  23. }
  24. },
  25. "required": true
  26. },
  27. "responses": {
  28. "200": {
  29. "description": "Successful Response",
  30. "content": {
  31. "application/json": {
  32. "schema": {
  33. "$ref": "#/components/schemas/FunnelQueryResponse"
  34. }
  35. }
  36. }
  37. },
  38. "422": {
  39. "description": "Validation Error",
  40. "content": {
  41. "application/json": {
  42. "schema": {
  43. "$ref": "#/components/schemas/HTTPValidationError"
  44. }
  45. }
  46. }
  47. }
  48. }
  49. }
  50. },
  51. "/health": {
  52. "get": {
  53. "tags": [
  54. "meta"
  55. ],
  56. "summary": "Health",
  57. "description": "Liveness probe. Does not touch the database.",
  58. "operationId": "health_health_get",
  59. "responses": {
  60. "200": {
  61. "description": "Successful Response",
  62. "content": {
  63. "application/json": {
  64. "schema": {
  65. "additionalProperties": {
  66. "type": "string"
  67. },
  68. "type": "object",
  69. "title": "Response Health Health Get"
  70. }
  71. }
  72. }
  73. }
  74. }
  75. }
  76. }
  77. },
  78. "components": {
  79. "schemas": {
  80. "DataStatus": {
  81. "type": "string",
  82. "enum": [
  83. "ready",
  84. "missing"
  85. ],
  86. "title": "DataStatus",
  87. "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."
  88. },
  89. "FunnelQueryRequest": {
  90. "properties": {
  91. "period": {
  92. "$ref": "#/components/schemas/Period"
  93. },
  94. "snapshot_dt": {
  95. "anyOf": [
  96. {
  97. "type": "string",
  98. "format": "date"
  99. },
  100. {
  101. "type": "null"
  102. }
  103. ],
  104. "title": "Snapshot Dt",
  105. "description": "Optional ISO date (YYYY-MM-DD). Only meaningful for period=day; ignored for last_7d/last_30d. Must be <= yesterday."
  106. }
  107. },
  108. "type": "object",
  109. "required": [
  110. "period"
  111. ],
  112. "title": "FunnelQueryRequest",
  113. "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."
  114. },
  115. "FunnelQueryResponse": {
  116. "properties": {
  117. "period": {
  118. "$ref": "#/components/schemas/Period"
  119. },
  120. "snapshot_dt": {
  121. "anyOf": [
  122. {
  123. "type": "string"
  124. },
  125. {
  126. "type": "null"
  127. }
  128. ],
  129. "title": "Snapshot Dt",
  130. "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."
  131. },
  132. "results": {
  133. "items": {
  134. "$ref": "#/components/schemas/FunnelStepResult"
  135. },
  136. "type": "array",
  137. "title": "Results"
  138. },
  139. "data_status": {
  140. "$ref": "#/components/schemas/DataStatus"
  141. }
  142. },
  143. "type": "object",
  144. "required": [
  145. "period",
  146. "results",
  147. "data_status"
  148. ],
  149. "title": "FunnelQueryResponse",
  150. "description": "Funnel query response body."
  151. },
  152. "FunnelStepResult": {
  153. "properties": {
  154. "step_index": {
  155. "type": "integer",
  156. "minimum": 1.0,
  157. "title": "Step Index",
  158. "description": "1-based step index"
  159. },
  160. "name": {
  161. "type": "string",
  162. "title": "Name",
  163. "description": "Chinese display name of the step"
  164. },
  165. "event_key": {
  166. "type": "string",
  167. "title": "Event Key",
  168. "description": "Stable step key (start/show/...)"
  169. },
  170. "uv": {
  171. "type": "integer",
  172. "minimum": 0.0,
  173. "title": "Uv"
  174. },
  175. "conversion_rate": {
  176. "anyOf": [
  177. {
  178. "type": "number"
  179. },
  180. {
  181. "type": "null"
  182. }
  183. ],
  184. "title": "Conversion Rate",
  185. "description": "uv[i] / uv[i-1]; null for step 1 or when uv[i-1] == 0"
  186. },
  187. "dropoff_rate": {
  188. "anyOf": [
  189. {
  190. "type": "number"
  191. },
  192. {
  193. "type": "null"
  194. }
  195. ],
  196. "title": "Dropoff Rate",
  197. "description": "1 - conversion_rate; null when conversion_rate is null"
  198. }
  199. },
  200. "type": "object",
  201. "required": [
  202. "step_index",
  203. "name",
  204. "event_key",
  205. "uv"
  206. ],
  207. "title": "FunnelStepResult",
  208. "description": "Computed UV and conversion metrics for one fixed step."
  209. },
  210. "HTTPValidationError": {
  211. "properties": {
  212. "detail": {
  213. "items": {
  214. "$ref": "#/components/schemas/ValidationError"
  215. },
  216. "type": "array",
  217. "title": "Detail"
  218. }
  219. },
  220. "type": "object",
  221. "title": "HTTPValidationError"
  222. },
  223. "Period": {
  224. "type": "string",
  225. "enum": [
  226. "day",
  227. "last_7d",
  228. "last_30d"
  229. ],
  230. "title": "Period",
  231. "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."
  232. },
  233. "ValidationError": {
  234. "properties": {
  235. "loc": {
  236. "items": {
  237. "anyOf": [
  238. {
  239. "type": "string"
  240. },
  241. {
  242. "type": "integer"
  243. }
  244. ]
  245. },
  246. "type": "array",
  247. "title": "Location"
  248. },
  249. "msg": {
  250. "type": "string",
  251. "title": "Message"
  252. },
  253. "type": {
  254. "type": "string",
  255. "title": "Error Type"
  256. },
  257. "input": {
  258. "title": "Input"
  259. },
  260. "ctx": {
  261. "type": "object",
  262. "title": "Context"
  263. }
  264. },
  265. "type": "object",
  266. "required": [
  267. "loc",
  268. "msg",
  269. "type"
  270. ],
  271. "title": "ValidationError"
  272. }
  273. }
  274. }
  275. }