openapi: 3.0.3 info: title: API AI Desa+ description: API untuk sistem manajemen AI Desa+ version: 1.0.0 contact: name: API Support email: support@desa-plus.com servers: - url: http://localhost:3000/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 message: type: string meta: type: object properties: total: type: integer page: type: integer perPage: type: integer # Banner BannerBase: type: object required: - id - idVillage - title - image - isActive properties: id: type: string idVillage: type: string title: type: string extension: type: string image: type: string isActive: type: boolean createdAt: type: string format: date-time updatedAt: type: string format: date-time BannerListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/BannerBase' BannerDetailResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: $ref: '#/components/schemas/BannerBase' # Announcement AnnouncementBase: type: object required: - id - idVillage - title - desc - isActive properties: id: type: string idVillage: type: string title: type: string desc: type: string isActive: type: boolean createdBy: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time AnnouncementMember: type: object required: - idGroup - idDivision properties: idGroup: type: string idDivision: type: string group: type: string division: type: string AnnouncementListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/AnnouncementBase' AnnouncementDetailResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: id: type: string title: type: string desc: type: string member: type: array items: $ref: '#/components/schemas/AnnouncementMember' # Calendar CalendarBase: type: object required: - id - dateStart - title - isActive properties: id: type: string dateStart: type: string format: date-time timeStart: type: string timeEnd: type: string createdAt: type: string format: date-time title: type: string desc: type: string createdBy: type: string isActive: type: boolean CalendarMember: type: object required: - id - idUser - name - email properties: id: type: string idUser: type: string name: type: string email: type: string img: type: string nullable: true CalendarListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/CalendarBase' CalendarDetailResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: id: type: string timeStart: type: string dateStart: type: string format: date-time timeEnd: type: string createdAt: type: string format: date-time title: type: string desc: type: string linkMeet: type: string repeatEventType: type: string repeatValue: type: integer member: type: array items: $ref: '#/components/schemas/CalendarMember' # Discussion DiscussionBase: type: object required: - id - desc - idDivision - status properties: id: type: string desc: type: string createdAt: type: string format: date-time idDivision: type: string division: type: string totalKomentar: type: integer status: type: string enum: [open, close] DiscussionComment: type: object required: - id - comment - username properties: id: type: string comment: type: string createdAt: type: string format: date-time username: type: string userimg: type: string nullable: true DiscussionListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/DiscussionBase' DiscussionDetailResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object properties: id: type: string idDivision: type: string division: type: string isActive: type: boolean desc: type: string status: type: string enum: [open, close] createdAt: type: string format: date-time createdBy: type: string komentar: type: array items: $ref: '#/components/schemas/DiscussionComment' # Discussion General DiskusiUmumListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - title - desc - status properties: id: type: string title: type: string desc: type: string createdAt: type: string format: date-time totalKomentar: type: integer status: type: string enum: [open, close] group: type: string DiskusiUmumDetailResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object required: - id - title - desc - status properties: id: type: string isActive: type: boolean idGroup: type: string group: type: string title: type: string desc: type: string status: type: string enum: [open, close] createdAt: type: string format: date-time DiskusiUmumMemberResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - idUser - name properties: idUser: type: string name: type: string img: type: string nullable: true DiskusiUmumCommentResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - comment - idUser - username properties: id: type: string comment: type: string createdAt: type: string format: date-time idUser: type: string username: type: string img: type: string nullable: true # Division DivisiListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - name properties: id: type: string name: type: string desc: type: string idGroup: type: string group: type: string jumlahMember: type: integer DivisiDetailResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object required: - id - name - isActive properties: id: type: string idVillage: type: string idGroup: type: string name: type: string desc: type: string isActive: type: boolean createdBy: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time member: type: array items: type: object required: - id - idUser - name properties: id: type: string isAdmin: type: boolean idUser: type: string name: type: string img: type: string nullable: true # Document DocumentItem: type: object required: - id - category - name - path properties: id: type: string category: type: string enum: [FILE, FOLDER] name: type: string extension: type: string idStorage: type: string nullable: true path: type: string createdBy: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time share: type: boolean DocumentListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/DocumentItem' # Group GroupItem: type: object required: - id - idVillage - name - isActive properties: id: type: string idVillage: type: string name: type: string isActive: type: boolean createdAt: type: string format: date-time updatedAt: type: string format: date-time GroupListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/GroupItem' # Position PositionItem: type: object required: - id - name - idGroup - isActive properties: id: type: string name: type: string idGroup: type: string group: type: string isActive: type: boolean createdAt: type: string format: date-time updatedAt: type: string format: date-time PositionListResponse: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/PositionItem' # Project BaseResponseProjectList: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - idGroup - title - status properties: id: type: string idGroup: type: string title: type: string desc: type: string nullable: true group: type: string status: type: string enum: [segera, dikerjakan, selesai, batal] progress: type: integer member: type: integer BaseResponseProjectDetail: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object required: - id - idVillage - idGroup - title - status - isActive properties: id: type: string idVillage: type: string idGroup: type: string group: type: string title: type: string status: type: string enum: [segera, dikerjakan, selesai, batal] desc: type: string nullable: true reason: type: string nullable: true report: type: string nullable: true isActive: type: boolean progress: type: integer BaseResponseTaskList: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - idDivision - title - status properties: id: type: string idDivision: type: string title: type: string desc: type: string nullable: true division: type: string status: type: string enum: [segera, dikerjakan, selesai, batal] progress: type: integer member: type: integer BaseResponseTaskDetail: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: object required: - id - idDivision - title - status - isActive properties: id: type: string idDivision: type: string division: type: string title: type: string status: type: string desc: type: string nullable: true reason: type: string nullable: true report: type: string nullable: true isActive: type: boolean progress: type: integer BaseResponseSubTaskList: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - title - status properties: id: type: string title: type: string status: type: string enum: [belum selesai, selesai] dateStart: type: string format: date-time dateEnd: type: string format: date-time BaseResponseMemberList: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - idUser - name - email properties: id: type: string idUser: type: string name: type: string email: type: string img: type: string nullable: true position: type: string BaseResponseFileList: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - name - path properties: id: type: string name: type: string extension: type: string idStorage: type: string nullable: true path: type: string createdBy: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time share: type: boolean BaseResponseLinkList: allOf: - $ref: '#/components/schemas/BaseResponse' - type: object properties: data: type: array items: type: object required: - id - idProject - link - isActive properties: id: type: string idProject: type: string link: type: string isActive: type: boolean createdAt: type: string format: date-time updatedAt: type: string format: date-time paths: # Announcement /announcement: get: tags: - Announcement summary: Get list of announcements description: Retrieves a paginated list of announcements filtered by village 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 - 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 responses: '200': description: List of announcements content: application/json: schema: $ref: '#/components/schemas/AnnouncementListResponse' /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' # Banner /banner: get: tags: - Banner summary: Get list of banners description: Retrieves a paginated list of banners filtered by village 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 - 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 responses: '200': description: List of banners content: application/json: schema: $ref: '#/components/schemas/BannerListResponse' /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' # Calendar /calendar: get: tags: - Calendar summary: Get calendar events description: Retrieves a paginated list of calendar events filtered by village, date, and division 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 - name: division in: query description: Filter by division ID schema: type: string - name: active in: query description: Filter by active status schema: type: boolean - name: search in: query description: Search term for event title or description schema: type: string - 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' /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' # Discussion /discussion: get: tags: - Discussion summary: Get division discussions description: Retrieves a paginated list of discussions filtered by village and division 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 - name: status in: query description: Filter by discussion status schema: type: string enum: [open, close] - name: active in: query description: Filter by active status schema: type: boolean - name: search in: query description: Search term for discussion description schema: type: string - 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' /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' # Discussion General /discussion-general: get: tags: - DiscussionGeneral summary: Get general discussions description: Retrieves a paginated list of general discussions filtered by village and group 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 - name: search in: query description: Search term for discussion title or description schema: type: string - name: status in: query description: Filter by discussion status schema: type: string enum: [open, close] - name: active in: query description: Filter by active status schema: type: boolean - 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' /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 schema: type: string enum: [detail, member, comment] responses: '200': description: Discussion details content: application/json: schema: oneOf: - $ref: '#/components/schemas/DiskusiUmumDetailResponse' - $ref: '#/components/schemas/DiskusiUmumMemberResponse' - $ref: '#/components/schemas/DiskusiUmumCommentResponse' # Division /division: get: tags: - Division summary: Get divisions description: Retrieves a paginated list of divisions filtered by village and group parameters: - name: desa in: query required: true description: Village ID schema: type: string - name: active in: query description: Filter by active status schema: type: boolean - name: group in: query description: Filter by group ID schema: type: string - name: search in: query description: Search term for division name or description schema: type: string - 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' /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' # Document /document: get: tags: - Document summary: Get documents description: Retrieves a paginated list of documents and folders filtered by village and division 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 - name: path in: query description: Filter by document path schema: type: string - name: active in: query description: Filter by active status schema: type: boolean - name: search in: query description: Search term for document name schema: type: string - 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' # Group /group: get: tags: - Group summary: Get groups description: Retrieves a paginated list of groups filtered by village parameters: - name: desa in: query required: true description: Village ID schema: type: string - name: active in: query description: Filter by active status schema: type: boolean - name: search in: query description: Search term for group name schema: type: string - 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' # Position /position: get: tags: - Position summary: Get positions description: Retrieves a paginated list of positions filtered by village and group 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 - name: search in: query description: Search term for position name schema: type: string - name: active in: query description: Filter by active status schema: type: boolean - 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' # Project /project: get: tags: - Project summary: Get projects description: Retrieves a paginated list of projects filtered by village, group, and status parameters: - name: desa in: query required: true description: Village ID schema: type: string - name: status in: query description: Filter by project status schema: type: string enum: [segera, dikerjakan, selesai, batal] - name: group in: query description: Filter by group ID schema: type: string - name: search in: query description: Search term for project title or description schema: type: string - 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' /project/{id}: get: tags: - Project summary: Get project details description: Retrieves details of a specific project based on category 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/BaseResponseMemberList' - $ref: '#/components/schemas/BaseResponseFileList' - $ref: '#/components/schemas/BaseResponseLinkList' # Task /task: get: tags: - Task summary: Get tasks description: Retrieves a paginated list of tasks filtered by village, division, and 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 - name: status in: query description: Filter by task status schema: type: string enum: [segera, dikerjakan, selesai, batal] - name: search in: query description: Search term for task title or description schema: type: string - 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' /task/{id}: get: tags: - Task summary: Get task details description: Retrieves details of a specific task based on category 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/BaseResponseMemberList' - $ref: '#/components/schemas/BaseResponseFileList' - $ref: '#/components/schemas/BaseResponseLinkList' security: - bearerAuth: [] tags: - 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 discussions - name: DiscussionGeneral description: Operations related to general discussions - name: Division description: Operations related to division management - name: Document description: Operations related to document 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