feat: 初始化考培练系统项目
- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
854
backend/app/api/v1/training_api_contract.yaml
Normal file
854
backend/app/api/v1/training_api_contract.yaml
Normal file
@@ -0,0 +1,854 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Training Module API
|
||||
description: 考培练系统陪练模块API契约
|
||||
version: 1.0.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8000/api/v1
|
||||
description: 本地开发服务器
|
||||
|
||||
paths:
|
||||
/training/scenes:
|
||||
get:
|
||||
summary: 获取陪练场景列表
|
||||
tags:
|
||||
- 陪练场景
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: category
|
||||
in: query
|
||||
description: 场景分类
|
||||
schema:
|
||||
type: string
|
||||
- name: status
|
||||
in: query
|
||||
description: 场景状态
|
||||
schema:
|
||||
type: string
|
||||
enum: [draft, active, inactive]
|
||||
- name: is_public
|
||||
in: query
|
||||
description: 是否公开
|
||||
schema:
|
||||
type: boolean
|
||||
- name: search
|
||||
in: query
|
||||
description: 搜索关键词
|
||||
schema:
|
||||
type: string
|
||||
- name: page
|
||||
in: query
|
||||
description: 页码
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
default: 1
|
||||
- name: page_size
|
||||
in: query
|
||||
description: 每页数量
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 20
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedScenesResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
post:
|
||||
summary: 创建陪练场景(管理员)
|
||||
tags:
|
||||
- 陪练场景
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingSceneCreate'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingSceneResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
|
||||
/training/scenes/{scene_id}:
|
||||
get:
|
||||
summary: 获取陪练场景详情
|
||||
tags:
|
||||
- 陪练场景
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: scene_id
|
||||
in: path
|
||||
required: true
|
||||
description: 场景ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingSceneResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
summary: 更新陪练场景(管理员)
|
||||
tags:
|
||||
- 陪练场景
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: scene_id
|
||||
in: path
|
||||
required: true
|
||||
description: 场景ID
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingSceneUpdate'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingSceneResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
summary: 删除陪练场景(管理员)
|
||||
tags:
|
||||
- 陪练场景
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: scene_id
|
||||
in: path
|
||||
required: true
|
||||
description: 场景ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "删除陪练场景成功"
|
||||
data:
|
||||
type: boolean
|
||||
example: true
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/training/sessions:
|
||||
post:
|
||||
summary: 开始陪练会话
|
||||
tags:
|
||||
- 陪练会话
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StartTrainingRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StartTrainingResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
description: 场景不存在
|
||||
|
||||
get:
|
||||
summary: 获取用户的陪练会话列表
|
||||
tags:
|
||||
- 陪练会话
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: scene_id
|
||||
in: query
|
||||
description: 场景ID
|
||||
schema:
|
||||
type: integer
|
||||
- name: status
|
||||
in: query
|
||||
description: 会话状态
|
||||
schema:
|
||||
type: string
|
||||
enum: [created, in_progress, completed, cancelled, error]
|
||||
- name: page
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
default: 1
|
||||
- name: page_size
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 20
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedSessionsResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/training/sessions/{session_id}:
|
||||
get:
|
||||
summary: 获取陪练会话详情
|
||||
tags:
|
||||
- 陪练会话
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: session_id
|
||||
in: path
|
||||
required: true
|
||||
description: 会话ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingSessionResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/training/sessions/{session_id}/end:
|
||||
post:
|
||||
summary: 结束陪练会话
|
||||
tags:
|
||||
- 陪练会话
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: session_id
|
||||
in: path
|
||||
required: true
|
||||
description: 会话ID
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EndTrainingRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EndTrainingResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/training/sessions/{session_id}/messages:
|
||||
get:
|
||||
summary: 获取陪练会话的消息列表
|
||||
tags:
|
||||
- 陪练消息
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: session_id
|
||||
in: path
|
||||
required: true
|
||||
description: 会话ID
|
||||
schema:
|
||||
type: integer
|
||||
- name: skip
|
||||
in: query
|
||||
description: 跳过数量
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 0
|
||||
- name: limit
|
||||
in: query
|
||||
description: 返回数量
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 500
|
||||
default: 100
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
message:
|
||||
type: string
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TrainingMessage'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/training/reports:
|
||||
get:
|
||||
summary: 获取用户的陪练报告列表
|
||||
tags:
|
||||
- 陪练报告
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: page
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
default: 1
|
||||
- name: page_size
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 20
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedReportsResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/training/reports/{report_id}:
|
||||
get:
|
||||
summary: 获取陪练报告详情
|
||||
tags:
|
||||
- 陪练报告
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: report_id
|
||||
in: path
|
||||
required: true
|
||||
description: 报告ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingReportResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/training/sessions/{session_id}/report:
|
||||
get:
|
||||
summary: 根据会话ID获取陪练报告
|
||||
tags:
|
||||
- 陪练报告
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: session_id
|
||||
in: path
|
||||
required: true
|
||||
description: 会话ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TrainingReportResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
responses:
|
||||
Unauthorized:
|
||||
description: 未授权
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
Forbidden:
|
||||
description: 禁止访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
NotFound:
|
||||
description: 资源未找到
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
schemas:
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
message:
|
||||
type: string
|
||||
detail:
|
||||
type: object
|
||||
|
||||
BaseResponse:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "success"
|
||||
request_id:
|
||||
type: string
|
||||
|
||||
PaginationMeta:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
page:
|
||||
type: integer
|
||||
page_size:
|
||||
type: integer
|
||||
pages:
|
||||
type: integer
|
||||
|
||||
TrainingSceneCreate:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- category
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
maxLength: 100
|
||||
description: 场景名称
|
||||
description:
|
||||
type: string
|
||||
description: 场景描述
|
||||
category:
|
||||
type: string
|
||||
maxLength: 50
|
||||
description: 场景分类
|
||||
ai_config:
|
||||
type: object
|
||||
description: AI配置
|
||||
prompt_template:
|
||||
type: string
|
||||
description: 提示词模板
|
||||
evaluation_criteria:
|
||||
type: object
|
||||
description: 评估标准
|
||||
is_public:
|
||||
type: boolean
|
||||
default: true
|
||||
description: 是否公开
|
||||
required_level:
|
||||
type: integer
|
||||
description: 所需用户等级
|
||||
status:
|
||||
type: string
|
||||
enum: [draft, active, inactive]
|
||||
default: draft
|
||||
|
||||
TrainingSceneUpdate:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
maxLength: 100
|
||||
description:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
maxLength: 50
|
||||
ai_config:
|
||||
type: object
|
||||
prompt_template:
|
||||
type: string
|
||||
evaluation_criteria:
|
||||
type: object
|
||||
status:
|
||||
type: string
|
||||
enum: [draft, active, inactive]
|
||||
is_public:
|
||||
type: boolean
|
||||
required_level:
|
||||
type: integer
|
||||
|
||||
TrainingScene:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
ai_config:
|
||||
type: object
|
||||
prompt_template:
|
||||
type: string
|
||||
evaluation_criteria:
|
||||
type: object
|
||||
status:
|
||||
type: string
|
||||
enum: [draft, active, inactive]
|
||||
is_public:
|
||||
type: boolean
|
||||
required_level:
|
||||
type: integer
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
TrainingSceneResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TrainingScene'
|
||||
|
||||
PaginatedScenesResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TrainingScene'
|
||||
total:
|
||||
type: integer
|
||||
page:
|
||||
type: integer
|
||||
page_size:
|
||||
type: integer
|
||||
pages:
|
||||
type: integer
|
||||
|
||||
StartTrainingRequest:
|
||||
type: object
|
||||
required:
|
||||
- scene_id
|
||||
properties:
|
||||
scene_id:
|
||||
type: integer
|
||||
description: 场景ID
|
||||
config:
|
||||
type: object
|
||||
description: 会话配置
|
||||
|
||||
StartTrainingResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
session_id:
|
||||
type: integer
|
||||
coze_conversation_id:
|
||||
type: string
|
||||
scene:
|
||||
$ref: '#/components/schemas/TrainingScene'
|
||||
websocket_url:
|
||||
type: string
|
||||
|
||||
EndTrainingRequest:
|
||||
type: object
|
||||
properties:
|
||||
generate_report:
|
||||
type: boolean
|
||||
default: true
|
||||
description: 是否生成报告
|
||||
|
||||
EndTrainingResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
session:
|
||||
$ref: '#/components/schemas/TrainingSession'
|
||||
report:
|
||||
$ref: '#/components/schemas/TrainingReport'
|
||||
|
||||
TrainingSession:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
user_id:
|
||||
type: integer
|
||||
scene_id:
|
||||
type: integer
|
||||
coze_conversation_id:
|
||||
type: string
|
||||
start_time:
|
||||
type: string
|
||||
format: date-time
|
||||
end_time:
|
||||
type: string
|
||||
format: date-time
|
||||
duration_seconds:
|
||||
type: integer
|
||||
status:
|
||||
type: string
|
||||
enum: [created, in_progress, completed, cancelled, error]
|
||||
session_config:
|
||||
type: object
|
||||
total_score:
|
||||
type: number
|
||||
evaluation_result:
|
||||
type: object
|
||||
scene:
|
||||
$ref: '#/components/schemas/TrainingScene'
|
||||
message_count:
|
||||
type: integer
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
TrainingSessionResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TrainingSession'
|
||||
|
||||
PaginatedSessionsResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TrainingSession'
|
||||
total:
|
||||
type: integer
|
||||
page:
|
||||
type: integer
|
||||
page_size:
|
||||
type: integer
|
||||
pages:
|
||||
type: integer
|
||||
|
||||
TrainingMessage:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
session_id:
|
||||
type: integer
|
||||
role:
|
||||
type: string
|
||||
enum: [user, assistant, system]
|
||||
type:
|
||||
type: string
|
||||
enum: [text, voice, system]
|
||||
content:
|
||||
type: string
|
||||
voice_url:
|
||||
type: string
|
||||
voice_duration:
|
||||
type: number
|
||||
metadata:
|
||||
type: object
|
||||
coze_message_id:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
TrainingReport:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
session_id:
|
||||
type: integer
|
||||
user_id:
|
||||
type: integer
|
||||
overall_score:
|
||||
type: number
|
||||
dimension_scores:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: number
|
||||
strengths:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
weaknesses:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
suggestions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
detailed_analysis:
|
||||
type: string
|
||||
transcript:
|
||||
type: string
|
||||
statistics:
|
||||
type: object
|
||||
session:
|
||||
$ref: '#/components/schemas/TrainingSession'
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
TrainingReportResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TrainingReport'
|
||||
|
||||
PaginatedReportsResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BaseResponse'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TrainingReport'
|
||||
total:
|
||||
type: integer
|
||||
page:
|
||||
type: integer
|
||||
page_size:
|
||||
type: integer
|
||||
pages:
|
||||
type: integer
|
||||
Reference in New Issue
Block a user