openapi: 3.0.0
info:
  title: 考试模块 API
  version: 1.0.0
  description: 考培练系统考试模块的 API 接口定义

servers:
  - url: http://localhost:8000/api/v1
    description: 本地开发服务器

paths:
  /exams/start:
    post:
      summary: 开始考试（动态组卷）
      description: 根据指定参数动态生成试卷并开始考试
      tags:
        - 考试管理
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExamStartRequest'
      responses:
        '200':
          description: 考试开始成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExamSessionResponse'
        '400':
          description: 请求参数错误或存在未完成的考试
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /exams/{examId}/submit:
    post:
      summary: 提交考试
      description: 提交考试答案并生成成绩
      tags:
        - 考试管理
      security:
        - bearerAuth: []
      parameters:
        - name: examId
          in: path
          required: true
          schema:
            type: integer
          description: 考试ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExamSubmitRequest'
      responses:
        '200':
          description: 考试提交成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExamResultResponse'
        '400':
          description: 考试状态不正确或已超时
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          description: 无权访问此考试
        '404':
          description: 考试不存在

  /exams/{examId}:
    get:
      summary: 获取考试详情
      description: 获取考试会话信息和题目列表（不包含答案）
      tags:
        - 考试管理
      security:
        - bearerAuth: []
      parameters:
        - name: examId
          in: path
          required: true
          schema:
            type: integer
          description: 考试ID
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExamSessionResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          description: 考试不存在

  /exams/records:
    get:
      summary: 获取考试记录列表
      description: 分页获取用户的考试记录
      tags:
        - 考试管理
      security:
        - bearerAuth: []
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            minimum: 1
            default: 1
          description: 页码
        - name: page_size
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          description: 每页数量
        - name: status
          in: query
          schema:
            $ref: '#/components/schemas/ExamStatus'
          description: 考试状态筛选
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExamRecordListResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /exams/{examId}/result:
    get:
      summary: 获取考试结果
      description: 获取详细的考试成绩、统计信息和答案详情
      tags:
        - 考试管理
      security:
        - bearerAuth: []
      parameters:
        - name: examId
          in: path
          required: true
          schema:
            type: integer
          description: 考试ID
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExamResultResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          description: 考试结果不存在

  /exams/mistakes:
    get:
      summary: 获取错题列表
      description: 分页获取用户的错题记录
      tags:
        - 错题管理
      security:
        - bearerAuth: []
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            minimum: 1
            default: 1
          description: 页码
        - name: page_size
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          description: 每页数量
        - name: is_mastered
          in: query
          schema:
            type: boolean
          description: 是否已掌握
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MistakeListResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    ExamStartRequest:
      type: object
      required:
        - exam_name
      properties:
        course_id:
          type: integer
          description: 课程ID
        exam_name:
          type: string
          description: 考试名称
        question_count:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
          description: 题目数量
        time_limit:
          type: integer
          minimum: 1
          maximum: 300
          description: 考试时长（分钟）
        difficulty:
          type: integer
          minimum: 1
          maximum: 5
          description: 难度等级
        knowledge_points:
          type: array
          items:
            type: string
          description: 知识点范围
        question_types:
          type: array
          items:
            $ref: '#/components/schemas/QuestionType'
          description: 题型范围

    ExamSubmitRequest:
      type: object
      required:
        - answers
      properties:
        answers:
          type: array
          items:
            $ref: '#/components/schemas/AnswerSubmitRequest'
          description: 答案列表
        force_submit:
          type: boolean
          default: false
          description: 是否强制提交

    AnswerSubmitRequest:
      type: object
      required:
        - question_id
        - user_answer
      properties:
        question_id:
          type: integer
          description: 题目ID
        user_answer:
          type: string
          description: 用户答案
        time_spent:
          type: integer
          minimum: 0
          description: 答题用时（秒）

    ExamStatus:
      type: string
      enum:
        - created
        - in_progress
        - submitted
        - graded
        - expired
      description: 考试状态

    QuestionType:
      type: string
      enum:
        - single_choice
        - multiple_choice
        - true_false
        - fill_blank
        - short_answer
        - essay
      description: 题目类型

    ExamSessionResponse:
      type: object
      properties:
        code:
          type: integer
          example: 200
        message:
          type: string
          example: success
        data:
          type: object
          properties:
            id:
              type: integer
            exam_name:
              type: string
            course_id:
              type: integer
            total_questions:
              type: integer
            total_score:
              type: number
            pass_score:
              type: number
            time_limit:
              type: integer
            status:
              $ref: '#/components/schemas/ExamStatus'
            started_at:
              type: string
              format: date-time
            submitted_at:
              type: string
              format: date-time
            questions:
              type: array
              items:
                $ref: '#/components/schemas/QuestionResponse'

    QuestionResponse:
      type: object
      properties:
        id:
          type: integer
        question_order:
          type: integer
        question_type:
          $ref: '#/components/schemas/QuestionType'
        question_text:
          type: string
        options:
          type: object
          additionalProperties:
            type: string
        score:
          type: number
        knowledge_points:
          type: array
          items:
            type: string
        difficulty:
          type: integer

    ExamResultResponse:
      type: object
      properties:
        code:
          type: integer
          example: 200
        message:
          type: string
          example: success
        data:
          type: object
          properties:
            id:
              type: integer
            exam_id:
              type: integer
            exam_name:
              type: string
            total_score:
              type: number
            actual_score:
              type: number
            percentage_score:
              type: number
            is_passed:
              type: boolean
            total_questions:
              type: integer
            answered_questions:
              type: integer
            correct_questions:
              type: integer
            question_type_stats:
              type: object
            knowledge_stats:
              type: object
            total_time_spent:
              type: integer
            average_time_per_question:
              type: number
            ai_analysis:
              type: string
            improvement_suggestions:
              type: array
              items:
                type: string
            answer_details:
              type: array
              items:
                $ref: '#/components/schemas/AnswerDetailResponse'

    AnswerDetailResponse:
      type: object
      properties:
        question_id:
          type: integer
        question_order:
          type: integer
        question_type:
          $ref: '#/components/schemas/QuestionType'
        question_text:
          type: string
        user_answer:
          type: string
        correct_answer:
          type: string
        is_correct:
          type: boolean
        actual_score:
          type: number
        total_score:
          type: number
        answer_explanation:
          type: string
        ai_feedback:
          type: string

    ExamRecordListResponse:
      type: object
      properties:
        code:
          type: integer
          example: 200
        message:
          type: string
          example: success
        data:
          type: object
          properties:
            items:
              type: array
              items:
                $ref: '#/components/schemas/ExamRecordResponse'
            total:
              type: integer
            page:
              type: integer
            page_size:
              type: integer
            total_pages:
              type: integer

    ExamRecordResponse:
      type: object
      properties:
        id:
          type: integer
        exam_name:
          type: string
        course_id:
          type: integer
        course_name:
          type: string
        status:
          $ref: '#/components/schemas/ExamStatus'
        total_questions:
          type: integer
        actual_score:
          type: number
        percentage_score:
          type: number
        is_passed:
          type: boolean
        started_at:
          type: string
          format: date-time
        submitted_at:
          type: string
          format: date-time

    MistakeListResponse:
      type: object
      properties:
        code:
          type: integer
          example: 200
        message:
          type: string
          example: success
        data:
          type: object
          properties:
            items:
              type: array
              items:
                $ref: '#/components/schemas/MistakeResponse'
            total:
              type: integer
            page:
              type: integer
            page_size:
              type: integer
            total_pages:
              type: integer

    MistakeResponse:
      type: object
      properties:
        id:
          type: integer
        question_type:
          $ref: '#/components/schemas/QuestionType'
        question_text:
          type: string
        user_answer:
          type: string
        correct_answer:
          type: string
        knowledge_points:
          type: array
          items:
            type: string
        difficulty:
          type: integer
        review_count:
          type: integer
        is_mastered:
          type: boolean
        last_review_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time

    ErrorResponse:
      type: object
      properties:
        code:
          type: integer
        message:
          type: string
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: object

  responses:
    UnauthorizedError:
      description: 未授权，需要登录
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    
    InternalServerError:
      description: 服务器内部错误
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
