openapi: 3.0.0
info:
  title: 课程管理模块API契约
  description: 定义课程管理模块对外提供的所有API接口
  version: 1.0.0

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

paths:
  /courses:
    get:
      summary: 获取课程列表
      description: 支持分页和多条件筛选
      operationId: getCourses
      security:
        - bearerAuth: []
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: size
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: status
          in: query
          schema:
            type: string
            enum: [draft, published, archived]
        - name: category
          in: query
          schema:
            type: string
            enum: [technology, management, business, general]
        - name: is_featured
          in: query
          schema:
            type: boolean
        - name: keyword
          in: query
          schema:
            type: string
      responses:
        "200":
          description: 成功获取课程列表
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CoursePageResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"

    post:
      summary: 创建课程
      description: 创建新课程（需要管理员权限）
      operationId: createCourse
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CourseCreate"
      responses:
        "201":
          description: 成功创建课程
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CourseResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/ForbiddenError"
        "409":
          $ref: "#/components/responses/ConflictError"

  /courses/{courseId}:
    get:
      summary: 获取课程详情
      operationId: getCourse
      security:
        - bearerAuth: []
      parameters:
        - name: courseId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 成功获取课程详情
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CourseResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"

    put:
      summary: 更新课程
      description: 更新课程信息（需要管理员权限）
      operationId: updateCourse
      security:
        - bearerAuth: []
      parameters:
        - name: courseId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CourseUpdate"
      responses:
        "200":
          description: 成功更新课程
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CourseResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/ForbiddenError"
        "404":
          $ref: "#/components/responses/NotFoundError"

    delete:
      summary: 删除课程
      description: 软删除课程（需要管理员权限）
      operationId: deleteCourse
      security:
        - bearerAuth: []
      parameters:
        - name: courseId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 成功删除课程
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeleteResponse"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "403":
          $ref: "#/components/responses/ForbiddenError"
        "404":
          $ref: "#/components/responses/NotFoundError"

  /courses/{courseId}/knowledge-points:
    get:
      summary: 获取课程知识点列表
      operationId: getCourseKnowledgePoints
      security:
        - bearerAuth: []
      parameters:
        - name: courseId
          in: path
          required: true
          schema:
            type: integer
        - name: parent_id
          in: query
          schema:
            type: integer
            nullable: true
      responses:
        "200":
          description: 成功获取知识点列表
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/KnowledgePointListResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"

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

  schemas:
    ResponseBase:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          default: 200
        message:
          type: string
        request_id:
          type: string
        timestamp:
          type: string
          format: date-time

    CourseBase:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
        category:
          type: string
          enum: [technology, management, business, general]
          default: general
        cover_image:
          type: string
          maxLength: 500
        duration_hours:
          type: number
          format: float
          minimum: 0
        difficulty_level:
          type: integer
          minimum: 1
          maximum: 5
        tags:
          type: array
          items:
            type: string
        sort_order:
          type: integer
          default: 0
        is_featured:
          type: boolean
          default: false

    CourseCreate:
      allOf:
        - $ref: "#/components/schemas/CourseBase"
        - type: object
          required:
            - name
          properties:
            status:
              type: string
              enum: [draft, published, archived]
              default: draft

    CourseUpdate:
      allOf:
        - $ref: "#/components/schemas/CourseBase"
        - type: object
          properties:
            status:
              type: string
              enum: [draft, published, archived]

    Course:
      allOf:
        - $ref: "#/components/schemas/CourseBase"
        - type: object
          required:
            - id
            - status
            - created_at
            - updated_at
          properties:
            id:
              type: integer
            status:
              type: string
              enum: [draft, published, archived]
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
            published_at:
              type: string
              format: date-time
              nullable: true
            publisher_id:
              type: integer
              nullable: true
            created_by:
              type: integer
              nullable: true
            updated_by:
              type: integer
              nullable: true

    CourseResponse:
      allOf:
        - $ref: "#/components/schemas/ResponseBase"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Course"

    CoursePageResponse:
      allOf:
        - $ref: "#/components/schemas/ResponseBase"
        - type: object
          properties:
            data:
              type: object
              required:
                - items
                - total
                - page
                - size
                - pages
              properties:
                items:
                  type: array
                  items:
                    $ref: "#/components/schemas/Course"
                total:
                  type: integer
                page:
                  type: integer
                size:
                  type: integer
                pages:
                  type: integer

    KnowledgePoint:
      type: object
      required:
        - id
        - course_id
        - name
        - level
        - created_at
        - updated_at
      properties:
        id:
          type: integer
        course_id:
          type: integer
        name:
          type: string
          maxLength: 200
        description:
          type: string
        parent_id:
          type: integer
          nullable: true
        level:
          type: integer
        path:
          type: string
          nullable: true
        sort_order:
          type: integer
        weight:
          type: number
          format: float
        is_required:
          type: boolean
        estimated_hours:
          type: number
          format: float
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    KnowledgePointListResponse:
      allOf:
        - $ref: "#/components/schemas/ResponseBase"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/KnowledgePoint"

    DeleteResponse:
      allOf:
        - $ref: "#/components/schemas/ResponseBase"
        - type: object
          properties:
            data:
              type: boolean

    ErrorDetail:
      type: object
      required:
        - message
      properties:
        message:
          type: string
        error_code:
          type: string
        field:
          type: string
        details:
          type: object

  responses:
    BadRequestError:
      description: 请求参数错误
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ResponseBase"
              - type: object
                properties:
                  code:
                    example: 400
                  detail:
                    $ref: "#/components/schemas/ErrorDetail"

    UnauthorizedError:
      description: 未认证
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ResponseBase"
              - type: object
                properties:
                  code:
                    example: 401
                  detail:
                    $ref: "#/components/schemas/ErrorDetail"

    ForbiddenError:
      description: 权限不足
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ResponseBase"
              - type: object
                properties:
                  code:
                    example: 403
                  detail:
                    $ref: "#/components/schemas/ErrorDetail"

    NotFoundError:
      description: 资源不存在
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ResponseBase"
              - type: object
                properties:
                  code:
                    example: 404
                  detail:
                    $ref: "#/components/schemas/ErrorDetail"

    ConflictError:
      description: 资源冲突
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ResponseBase"
              - type: object
                properties:
                  code:
                    example: 409
                  detail:
                    $ref: "#/components/schemas/ErrorDetail"
