feat(ECR-012–016): 合规、题库、时辰刷新、头像、MBTI OEJTS 与埋点
落地输入合规、探索题库、报告日/时辰刷新、账号头像、OEJTS 量表,并补齐 H5 埋点与 Admin 漏斗;同步 ESS 工件、切至自建 Git、清理 GitHub Actions。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+162
-9
@@ -6,6 +6,8 @@ info:
|
||||
愈心谷 P1 API 契约(冻结草案)。
|
||||
用户可见文案遵循 .ai/product/lexicon.md。
|
||||
统一信封:{ code, message, data };code=0 成功。
|
||||
用户自由文字不合规(昵称/档案名/问答/备注等):HTTP 400 · code 40060 · message「文案不合规:…」
|
||||
(见 feature-spec/input-compliance;后端 textsafe 权威校验)。
|
||||
servers:
|
||||
- url: http://127.0.0.1:8080
|
||||
tags:
|
||||
@@ -64,6 +66,44 @@ paths:
|
||||
'200':
|
||||
description: OK
|
||||
|
||||
/api/v1/auth/me/avatar:
|
||||
post:
|
||||
tags: [system]
|
||||
summary: Upload account avatar (multipart file)
|
||||
description: jpeg/png/webp · max 2MB · field name `file` · returns AuthUser with avatar_url
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
required: [file]
|
||||
properties:
|
||||
file: { type: string, format: binary }
|
||||
responses:
|
||||
'200':
|
||||
description: OK · AuthUser with avatar_url
|
||||
'400':
|
||||
description: bad type / too large / empty (code 40114)
|
||||
'401':
|
||||
description: unauthorized
|
||||
|
||||
/api/v1/media/avatars/{file}:
|
||||
get:
|
||||
tags: [system]
|
||||
summary: Serve account avatar image
|
||||
description: Public read; `{uuid}.{jpg|jpeg|png|webp}` only; path traversal rejected
|
||||
parameters:
|
||||
- name: file
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: image bytes
|
||||
'404':
|
||||
description: missing or invalid name
|
||||
|
||||
/api/v1/admin/auth/login:
|
||||
post:
|
||||
tags: [admin]
|
||||
@@ -419,13 +459,17 @@ paths:
|
||||
/api/v1/home/daily-tips:
|
||||
get:
|
||||
tags: [system]
|
||||
summary: Homepage self-card daily tips (clothing / colors / wellness)
|
||||
summary: Homepage self-card tips by 时辰 (clothing / colors / wellness)
|
||||
description: >
|
||||
Uses self profile birth + local time hexagram seed and DeepSeek when configured.
|
||||
Falls back to local tips without LLM or birth profile. DeviceAuth required.
|
||||
Cached per user × Chinese double-hour (时辰). Returns immediately from cache/fallback;
|
||||
LLM warm runs in background. Includes shichen, shichen_name, valid_until for client refresh.
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
description: OK · tips + valid_until
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EnvelopeHomeDailyTips'
|
||||
|
||||
/api/v1/admin/home/tools:
|
||||
get:
|
||||
@@ -639,7 +683,7 @@ paths:
|
||||
profile_id: { type: string, format: uuid }
|
||||
responses:
|
||||
'200':
|
||||
description: GrowthReport type=star(含 chart/planets/aspects_preview/outlook/transits)
|
||||
description: GrowthReport type=star(含 chart/planets/aspects_preview/outlook/transits;summary.as_of/valid_until 按自然日;GET 换日原地刷新运势)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -758,7 +802,7 @@ paths:
|
||||
profile_id: { type: string, format: uuid }
|
||||
responses:
|
||||
'200':
|
||||
description: GrowthReport type=rhythm
|
||||
description: GrowthReport type=rhythm(summary.as_of/valid_until 按自然日;GET 换日原地刷新今日/本周建议)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -853,6 +897,61 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EnvelopeGrowthReport'
|
||||
|
||||
/api/v1/scale-bank/catalog:
|
||||
get:
|
||||
tags: [scale]
|
||||
summary: curated 题库精选宫格 + 分类卡片(A 集非临床)
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: { type: integer }
|
||||
message: { type: string }
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
featured:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
slug: { type: string }
|
||||
title: { type: string }
|
||||
description: { type: string }
|
||||
category_key: { type: string }
|
||||
icon: { type: string }
|
||||
path: { type: string }
|
||||
categories:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
key: { type: string }
|
||||
title: { type: string }
|
||||
description: { type: string }
|
||||
icon: { type: string }
|
||||
count: { type: integer }
|
||||
path: { type: string }
|
||||
|
||||
/api/v1/scale-bank/categories/{key}:
|
||||
get:
|
||||
tags: [scale]
|
||||
summary: curated 题库某一分类下的量表列表
|
||||
parameters:
|
||||
- name: key
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
'404':
|
||||
description: category not found
|
||||
|
||||
/api/v1/scales:
|
||||
get:
|
||||
tags: [scale]
|
||||
@@ -869,6 +968,9 @@ paths:
|
||||
get:
|
||||
tags: [scale]
|
||||
summary: 探索测试题目
|
||||
description: >
|
||||
`mbti-full` 未开通成长会员时返回 access=membership · locked=true 且 questions 为空。
|
||||
curated scalebank slug 从 embed 返回题目。
|
||||
parameters:
|
||||
- name: slug
|
||||
in: path
|
||||
@@ -883,6 +985,19 @@ paths:
|
||||
$ref: '#/components/schemas/EnvelopeScaleDetail'
|
||||
|
||||
/api/v1/scales/{slug}/result:
|
||||
get:
|
||||
tags: [scale]
|
||||
summary: 当前用户该量表最近一次结果
|
||||
parameters:
|
||||
- name: slug
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: ScaleSubmitResult
|
||||
'404':
|
||||
description: 尚无结果
|
||||
post:
|
||||
tags: [scale]
|
||||
summary: 提交探索测试并计分
|
||||
@@ -904,8 +1019,8 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: 探索结果
|
||||
|
||||
/api/v1/ask/quota:
|
||||
'403':
|
||||
description: mbti-full 需要成长会员(code 40310)
|
||||
get:
|
||||
tags: [ask]
|
||||
summary: 当前问答剩余次数(免费额度或成长会员)
|
||||
@@ -1097,11 +1212,40 @@ components:
|
||||
user_id: { type: string, format: uuid }
|
||||
profile_id: { type: string, format: uuid }
|
||||
type: { type: string }
|
||||
summary: { type: object, additionalProperties: true }
|
||||
summary:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
description: >
|
||||
For type=star|rhythm include as_of (YYYY-MM-DD CST) and valid_until (next midnight CST RFC3339).
|
||||
GET latest/id refreshes day-scoped outlook in place when as_of is stale; report id unchanged.
|
||||
detail: { type: object, nullable: true, additionalProperties: true }
|
||||
has_deep_access: { type: boolean }
|
||||
created_at: { type: string, format: date-time }
|
||||
|
||||
HomeDailyTips:
|
||||
type: object
|
||||
required: [clothing_index, clothing, color_note, palette, wellness, source, shichen, shichen_name, valid_until]
|
||||
properties:
|
||||
clothing_index: { type: integer }
|
||||
clothing: { type: string }
|
||||
color_note: { type: string }
|
||||
palette:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name: { type: string }
|
||||
hex: { type: string }
|
||||
wellness: { type: string }
|
||||
source: { type: string, description: llm | fallback }
|
||||
gua_name: { type: string }
|
||||
day_part: { type: string }
|
||||
as_of: { type: string, format: date }
|
||||
shichen: { type: integer, minimum: 0, maximum: 11 }
|
||||
shichen_name: { type: string }
|
||||
valid_until: { type: string, format: date-time, description: Next 时辰 start RFC3339 }
|
||||
need_birth: { type: boolean }
|
||||
|
||||
MembershipMe:
|
||||
type: object
|
||||
required: [active, status]
|
||||
@@ -1149,6 +1293,8 @@ components:
|
||||
slug: { type: string }
|
||||
title: { type: string }
|
||||
description: { type: string }
|
||||
access: { type: string, description: free | membership }
|
||||
locked: { type: boolean, description: true when membership required and inactive }
|
||||
questions:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/ScaleQuestion' }
|
||||
@@ -1223,6 +1369,13 @@ components:
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/GrowthReport' }
|
||||
|
||||
EnvelopeHomeDailyTips:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Envelope'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/HomeDailyTips' }
|
||||
|
||||
EnvelopeMembershipMe:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Envelope'
|
||||
|
||||
Reference in New Issue
Block a user