openapi: 3.0.3
info:
  title: AI Desa+ API
  description: API for the AI Desa+ management system, providing endpoints for managing announcements, banners, calendar events, discussions, divisions, documents, groups, positions, projects, tasks, users, and division reports.
  version: 1.0.0
  contact:
    name: API Support
    email: support@desa-plus.com

servers:
  - url: http://localhost:3000/api/ai
    description: Development server
  - url: https://api.desa-plus.com/api/ai
    description: Production server

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

  schemas:
    BaseResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          description: Indicates whether the request was successful
        message:
          type: string
          description: Response message or error description

    # Village
    VillageListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                properties:
                  id:
                    type: string
                    description: Unique identifier for the village
                  name:
                    type: string
                    description: Name of the village
                  isActive:
                    type: boolean
                    description: Indicates whether the village is active
                  createdAt:
                    type: string
                    format: date-time
                    description: Timestamp when the village was created
                  updatedAt:
                    type: string
                    format: date-time
                    description: Timestamp when the village was last updatedØ

    # Banner
    BannerBase:
      type: object
      required:
        - id
        - idVillage
        - title
        - image
        - isActive
      properties:
        id:
          type: string
          description: Unique identifier for the banner
        idVillage:
          type: string
          description: ID of the village associated with the banner
        title:
          type: string
          description: Title of the banner
        image:
          type: string
          description: URL or path to the banner image
        extension:
          type: string
          description: File extension of the banner image (e.g., jpg, png)
          nullable: true
        isActive:
          type: boolean
          description: Indicates whether the banner is active
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the banner was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the banner was last updated

    BannerListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/BannerBase"
              description: List of banners

    BannerDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/BannerBase"
              description: Details of a specific banner

    # Announcement
    AnnouncementBase:
      type: object
      required:
        - id
        - idVillage
        - title
        - desc
        - isActive
      properties:
        id:
          type: string
          description: Unique identifier for the announcement
        idVillage:
          type: string
          description: ID of the village associated with the announcement
        title:
          type: string
          description: Title of the announcement
        desc:
          type: string
          description: Description or content of the announcement
        isActive:
          type: boolean
          description: Indicates whether the announcement is active
        createdBy:
          type: string
          description: ID of the user who created the announcement
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the announcement was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the announcement was last updated

    AnnouncementMember:
      type: object
      required:
        - idGroup
        - idDivision
      properties:
        idGroup:
          type: string
          description: ID of the group associated with the announcement
        idDivision:
          type: string
          description: ID of the division associated with the announcement
        group:
          type: string
          description: Name of the group
        division:
          type: string
          description: Name of the division

    AnnouncementListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/AnnouncementBase"
              description: List of announcements

    AnnouncementDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                id:
                  type: string
                  description: Unique identifier for the announcement
                title:
                  type: string
                  description: Title of the announcement
                desc:
                  type: string
                  description: Description or content of the announcement
                isActive:
                  type: boolean
                  description: Indicates whether the announcement is active
                createdBy:
                  type: string
                  description: ID of the user who created the announcement
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the announcement was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the announcement was last updated
                member:
                  type: array
                  items:
                    $ref: "#/components/schemas/AnnouncementMember"
                  description: List of members associated with the announcement
              description: Details of a specific announcement

    # Calendar
    CalendarBase:
      type: object
      required:
        - id
        - dateStart
        - title
        - isActive
      properties:
        id:
          type: string
          description: Unique identifier for the calendar event
        dateStart:
          type: string
          format: date-time
          description: Start date and time of the event
        timeStart:
          type: string
          description: Start time of the event (e.g., HH:MM)
          nullable: true
        timeEnd:
          type: string
          description: End time of the event (e.g., HH:MM)
          nullable: true
        title:
          type: string
          description: Title of the event
        desc:
          type: string
          description: Description of the event
          nullable: true
        createdBy:
          type: string
          description: ID of the user who created the event
        isActive:
          type: boolean
          description: Indicates whether the event is active
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the event was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the event was last updated

    CalendarMember:
      type: object
      required:
        - id
        - idUser
        - name
        - email
      properties:
        id:
          type: string
          description: Unique identifier for the member
        idUser:
          type: string
          description: ID of the user
        name:
          type: string
          description: Name of the user
        email:
          type: string
          description: Email of the user
        img:
          type: string
          description: URL or path to the user's image
          nullable: true

    CalendarListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/CalendarBase"
              description: List of calendar events

    CalendarDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                id:
                  type: string
                  description: Unique identifier for the event
                dateStart:
                  type: string
                  format: date-time
                  description: Start date and time of the event
                timeStart:
                  type: string
                  description: Start time of the event (e.g., HH:MM)
                  nullable: true
                timeEnd:
                  type: string
                  description: End time of the event (e.g., HH:MM)
                  nullable: true
                title:
                  type: string
                  description: Title of the event
                desc:
                  type: string
                  description: Description of the event
                  nullable: true
                linkMeet:
                  type: string
                  description: URL for the meeting (if applicable)
                  nullable: true
                repeatEventType:
                  type: string
                  description: Type of event repetition (e.g., daily, weekly)
                  nullable: true
                repeatValue:
                  type: integer
                  description: Number of repetitions or interval
                  nullable: true
                createdBy:
                  type: string
                  description: ID of the user who created the event
                isActive:
                  type: boolean
                  description: Indicates whether the event is active
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the event was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the event was last updated
                member:
                  type: array
                  items:
                    $ref: "#/components/schemas/CalendarMember"
                  description: List of members associated with the event
              description: Details of a specific calendar event

    # Discussion
    DiscussionBase:
      type: object
      required:
        - id
        - desc
        - idDivision
        - status
      properties:
        id:
          type: string
          description: Unique identifier for the discussion
        desc:
          type: string
          description: Description of the discussion
        idDivision:
          type: string
          description: ID of the division associated with the discussion
        division:
          type: string
          description: Name of the division
        status:
          type: string
          enum: [open, closed]
          description: Status of the discussion
        totalKomentar:
          type: integer
          description: Total number of comments in the discussion
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the discussion was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the discussion was last updated

    DiscussionComment:
      type: object
      required:
        - id
        - comment
        - username
      properties:
        id:
          type: string
          description: Unique identifier for the comment
        comment:
          type: string
          description: Content of the comment
        username:
          type: string
          description: Username of the commenter
        userimg:
          type: string
          description: URL or path to the commenter's image
          nullable: true
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the comment was created

    DiscussionListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/DiscussionBase"
              description: List of discussions

    DiscussionDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                id:
                  type: string
                  description: Unique identifier for the discussion
                idDivision:
                  type: string
                  description: ID of the division associated with the discussion
                division:
                  type: string
                  description: Name of the division
                desc:
                  type: string
                  description: Description of the discussion
                status:
                  type: string
                  enum: [open, closed]
                  description: Status of the discussion
                isActive:
                  type: boolean
                  description: Indicates whether the discussion is active
                createdBy:
                  type: string
                  description: ID of the user who created the discussion
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the discussion was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the discussion was last updated
                komentar:
                  type: array
                  items:
                    $ref: "#/components/schemas/DiscussionComment"
                  description: List of comments in the discussion
              description: Details of a specific discussion

    # Discussion General
    DiskusiUmumBase:
      type: object
      required:
        - id
        - title
        - desc
        - status
      properties:
        id:
          type: string
          description: Unique identifier for the general discussion
        title:
          type: string
          description: Title of the general discussion
        desc:
          type: string
          description: Description of the general discussion
        status:
          type: string
          enum: [open, closed]
          description: Status of the general discussion
        group:
          type: string
          description: Name of the group associated with the discussion
        totalKomentar:
          type: integer
          description: Total number of comments in the discussion
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the discussion was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the discussion was last updated

    DiskusiUmumListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/DiskusiUmumBase"
              description: List of general discussions

    DiskusiUmumDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              required:
                - id
                - title
                - desc
                - status
              properties:
                id:
                  type: string
                  description: Unique identifier for the general discussion
                idGroup:
                  type: string
                  description: ID of the group associated with the discussion
                group:
                  type: string
                  description: Name of the group
                title:
                  type: string
                  description: Title of the general discussion
                desc:
                  type: string
                  description: Description of the general discussion
                status:
                  type: string
                  enum: [open, closed]
                  description: Status of the general discussion
                isActive:
                  type: boolean
                  description: Indicates whether the discussion is active
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the discussion was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the discussion was last updated
              description: Details of a specific general discussion

    DiskusiUmumMemberResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                type: object
                required:
                  - idUser
                  - name
                properties:
                  idUser:
                    type: string
                    description: ID of the user
                  name:
                    type: string
                    description: Name of the user
                  img:
                    type: string
                    description: URL or path to the user's image
                    nullable: true
              description: List of members in the general discussion

    DiskusiUmumCommentResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                type: object
                required:
                  - id
                  - comment
                  - idUser
                  - username
                properties:
                  id:
                    type: string
                    description: Unique identifier for the comment
                  comment:
                    type: string
                    description: Content of the comment
                  idUser:
                    type: string
                    description: ID of the user who made the comment
                  username:
                    type: string
                    description: Username of the commenter
                  img:
                    type: string
                    description: URL or path to the commenter's image
                    nullable: true
                  createdAt:
                    type: string
                    format: date-time
                    description: Timestamp when the comment was created
              description: List of comments in the general discussion

    # Division
    DivisiBase:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: string
          description: Unique identifier for the division
        name:
          type: string
          description: Name of the division
        desc:
          type: string
          description: Description of the division
          nullable: true
        idGroup:
          type: string
          description: ID of the group associated with the division
        group:
          type: string
          description: Name of the group
        jumlahMember:
          type: integer
          description: Number of members in the division

    DivisiListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/DivisiBase"
              description: List of divisions

    DivisiDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              required:
                - id
                - name
                - isActive
              properties:
                id:
                  type: string
                  description: Unique identifier for the division
                idVillage:
                  type: string
                  description: ID of the village associated with the division
                idGroup:
                  type: string
                  description: ID of the group associated with the division
                name:
                  type: string
                  description: Name of the division
                desc:
                  type: string
                  description: Description of the division
                  nullable: true
                isActive:
                  type: boolean
                  description: Indicates whether the division is active
                createdBy:
                  type: string
                  description: ID of the user who created the division
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the division was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the division was last updated
                member:
                  type: array
                  items:
                    type: object
                    required:
                      - id
                      - idUser
                      - name
                    properties:
                      id:
                        type: string
                        description: Unique identifier for the member
                      idUser:
                        type: string
                        description: ID of the user
                      name:
                        type: string
                        description: Name of the user
                      isAdmin:
                        type: boolean
                        description: Indicates whether the user is an admin
                      img:
                        type: string
                        description: URL or path to the user's image
                        nullable: true
                  description: List of members in the division
              description: Details of a specific division

    DivisiReportDokumenResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                gambar:
                  type: integer
                  description: Number of images in the division
                dokumen:
                  type: integer
                  description: Number of documents in the division
              description: Document report for the division

    DivisiReportEventResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                selesai:
                  type: integer
                  description: Number of completed events
                akan_datang:
                  type: integer
                  description: Number of upcoming events
              description: Event report for the division

    DivisiReportProgressResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                Segera:
                  type: string
                  description: Percentage of tasks in 'Segera' status
                Dikerjakan:
                  type: string
                  description: Percentage of tasks in 'Dikerjakan' status
                Selesai:
                  type: integer
                  description: Percentage of tasks in 'Selesai' status
                Dibatalkan:
                  type: string
                  description: Percentage of tasks in 'Dibatalkan' status
              description: Progress report for the division

    # Document
    DocumentItem:
      type: object
      required:
        - id
        - category
        - name
        - path
      properties:
        id:
          type: string
          description: Unique identifier for the document or folder
        category:
          type: string
          enum: [FILE, FOLDER]
          description: Type of item (file or folder)
        name:
          type: string
          description: Name of the document or folder
        extension:
          type: string
          description: File extension (e.g., pdf, docx)
          nullable: true
        idStorage:
          type: string
          description: ID of the storage location
          nullable: true
        path:
          type: string
          description: Path to the document or folder
        createdBy:
          type: string
          description: ID of the user who created the document or folder
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the document or folder was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the document or folder was last updated
        share:
          type: boolean
          description: Indicates whether the document or folder is shared

    DocumentListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/DocumentItem"
              description: List of documents and folders

    # Group
    GroupItem:
      type: object
      required:
        - id
        - idVillage
        - name
        - isActive
      properties:
        id:
          type: string
          description: Unique identifier for the group
        idVillage:
          type: string
          description: ID of the village associated with the group
        name:
          type: string
          description: Name of the group
        isActive:
          type: boolean
          description: Indicates whether the group is active
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the group was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the group was last updated

    GroupListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/GroupItem"
              description: List of groups

    # Position
    PositionItem:
      type: object
      required:
        - id
        - name
        - idGroup
        - isActive
      properties:
        id:
          type: string
          description: Unique identifier for the position
        name:
          type: string
          description: Name of the position
        idGroup:
          type: string
          description: ID of the group associated with the position
        group:
          type: string
          description: Name of the group
        isActive:
          type: boolean
          description: Indicates whether the position is active
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the position was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the position was last updated

    PositionListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/PositionItem"
              description: List of positions

    # Project
    ProjectBase:
      type: object
      required:
        - id
        - idGroup
        - title
        - status
      properties:
        id:
          type: string
          description: Unique identifier for the project
        idGroup:
          type: string
          description: ID of the group associated with the project
        title:
          type: string
          description: Title of the project
        desc:
          type: string
          description: Description of the project
          nullable: true
        group:
          type: string
          description: Name of the group
        status:
          type: string
          enum: [segera, dikerjakan, selesai, batal]
          description: Status of the project
        progress:
          type: integer
          description: Progress percentage of the project
        member:
          type: integer
          description: Number of members in the project

    BaseResponseProjectList:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/ProjectBase"
              description: List of projects

    BaseResponseProjectDetail:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              required:
                - id
                - idVillage
                - idGroup
                - title
                - status
                - isActive
              properties:
                id:
                  type: string
                  description: Unique identifier for the project
                idVillage:
                  type: string
                  description: ID of the village associated with the project
                idGroup:
                  type: string
                  description: ID of the group associated with the project
                group:
                  type: string
                  description: Name of the group
                title:
                  type: string
                  description: Title of the project
                status:
                  type: string
                  enum: [segera, dikerjakan, selesai, batal]
                  description: Status of the project
                desc:
                  type: string
                  description: Description of the project
                  nullable: true
                reason:
                  type: string
                  description: Reason for project status (e.g., cancellation)
                  nullable: true
                report:
                  type: string
                  description: Project report or summary
                  nullable: true
                isActive:
                  type: boolean
                  description: Indicates whether the project is active
                progress:
                  type: integer
                  description: Progress percentage of the project
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the project was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the project was last updated
              description: Details of a specific project

    # Task
    TaskBase:
      type: object
      required:
        - id
        - idDivision
        - title
        - status
      properties:
        id:
          type: string
          description: Unique identifier for the task
        idDivision:
          type: string
          description: ID of the division associated with the task
        title:
          type: string
          description: Title of the task
        desc:
          type: string
          description: Description of the task
          nullable: true
        division:
          type: string
          description: Name of the division
        status:
          type: string
          enum: [segera, dikerjakan, selesai, batal]
          description: Status of the task
        progress:
          type: integer
          description: Progress percentage of the task
        member:
          type: integer
          description: Number of members assigned to the task

    BaseResponseTaskList:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/TaskBase"
              description: List of tasks

    BaseResponseTaskDetail:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              required:
                - id
                - idDivision
                - title
                - status
                - isActive
              properties:
                id:
                  type: string
                  description: Unique identifier for the task
                idDivision:
                  type: string
                  description: ID of the division associated with the task
                division:
                  type: string
                  description: Name of the division
                title:
                  type: string
                  description: Title of the task
                status:
                  type: string
                  enum: [segera, dikerjakan, selesai, batal]
                  description: Status of the task
                desc:
                  type: string
                  description: Description of the task
                  nullable: true
                reason:
                  type: string
                  description: Reason for task status (e.g., cancellation)
                  nullable: true
                report:
                  type: string
                  description: Task report or summary
                  nullable: true
                isActive:
                  type: boolean
                  description: Indicates whether the task is active
                progress:
                  type: integer
                  description: Progress percentage of the task
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the task was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the task was last updated
              description: Details of a specific task

    BaseResponseSubTaskList:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                type: object
                required:
                  - id
                  - title
                  - status
                properties:
                  id:
                    type: string
                    description: Unique identifier for the subtask
                  title:
                    type: string
                    description: Title of the subtask
                  status:
                    type: string
                    enum: [belum_selesai, selesai]
                    description: Status of the subtask
                  dateStart:
                    type: string
                    format: date-time
                    description: Start date and time of the subtask
                  dateEnd:
                    type: string
                    format: date-time
                    description: End date and time of the subtask
              description: List of subtasks

    BaseResponseMemberList:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                type: object
                required:
                  - id
                  - idUser
                  - name
                  - email
                properties:
                  id:
                    type: string
                    description: Unique identifier for the member
                  idUser:
                    type: string
                    description: ID of the user
                  name:
                    type: string
                    description: Name of the user
                  email:
                    type: string
                    description: Email of the user
                  img:
                    type: string
                    description: URL or path to the user's image
                    nullable: true
                  position:
                    type: string
                    description: Position of the user
                    nullable: true
              description: List of members

    BaseResponseFileList:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/DocumentItem"
              description: List of files

    BaseResponseLinkList:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                type: object
                required:
                  - id
                  - idProject
                  - link
                  - isActive
                properties:
                  id:
                    type: string
                    description: Unique identifier for the link
                  idProject:
                    type: string
                    description: ID of the project associated with the link
                  link:
                    type: string
                    description: URL of the link
                  isActive:
                    type: boolean
                    description: Indicates whether the link is active
                  createdAt:
                    type: string
                    format: date-time
                    description: Timestamp when the link was created
                  updatedAt:
                    type: string
                    format: date-time
                    description: Timestamp when the link was last updated
              description: List of links

    # User
    UserBase:
      type: object
      required:
        - id
        - idUserRole
        - nik
        - name
        - gender
        - phone
        - isActive
      properties:
        id:
          type: string
          description: Unique identifier for the user
        idUserRole:
          type: string
          description: ID of the user's role
        nik:
          type: string
          description: National identification number of the user
        name:
          type: string
          description: Name of the user
        gender:
          type: string
          description: Gender of the user
        phone:
          type: string
          description: Phone number of the user
        position:
          type: string
          description: Position of the user
          nullable: true
        group:
          type: string
          description: Name of the group the user belongs to
          nullable: true
        isActive:
          type: boolean
          description: Indicates whether the user is active

    UserListResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/UserBase"
              description: List of users

    UserDetailResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              type: object
              required:
                - id
                - idUserRole
                - nik
                - name
                - phone
                - email
                - gender
                - isActive
              properties:
                id:
                  type: string
                  description: Unique identifier for the user
                idUserRole:
                  type: string
                  description: ID of the user's role
                nik:
                  type: string
                  description: National identification number of the user
                name:
                  type: string
                  description: Name of the user
                email:
                  type: string
                  description: Email of the user
                gender:
                  type: string
                  description: Gender of the user
                phone:
                  type: string
                  description: Phone number of the user
                img:
                  type: string
                  description: URL or path to the user's image
                  nullable: true
                idGroup:
                  type: string
                  description: ID of the group the user belongs to
                  nullable: true
                idPosition:
                  type: string
                  description: ID of the user's position
                  nullable: true
                role:
                  type: string
                  description: Role of the user
                  nullable: true
                position:
                  type: string
                  description: Position of the user
                  nullable: true
                group:
                  type: string
                  description: Name of the group the user belongs to
                  nullable: true
                isActive:
                  type: boolean
                  description: Indicates whether the user is active
                createdAt:
                  type: string
                  format: date-time
                  description: Timestamp when the user was created
                updatedAt:
                  type: string
                  format: date-time
                  description: Timestamp when the user was last updated
              description: Details of a specific user

paths:
  # Village
  /village:
    get:
      tags:
        - Village
      summary: Get list of villages
      description: Retrieves a paginated list of villages filtered by search term and active status
      parameters:
        - name: search
          in: query
          description: Search term for village name
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of villages
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/VillageListResponse"

  # Announcement
  /announcement:
    get:
      tags:
        - Announcement
      summary: Get list of announcements
      description: Retrieves a paginated list of announcements filtered by village, search term, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: search
          in: query
          description: Search term for announcement title or description
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
      responses:
        "200":
          description: List of announcements
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnnouncementListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /announcement/{id}:
    get:
      tags:
        - Announcement
      summary: Get announcement details
      description: Retrieves details of a specific announcement
      parameters:
        - name: id
          in: path
          required: true
          description: Announcement ID
          schema:
            type: string
      responses:
        "200":
          description: Announcement details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnnouncementDetailResponse"
        "404":
          description: Announcement not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Banner
  /banner:
    get:
      tags:
        - Banner
      summary: Get list of banners
      description: Retrieves a paginated list of banners filtered by village, search term, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: search
          in: query
          description: Search term for banner title
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
      responses:
        "200":
          description: List of banners
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BannerListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /banner/{id}:
    get:
      tags:
        - Banner
      summary: Get banner details
      description: Retrieves details of a specific banner
      parameters:
        - name: id
          in: path
          required: true
          description: Banner ID
          schema:
            type: string
      responses:
        "200":
          description: Banner details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BannerDetailResponse"
        "404":
          description: Banner not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Calendar
  /calendar:
    get:
      tags:
        - Calendar
      summary: Get calendar events
      description: Retrieves a paginated list of calendar events filtered by village, date, division, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: date
          in: query
          description: Filter by event date
          schema:
            type: string
            format: date
            nullable: true
        - name: division
          in: query
          description: Filter by division ID
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: search
          in: query
          description: Search term for event title or description
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of calendar events
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CalendarListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /calendar/{id}:
    get:
      tags:
        - Calendar
      summary: Get calendar event details
      description: Retrieves details of a specific calendar event
      parameters:
        - name: id
          in: path
          required: true
          description: Event ID
          schema:
            type: string
      responses:
        "200":
          description: Event details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CalendarDetailResponse"
        "404":
          description: Event not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Discussion
  /discussion:
    get:
      tags:
        - Discussion
      summary: Get division discussions
      description: Retrieves a paginated list of discussions filtered by village, division, status, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: division
          in: query
          description: Filter by division ID
          schema:
            type: string
            nullable: true
        - name: status
          in: query
          description: Filter by discussion status
          schema:
            type: string
            enum: [open, closed]
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: search
          in: query
          description: Search term for discussion description
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of discussions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DiscussionListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /discussion/{id}:
    get:
      tags:
        - Discussion
      summary: Get division discussion details
      description: Retrieves details of a specific division discussion
      parameters:
        - name: id
          in: path
          required: true
          description: Discussion ID
          schema:
            type: string
      responses:
        "200":
          description: Discussion details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DiscussionDetailResponse"
        "404":
          description: Discussion not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Discussion General
  /discussion-general:
    get:
      tags:
        - DiscussionGeneral
      summary: Get general discussions
      description: Retrieves a paginated list of general discussions filtered by village, group, status, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: group
          in: query
          description: Filter by group ID
          schema:
            type: string
            nullable: true
        - name: search
          in: query
          description: Search term for discussion title or description
          schema:
            type: string
            nullable: true
        - name: status
          in: query
          description: Filter by discussion status
          schema:
            type: string
            enum: [open, closed]
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of general discussions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DiskusiUmumListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /discussion-general/{id}:
    get:
      tags:
        - DiscussionGeneral
      summary: Get general discussion details
      description: Retrieves details of a specific general discussion, including members or comments based on category
      parameters:
        - name: id
          in: path
          required: true
          description: Discussion ID
          schema:
            type: string
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: cat
          in: query
          description: Category of data to retrieve (detail, member, or comment)
          schema:
            type: string
            enum: [detail, member, comment]
            nullable: true
      responses:
        "200":
          description: Discussion details, members, or comments
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/DiskusiUmumDetailResponse"
                  - $ref: "#/components/schemas/DiskusiUmumMemberResponse"
                  - $ref: "#/components/schemas/DiskusiUmumCommentResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "404":
          description: Discussion not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Division
  /division:
    get:
      tags:
        - Division
      summary: Get divisions
      description: Retrieves a paginated list of divisions filtered by village, group, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: group
          in: query
          description: Filter by group ID
          schema:
            type: string
            nullable: true
        - name: search
          in: query
          description: Search term for division name or description
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of divisions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DivisiListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /division/{id}:
    get:
      tags:
        - Division
      summary: Get division details
      description: Retrieves details of a specific division
      parameters:
        - name: id
          in: path
          required: true
          description: Division ID
          schema:
            type: string
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
      responses:
        "200":
          description: Division details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DivisiDetailResponse"
        "404":
          description: Division not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /division/report:
    get:
      tags:
        - Division
      summary: Get division reports
      description: Retrieves reports for a specific division based on category (dokumen, event, or progress)
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: cat
          in: query
          required: true
          description: Category of report to retrieve (dokumen, event, or progress)
          schema:
            type: string
            enum: [dokumen, event, progress]
        - name: group
          in: query
          description: Group ID
          schema:
            type: string
            nullable: true
        - name: division
          in: query
          description: Division ID
          schema:
            type: string
            nullable: true
        - name: date-start
          in: query
          required: true
          description: Start date for filtering
          schema:
            type: string
            format: date
        - name: date-end
          in: query
          required: true
          description: End date for filtering
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Division report data
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/DivisiReportDokumenResponse"
                  - $ref: "#/components/schemas/DivisiReportEventResponse"
                  - $ref: "#/components/schemas/DivisiReportProgressResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "404":
          description: Division not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Document
  /document:
    get:
      tags:
        - Document
      summary: Get documents
      description: Retrieves a paginated list of documents and folders filtered by village, division, path, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: division
          in: query
          description: Filter by division ID
          schema:
            type: string
            nullable: true
        - name: path
          in: query
          description: Filter by document path
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: search
          in: query
          description: Search term for document name
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of documents and folders
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Group
  /group:
    get:
      tags:
        - Group
      summary: Get groups
      description: Retrieves a paginated list of groups filtered by village, search term, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: search
          in: query
          description: Search term for group name
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of groups
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GroupListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Position
  /position:
    get:
      tags:
        - Position
      summary: Get positions
      description: Retrieves a paginated list of positions filtered by village, group, search term, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: group
          in: query
          description: Filter by group ID
          schema:
            type: string
            nullable: true
        - name: search
          in: query
          description: Search term for position name
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of positions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PositionListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Project
  /project:
    get:
      tags:
        - Project
      summary: Get projects
      description: Retrieves a paginated list of projects filtered by village, group, status, and search term
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: group
          in: query
          description: Filter by group ID
          schema:
            type: string
            nullable: true
        - name: status
          in: query
          description: Filter by project status
          schema:
            type: string
            enum: [segera, dikerjakan, selesai, batal]
            nullable: true
        - name: search
          in: query
          description: Search term for project title or description
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of projects
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BaseResponseProjectList"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /project/{id}:
    get:
      tags:
        - Project
      summary: Get project details
      description: Retrieves details of a specific project based on category (data, task, file, member, or link)
      parameters:
        - name: id
          in: path
          required: true
          description: Project ID
          schema:
            type: string
        - name: cat
          in: query
          required: true
          description: Category of project data to retrieve
          schema:
            type: string
            enum: [data, task, file, member, link]
      responses:
        "200":
          description: Project details
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/BaseResponseProjectDetail"
                  - $ref: "#/components/schemas/BaseResponseTaskList"
                  - $ref: "#/components/schemas/BaseResponseFileList"
                  - $ref: "#/components/schemas/BaseResponseMemberList"
                  - $ref: "#/components/schemas/BaseResponseLinkList"
        "400":
          description: Bad request (e.g., invalid parameters)
        "404":
          description: Project not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # Task
  /task:
    get:
      tags:
        - Task
      summary: Get tasks
      description: Retrieves a paginated list of tasks filtered by village, division, status, and search term
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: division
          in: query
          description: Filter by division ID
          schema:
            type: string
            nullable: true
        - name: status
          in: query
          description: Filter by task status
          schema:
            type: string
            enum: [segera, dikerjakan, selesai, batal]
            nullable: true
        - name: search
          in: query
          description: Search term for task title or description
          schema:
            type: string
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of tasks
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BaseResponseTaskList"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /task/{id}:
    get:
      tags:
        - Task
      summary: Get task details
      description: Retrieves details of a specific task based on category (data, task, file, member, or link)
      parameters:
        - name: id
          in: path
          required: true
          description: Task ID
          schema:
            type: string
        - name: cat
          in: query
          required: true
          description: Category of task data to retrieve
          schema:
            type: string
            enum: [data, task, file, member, link]
      responses:
        "200":
          description: Task details
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/BaseResponseTaskDetail"
                  - $ref: "#/components/schemas/BaseResponseSubTaskList"
                  - $ref: "#/components/schemas/BaseResponseFileList"
                  - $ref: "#/components/schemas/BaseResponseMemberList"
                  - $ref: "#/components/schemas/BaseResponseLinkList"
        "400":
          description: Bad request (e.g., invalid parameters)
        "404":
          description: Task not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  # User
  /user:
    get:
      tags:
        - User
      summary: Get users
      description: Retrieves a paginated list of users filtered by village, group, search term, and active status
      parameters:
        - name: desa
          in: query
          required: true
          description: Village ID
          schema:
            type: string
        - name: group
          in: query
          description: Filter by group ID
          schema:
            type: string
            nullable: true
        - name: search
          in: query
          description: Search term for user name
          schema:
            type: string
            nullable: true
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
            nullable: true
        - name: page
          in: query
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: get
          in: query
          description: Number of items per page
          schema:
            type: integer
            minimum: 1
            default: 10
      responses:
        "200":
          description: List of users
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserListResponse"
        "400":
          description: Bad request (e.g., invalid parameters)
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

  /user/{id}:
    get:
      tags:
        - User
      summary: Get user details
      description: Retrieves details of a specific user
      parameters:
        - name: id
          in: path
          required: true
          description: User ID
          schema:
            type: string
      responses:
        "200":
          description: User details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserDetailResponse"
        "404":
          description: User not found
        "401":
          description: Unauthorized (invalid or missing token)
        "500":
          description: Internal server error

security:
  - bearerAuth: []

tags:
  - name: Village
    description: Operations related to village management
  - name: Announcement
    description: Operations related to announcements
  - name: Banner
    description: Operations related to banner management
  - name: Calendar
    description: Operations related to calendar events
  - name: Discussion
    description: Operations related to division-specific discussions
  - name: DiscussionGeneral
    description: Operations related to general discussions
  - name: Division
    description: Operations related to division management and reports
  - name: Document
    description: Operations related to document and folder management
  - name: Group
    description: Operations related to group management
  - name: Position
    description: Operations related to position management
  - name: Project
    description: Operations related to project management
  - name: Task
    description: Operations related to task management
  - name: User
    description: Operations related to user managementØ
