{"openapi":"3.0.0","paths":{"/api":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}},"tags":["App"]}},"/health":{"get":{"operationId":"AppController_health","parameters":[],"responses":{"200":{"description":""}},"tags":["App"]}},"/metrics":{"get":{"operationId":"MetricsController_index","parameters":[],"responses":{"200":{"description":""}},"tags":["Metrics"]}},"/api/storage/presigned-upload":{"post":{"operationId":"StorageController_getPresignedUploadUrl","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUploadDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUploadEntity"}}}}},"tags":["storage"]}},"/api/storage/multipart/create":{"post":{"operationId":"StorageController_createMultipartUpload","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMultipartUploadDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MultipartUploadEntity"}}}}},"tags":["storage"]}},"/api/storage/multipart/upload-part":{"post":{"operationId":"StorageController_uploadPart","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"key":{"type":"string"},"uploadId":{"type":"string"},"partNumber":{"type":"integer"},"chunk":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadedPartEntity"}}}}},"tags":["storage"]}},"/api/storage/multipart/complete":{"post":{"operationId":"StorageController_completeMultipartUpload","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteMultipartUploadDto"}}}},"responses":{"201":{"description":""}},"tags":["storage"]}},"/api/storage/multipart/abort":{"delete":{"operationId":"StorageController_abortMultipartUpload","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbortMultipartUploadDto"}}}},"responses":{"200":{"description":""}},"tags":["storage"]}},"/api/rooms":{"post":{"operationId":"CollabController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollabRoomDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomEntity"}}}}},"tags":["collab"]},"get":{"operationId":"CollabController_findByOwner","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RoomEntity"}}}}}},"tags":["collab"]}},"/api/rooms/{slug}":{"delete":{"operationId":"CollabController_deleteRoom","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["collab"]},"get":{"operationId":"CollabController_findBySlug","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomEntity"}}}}},"tags":["collab"]},"patch":{"operationId":"CollabController_updateRoom","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoomDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomEntity"}}}}},"tags":["collab"]}},"/api/rooms/{slug}/join":{"post":{"operationId":"CollabController_joinRoom","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRoomBodyDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRoomResponseDto"}}}}},"tags":["collab"]}},"/api/courses":{"post":{"operationId":"CoursesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCourseDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseEntity"}}}}},"tags":["courses"]},"get":{"operationId":"CoursesController_findAll","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"type":"number"}},{"name":"departmentId","required":false,"in":"query","schema":{"type":"string"}},{"name":"hasOutline","required":false,"in":"query","description":"Only return courses with a saved module outline","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedCourseEntity"}}}}},"tags":["courses"]}},"/api/courses/{id}":{"get":{"operationId":"CoursesController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseEntity"}}}}},"tags":["courses"]},"patch":{"operationId":"CoursesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCourseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseEntity"}}}}},"tags":["courses"]},"delete":{"operationId":"CoursesController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["courses"]}},"/api/courses/{id}/outline":{"get":{"operationId":"CoursesController_getOutline","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseModuleOutlineEntity"}}}}}},"tags":["courses"]},"put":{"operationId":"CoursesController_replaceOutline","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceCourseOutlineDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseModuleOutlineEntity"}}}}}},"tags":["courses"]}},"/api/courses/{id}/outline/extract":{"post":{"operationId":"CoursesController_extractOutline","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractCourseOutlineDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseModuleOutlineEntity"}}}}}},"tags":["courses"]}},"/api/tags/autocomplete":{"get":{"operationId":"TagsController_autocomplete","parameters":[{"name":"q","required":false,"in":"query","description":"Tag name prefix","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["tags"]}},"/api/tags/trending":{"get":{"operationId":"TagsController_trending","parameters":[],"responses":{"200":{"description":""}},"tags":["tags"]}},"/api/tags/stats":{"get":{"operationId":"TagsController_stats","parameters":[],"responses":{"200":{"description":""}},"tags":["tags"]}},"/api/users/me":{"get":{"operationId":"UsersController_getMe","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileEntity"}}}}},"tags":["users"]},"patch":{"operationId":"UsersController_updateMe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileEntity"}}}}},"tags":["users"]}},"/api/users/me/export":{"get":{"operationId":"UsersController_exportMyData","parameters":[],"responses":{"200":{"description":""}},"tags":["users"]}},"/api/users/me/consent":{"post":{"operationId":"UsersController_giveConsent","parameters":[],"responses":{"200":{"description":""}},"tags":["users"]}},"/api/users/{id}":{"get":{"operationId":"UsersController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileEntity"}}}}},"tags":["users"]}},"/api/users/me/academic-profile":{"patch":{"operationId":"UsersController_updateAcademicProfile","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAcademicProfileDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileEntity"}}}}},"tags":["users"]}},"/api/users/me/public-key":{"patch":{"operationId":"UsersController_updatePublicKey","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePublicKeyDto"}}}},"responses":{"200":{"description":""}},"tags":["users"]},"delete":{"operationId":"UsersController_clearMyKeys","parameters":[],"responses":{"200":{"description":"Encryption keys cleared"}},"tags":["users"]}},"/api/users/me/key-backup":{"patch":{"operationId":"UsersController_updateKeyBackup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateKeyBackupDto"}}}},"responses":{"200":{"description":""}},"tags":["users"]},"get":{"operationId":"UsersController_getKeyBackup","parameters":[],"responses":{"200":{"description":""}},"tags":["users"]},"delete":{"operationId":"UsersController_clearKeyBackup","parameters":[],"responses":{"200":{"description":""}},"tags":["users"]}},"/api/users/admin/public-keys":{"delete":{"operationId":"UsersController_clearAllPublicKeys","parameters":[],"responses":{"200":{"description":""}},"tags":["users"]}},"/api/users/{id}/follow":{"post":{"operationId":"FollowsController_follow","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["follows"]},"delete":{"operationId":"FollowsController_unfollow","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["follows"]}},"/api/users/{id}/followers":{"get":{"operationId":"FollowsController_getFollowers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FollowUserEntity"}}}}}},"tags":["follows"]}},"/api/users/{id}/following":{"get":{"operationId":"FollowsController_getFollowing","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FollowUserEntity"}}}}}},"tags":["follows"]}},"/api/chat/presence":{"get":{"operationId":"ChatController_getPresence","parameters":[{"name":"userIds","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PresenceStatusDto"}}}}}},"summary":"Get presence status for a list of users","tags":["chat"]}},"/api/chat/rooms":{"get":{"operationId":"ChatController_getRooms","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChatRoomEntity"}}}}}},"tags":["chat"]},"post":{"operationId":"ChatController_createRoom","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoomDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRoomEntity"}}}}},"tags":["chat"]}},"/api/chat/rooms/{id}":{"get":{"operationId":"ChatController_getRoom","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRoomEntity"}}}}},"tags":["chat"]},"patch":{"operationId":"ChatController_updateRoom","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChatRoomDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRoomEntity"}}}}},"summary":"Update group room name/image","tags":["chat"]}},"/api/chat/rooms/{id}/messages":{"get":{"operationId":"ChatController_getMessages","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"default":20,"type":"number"}},{"name":"direction","required":false,"in":"query","schema":{"default":"desc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedMessagesEntity"}}}}},"tags":["chat"]},"post":{"operationId":"ChatController_sendMessage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessageEntity"}}}}},"tags":["chat"]}},"/api/chat/messages/{id}":{"patch":{"operationId":"ChatController_editMessage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMessageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessageEntity"}}}}},"tags":["chat"]},"delete":{"operationId":"ChatController_deleteMessage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteMessageResponseDto"}}}}},"tags":["chat"]}},"/api/chat/rooms/{id}/read":{"post":{"operationId":"ChatController_markAsRead","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["chat"]}},"/api/chat/rooms/{id}/upgrade-encryption":{"post":{"operationId":"ChatController_upgradeEncryption","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeEncryptionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRoomEntity"}}}}},"tags":["chat"]}},"/api/chat/rooms/{id}/leave":{"delete":{"operationId":"ChatController_leaveRoom","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Left the room. roomDeleted indicates if the room was also deleted."}},"tags":["chat"]}},"/api/chat/link-preview":{"get":{"operationId":"ChatController_getLinkPreview","parameters":[{"name":"url","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Link preview metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkPreviewResponseDto"}}}}},"tags":["chat"]}},"/api/chat/rooms/{id}/participants/{userId}":{"delete":{"operationId":"ChatController_removeMember","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Member removed"}},"summary":"Remove a member from group","tags":["chat"]}},"/api/chat/rooms/{id}/participants":{"post":{"operationId":"ChatController_inviteMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteMembersDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRoomEntity"}}}}},"tags":["chat"]}},"/api/notifications/stream":{"get":{"operationId":"NotificationsController_stream","parameters":[],"responses":{"200":{"description":""}},"tags":["notifications"]}},"/api/notifications":{"get":{"operationId":"NotificationsController_findAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NotificationEntity"}}}}}},"tags":["notifications"]}},"/api/notifications/{id}/read":{"patch":{"operationId":"NotificationsController_markOneRead","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["notifications"]}},"/api/notifications/read-all":{"patch":{"operationId":"NotificationsController_markAllRead","parameters":[],"responses":{"200":{"description":""}},"tags":["notifications"]}},"/api/departments":{"post":{"operationId":"DepartmentsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDepartmentDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartmentEntity"}}}}},"tags":["departments"]},"get":{"operationId":"DepartmentsController_findAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DepartmentEntity"}}}}}},"tags":["departments"]}},"/api/departments/{id}":{"get":{"operationId":"DepartmentsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartmentWithCoursesEntity"}}}}},"tags":["departments"]},"patch":{"operationId":"DepartmentsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDepartmentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartmentEntity"}}}}},"tags":["departments"]},"delete":{"operationId":"DepartmentsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["departments"]}},"/api/posts":{"post":{"operationId":"PostsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]},"get":{"operationId":"PostsController_findAll","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"type":"number"}},{"name":"courseId","required":false,"in":"query","schema":{"type":"string"}},{"name":"departmentId","required":false,"in":"query","schema":{"type":"string"}},{"name":"yearLevel","required":false,"in":"query","schema":{"minimum":1,"maximum":6,"type":"number"}},{"name":"moduleNumber","required":false,"in":"query","schema":{"minimum":1,"maximum":3,"type":"number"}},{"name":"type","required":false,"in":"query","schema":{"$ref":"#/components/schemas/PostType"}},{"name":"status","required":false,"in":"query","schema":{"$ref":"#/components/schemas/PostStatus"}},{"name":"authorId","required":false,"in":"query","schema":{"type":"string"}},{"name":"tagSlug","required":false,"in":"query","description":"Filter by tag slug (exact match)","schema":{"type":"string"}},{"name":"hasSummary","required":false,"in":"query","description":"Only return posts that have an AI summary","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedPostEntity"}}}}},"tags":["posts"]}},"/api/posts/saved":{"get":{"operationId":"PostsController_getSavedPosts","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedPostEntity"}}}}},"tags":["posts"]}},"/api/posts/s/{shortCode}":{"get":{"operationId":"PostsController_findByShortCode","parameters":[{"name":"shortCode","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]}},"/api/posts/search":{"get":{"operationId":"PostsController_search","parameters":[{"name":"q","required":true,"in":"query","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Search results with pagination"}},"tags":["posts"]}},"/api/posts/trending":{"get":{"operationId":"PostsController_getTrendingPosts","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (1-indexed)","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Results per page","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"example":{"success":true,"data":{"posts":[{"id":"post123","title":"Linear Algebra Notes","trendingScore":42.5,"views":150,"createdAt":"2026-03-19T12:00:00Z"}],"total":250,"page":1,"limit":20}}}}}}},"tags":["posts"]}},"/api/posts/{id}/ai-index-status":{"get":{"operationId":"PostsController_getAiIndexStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiIndexStatusDto"}}}}},"summary":"Progress of document indexing for AI chat","tags":["posts"]}},"/api/posts/{id}":{"get":{"operationId":"PostsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]},"patch":{"operationId":"PostsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]},"delete":{"operationId":"PostsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["posts"]}},"/api/posts/{id}/save":{"post":{"operationId":"PostsController_savePost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["posts"]},"delete":{"operationId":"PostsController_unsavePost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["posts"]}},"/api/posts/{id}/react":{"post":{"operationId":"PostsController_react","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactToPostDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]}},"/api/posts/{id}/status":{"patch":{"operationId":"PostsController_updateStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostStatusDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]}},"/api/posts/{id}/ai-chat":{"post":{"operationId":"PostsController_aiChat","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiChatDto"}}}},"responses":{"200":{"description":"AI response to the user message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiChatResponseDto"}}}}},"summary":"Chat with a post using AI","tags":["posts"]}},"/api/posts/{id}/summarize":{"post":{"operationId":"PostsController_summarize","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]}},"/api/posts/{id}/tags":{"post":{"operationId":"PostsController_addTags","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagPostDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailEntity"}}}}},"tags":["posts"]}},"/api/posts/{id}/tags/{tagId}":{"delete":{"operationId":"PostsController_removeTag","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"tagId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["posts"]}},"/api/posts/{postId}/comments":{"get":{"operationId":"CommentsController_findAll","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommentEntity"}}}}}},"tags":["comments"]},"post":{"operationId":"CommentsController_create","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentEntity"}}}}},"tags":["comments"]}},"/api/posts/{postId}/comments/{commentId}/replies":{"post":{"operationId":"CommentsController_createReply","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentEntity"}}}}},"tags":["comments"]}},"/api/posts/{postId}/comments/{commentId}":{"patch":{"operationId":"CommentsController_update","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentEntity"}}}}},"tags":["comments"]},"delete":{"operationId":"CommentsController_remove","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentEntity"}}}}},"tags":["comments"]}},"/api/posts/{postId}/files/{fileId}/url":{"get":{"operationId":"FilesController_getDownloadUrl","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"fileId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadUrlEntity"}}}}},"tags":["files"]}},"/api/posts/{postId}/files/{fileId}/download":{"post":{"operationId":"FilesController_recordDownload","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"fileId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["files"]}},"/api/posts/{postId}/files":{"post":{"operationId":"FilesController_confirmUpload","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmFileUploadDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileEntity"}}}}},"tags":["files"]}},"/api/posts/{postId}/files/{fileId}":{"delete":{"operationId":"FilesController_remove","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"fileId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["files"]}},"/api/stats":{"get":{"operationId":"StatsController_getStats","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsEntity"}}}}},"tags":["stats"]}},"/api/post-requests":{"post":{"operationId":"PostRequestsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostRequestDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostRequestEntity"}}}}},"tags":["post-requests"]},"get":{"operationId":"PostRequestsController_findAll","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"type":"number"}},{"name":"courseId","required":false,"in":"query","schema":{"type":"string"}},{"name":"departmentId","required":false,"in":"query","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["OPEN","FULFILLED"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedPostRequestEntity"}}}}},"tags":["post-requests"]}},"/api/post-requests/{id}":{"get":{"operationId":"PostRequestsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostRequestDetailEntity"}}}}},"tags":["post-requests"]},"delete":{"operationId":"PostRequestsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["post-requests"]}},"/api/post-requests/{id}/upvote":{"post":{"operationId":"PostRequestsController_upvote","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostRequestDetailEntity"}}}}},"tags":["post-requests"]}},"/api/post-requests/{id}/suggestions":{"post":{"operationId":"PostRequestsController_suggest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFulfillmentSuggestionDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostRequestFulfillmentEntity"}}}}},"tags":["post-requests"]}},"/api/post-requests/{id}/suggestions/{suggestionId}":{"delete":{"operationId":"PostRequestsController_removeSuggestion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"suggestionId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["post-requests"]}},"/api/post-requests/{id}/suggestions/{suggestionId}/accept":{"post":{"operationId":"PostRequestsController_acceptSuggestion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"suggestionId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostRequestDetailEntity"}}}}},"tags":["post-requests"]}},"/api/posts/{id}/report":{"post":{"operationId":"ReportsController_reportPost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportDetail"}}}}},"tags":["reports"]}},"/api/admin/reports":{"get":{"operationId":"AdminReportsController_listReports","parameters":[{"name":"status","required":false,"in":"query","description":"Filter by status","schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]}},{"name":"reason","required":false,"in":"query","description":"Filter by reason","schema":{"type":"string","enum":["SPAM","OFFENSIVE","COPYRIGHT","OTHER"]}},{"name":"page","required":false,"in":"query","description":"Page number (1-indexed)","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Results per page","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedReportsEntity"}}}},"403":{"description":"Admin or moderator role required"}},"tags":["admin"]}},"/api/admin/reports/{id}/approve":{"patch":{"operationId":"AdminReportsController_approveReport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportDetail"}}}},"403":{"description":"Admin or moderator role required"}},"tags":["admin"]}},"/api/admin/reports/{id}/reject":{"patch":{"operationId":"AdminReportsController_rejectReport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportDetail"}}}},"403":{"description":"Admin or moderator role required"}},"tags":["admin"]}},"/api/reading-lists":{"post":{"operationId":"ReadingListsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReadingListDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadingListEntity"}}}}},"tags":["reading-lists"]},"get":{"operationId":"ReadingListsController_findAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReadingListEntity"}}}}}},"tags":["reading-lists"]}},"/api/reading-lists/user/{userId}/public":{"get":{"operationId":"ReadingListsController_findPublicByUser","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReadingListEntity"}}}}}},"tags":["reading-lists"]}},"/api/reading-lists/{id}":{"get":{"operationId":"ReadingListsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadingListEntity"}}}}},"tags":["reading-lists"]},"put":{"operationId":"ReadingListsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReadingListDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadingListEntity"}}}}},"tags":["reading-lists"]},"delete":{"operationId":"ReadingListsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["reading-lists"]}},"/api/reading-lists/{id}/posts":{"get":{"operationId":"ReadingListsController_getListPosts","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"type":"number"}}],"responses":{"200":{"description":""}},"tags":["reading-lists"]}},"/api/reading-lists/{id}/posts/{postId}":{"post":{"operationId":"ReadingListsController_addPost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"postId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadingListEntity"}}}}},"tags":["reading-lists"]},"delete":{"operationId":"ReadingListsController_removePost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"postId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["reading-lists"]}},"/api/feedback":{"post":{"operationId":"FeedbackController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedbackDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackEntity"}}}}},"tags":["feedback"]}},"/api/admin/feedback":{"get":{"operationId":"AdminFeedbackController_findAll","parameters":[{"name":"type","required":false,"in":"query","description":"Filter by feedback type","schema":{"type":"string","enum":["FEEDBACK","BUG_REPORT"]}},{"name":"page","required":false,"in":"query","description":"Page number (1-indexed)","schema":{"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Results per page","schema":{"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedFeedbackEntity"}}}},"403":{"description":"Admin or moderator role required"}},"tags":["admin"]}},"/api/quizzes":{"get":{"operationId":"QuizzesController_listQuizzes","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"type":"number"}},{"name":"courseId","required":false,"in":"query","schema":{"type":"string"}},{"name":"departmentId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedQuizzesEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/student/{studentId}/progress":{"get":{"operationId":"QuizzesController_getStudentProgress","parameters":[{"name":"studentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentProgressEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/sessions/{sessionId}":{"get":{"operationId":"QuizzesController_getSession","parameters":[{"name":"sessionId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizSessionEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/generate":{"post":{"operationId":"QuizzesController_generateQuestions","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["courseId","file"],"properties":{"courseId":{"type":"string"},"questionCount":{"type":"integer","default":20},"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateQuizResponseEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/generate-from-post":{"post":{"operationId":"QuizzesController_generateFromPost","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateFromPostDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateQuizResponseEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/generate-bulk":{"post":{"operationId":"QuizzesController_generateBulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateBulkDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateBulkResponseEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/questions/{id}":{"put":{"operationId":"QuizzesController_updateQuestion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQuestionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizQuestionEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/{id}":{"get":{"operationId":"QuizzesController_getQuiz","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizEntity"}}}}},"tags":["quizzes"]},"delete":{"operationId":"QuizzesController_deleteQuiz","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["quizzes"]}},"/api/quizzes/{id}/submit":{"post":{"operationId":"QuizzesController_submitQuiz","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitQuizDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitQuizResponseEntity"}}}}},"tags":["quizzes"]}},"/api/quizzes/{id}/publish":{"post":{"operationId":"QuizzesController_publishQuiz","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizEntity"}}}}},"tags":["quizzes"]}},"/api/decks":{"get":{"operationId":"DecksController_listDecks","parameters":[{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"maximum":50,"default":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedDecksEntity"}}}}},"tags":["decks"]},"post":{"operationId":"DecksController_createDeck","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeckDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckEntity"}}}}},"tags":["decks"]}},"/api/decks/quota":{"get":{"operationId":"DecksController_getQuota","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckQuotaEntity"}}}}},"tags":["decks"]}},"/api/decks/templates":{"get":{"operationId":"DecksController_listTemplates","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeckTemplateEntity"}}}}}},"tags":["decks"]}},"/api/decks/{id}":{"get":{"operationId":"DecksController_getDeck","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckEntity"}}}}},"tags":["decks"]},"patch":{"operationId":"DecksController_updateDeck","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeckDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckEntity"}}}}},"tags":["decks"]},"delete":{"operationId":"DecksController_deleteDeck","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["decks"]}},"/api/decks/{id}/download":{"get":{"operationId":"DecksController_getDownloadUrl","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"format","required":false,"in":"query","schema":{"enum":["pptx","pdf"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckDownloadEntity"}}}}},"tags":["decks"]}},"/api/decks/{id}/reexport":{"post":{"operationId":"DecksController_reexport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckEntity"}}}}},"tags":["decks"]}},"/api/exams":{"post":{"operationId":"ExamsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExamDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamEntity"}}}}},"tags":["exams"]},"get":{"operationId":"ExamsController_findAll","parameters":[{"name":"from","required":true,"in":"query","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","schema":{"type":"string"}},{"name":"departmentId","required":false,"in":"query","schema":{"type":"string"}},{"name":"courseId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ExamEntity"}}}}}},"tags":["exams"]}},"/api/exams/{id}":{"patch":{"operationId":"ExamsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateExamDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamEntity"}}}}},"tags":["exams"]},"delete":{"operationId":"ExamsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["exams"]}},"/api/universities":{"get":{"operationId":"UniversitiesController_findAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UniversityEntity"}}}}}},"tags":["universities"]}},"/api/universities/{id}":{"get":{"operationId":"UniversitiesController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UniversityEntity"}}}},"404":{"description":"University not found"}},"tags":["universities"]}},"/api/decks/{id}/share":{"post":{"operationId":"DecksController_createShareLink","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckShareEntity"}}}}},"tags":["decks"]},"delete":{"operationId":"DecksController_revokeShareLink","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckShareRevokedEntity"}}}}},"tags":["decks"]}},"/api/decks/shared/{token}":{"get":{"operationId":"DecksController_getSharedDeck","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedDeckEntity"}}}}},"tags":["decks"]}},"/api/decks/shared/{token}/download":{"get":{"operationId":"DecksController_getSharedDownloadUrl","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}},{"name":"format","required":false,"in":"query","schema":{"enum":["pptx","pdf"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeckDownloadEntity"}}}}},"tags":["decks"]}},"/api/admin/audit-logs":{"get":{"operationId":"AuditController_list","parameters":[{"name":"action","required":false,"in":"query","description":"Filter by action","schema":{"type":"string","enum":["report.approve","report.reject","post.delete","post.status_change","comment.delete","user.set_role","user.ban","user.unban","user.delete","user.delete_via_uniauth","user.consent","auth.sign_in"]}},{"name":"category","required":false,"in":"query","description":"Filter by action group, e.g. user matches user.ban and user.set_role","schema":{"type":"string","enum":["report","post","comment","user","auth"]}},{"name":"actorId","required":false,"in":"query","description":"Filter by acting user id","schema":{"type":"string"}},{"name":"targetType","required":false,"in":"query","description":"Filter by target type, e.g. post, user, report","schema":{"type":"string"}},{"name":"targetId","required":false,"in":"query","description":"Filter by target id","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"Only entries at or after this ISO timestamp","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"Only entries at or before this ISO timestamp","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number (1-indexed)","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Results per page (max 100)","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedAuditLogsEntity"}}}},"403":{"description":"Admin role required"}},"tags":["admin"]}}},"info":{"title":"Unishare API","description":"API for the Unishare platform","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PresignedUploadDto":{"type":"object","properties":{"mimeType":{"type":"string","maxLength":255,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_]*\\/[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*$"},"uploadType":{"type":"string","enum":["document","image","video","encrypted-blob"]},"purpose":{"type":"string","enum":["profile-picture","post-attachment","chat-attachment","group-picture","board-attachment","course-outline"]},"roomSlug":{"type":"string","description":"Room slug — required when purpose is board-attachment, scopes the S3 folder"},"checksumSha256":{"type":"string","description":"Base64-encoded SHA-256 of the file body, verified by storage on upload.","example":"eWPfwx9oFQy+i82Q9/7n0jdzN2qLAM0XGuurO4CgUmk="}},"required":["mimeType","uploadType","purpose"]},"PresignedUploadEntity":{"type":"object","properties":{"url":{"type":"string"},"key":{"type":"string"},"publicUrl":{"type":"string"}},"required":["url","key","publicUrl"]},"CreateMultipartUploadDto":{"type":"object","properties":{"mimeType":{"type":"string","maxLength":255},"uploadType":{"type":"string","enum":["document","image","video"]},"purpose":{"type":"string","enum":["post-attachment"]}},"required":["mimeType","uploadType","purpose"]},"MultipartUploadEntity":{"type":"object","properties":{"uploadId":{"type":"string"},"key":{"type":"string"}},"required":["uploadId","key"]},"UploadedPartEntity":{"type":"object","properties":{"etag":{"type":"string"}},"required":["etag"]},"CompleteMultipartUploadDto":{"type":"object","properties":{"key":{"type":"string","maxLength":500},"uploadId":{"type":"string","maxLength":1024}},"required":["key","uploadId"]},"AbortMultipartUploadDto":{"type":"object","properties":{"key":{"type":"string","maxLength":500},"uploadId":{"type":"string","maxLength":1024}},"required":["key","uploadId"]},"CreateCollabRoomDto":{"type":"object","properties":{"title":{"type":"string","description":"Optional room title","maxLength":120},"visibility":{"type":"string","enum":["OPEN","VIEW_ONLY","PRIVATE"],"description":"Room visibility (default: OPEN)"},"password":{"type":"string","description":"Optional password to protect room on creation"}}},"RoomEntity":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string","nullable":true},"ownerId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"visibility":{"type":"string","enum":["OPEN","VIEW_ONLY","PRIVATE"]},"hasPassword":{"type":"boolean","description":"Whether room has a password set (never exposes the hash)"},"encrypted":{"type":"boolean","description":"Whether board content is end-to-end encrypted with a key carried in the URL fragment. False for rooms created before this existed."}},"required":["id","slug","ownerId","createdAt","updatedAt","visibility","hasPassword","encrypted"]},"UpdateRoomDto":{"type":"object","properties":{"visibility":{"type":"string","enum":["OPEN","VIEW_ONLY","PRIVATE"]},"title":{"type":"string"},"password":{"type":"string","nullable":true,"description":"Set/change password (string) or remove (null)"}}},"JoinRoomBodyDto":{"type":"object","properties":{"password":{"type":"string"},"pwVerified":{"type":"boolean","description":"Sentinel from sessionStorage — skip password check if true (D-22)"}}},"JoinRoomResponseDto":{"type":"object","properties":{"roomSlug":{"type":"string"},"sessionId":{"type":"string"},"userId":{"type":"string"},"displayName":{"type":"string"},"isAnonymous":{"type":"boolean"},"isViewOnly":{"type":"boolean"},"ownerId":{"type":"string"},"encrypted":{"type":"boolean","description":"Whether board content is end-to-end encrypted (key in URL fragment)"}},"required":["roomSlug","sessionId","userId","displayName","isAnonymous","isViewOnly","ownerId","encrypted"]},"CreateCourseDto":{"type":"object","properties":{"code":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":2,"maxLength":100},"yearLevel":{"type":"number","nullable":true,"minimum":1,"maximum":6},"departmentId":{"type":"string"}},"required":["code","name","departmentId"]},"CourseDeptEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"}},"required":["id","name","code"]},"CourseEntity":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"},"yearLevel":{"type":"number","nullable":true,"minimum":1,"maximum":6},"department":{"$ref":"#/components/schemas/CourseDeptEntity"}},"required":["id","code","name","department"]},"PaginatedCourseEntity":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CourseEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["items","total","page","limit","totalPages"]},"UpdateCourseDto":{"type":"object","properties":{"code":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":2,"maxLength":100},"yearLevel":{"type":"number","nullable":true,"minimum":1,"maximum":6},"departmentId":{"type":"string"}}},"CourseModuleOutlineEntity":{"type":"object","properties":{"moduleNumber":{"type":"number"},"topics":{"type":"array","items":{"type":"string"}}},"required":["moduleNumber","topics"]},"CourseModuleOutlineEntryDto":{"type":"object","properties":{"moduleNumber":{"type":"number","minimum":1},"topics":{"type":"array","items":{"type":"string"}}},"required":["moduleNumber","topics"]},"ReplaceCourseOutlineDto":{"type":"object","properties":{"modules":{"type":"array","items":{"$ref":"#/components/schemas/CourseModuleOutlineEntryDto"}}},"required":["modules"]},"ExtractCourseOutlineDto":{"type":"object","properties":{"key":{"type":"string"},"mimeType":{"type":"string"}},"required":["key","mimeType"]},"UserRole":{"type":"string","enum":["STUDENT","MODERATOR","ADMIN"]},"UserDepartmentEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"}},"required":["id","name","code"]},"UserUniversityEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"shortName":{"type":"string"},"logoUrl":{"type":"string","nullable":true}},"required":["id","name","shortName"]},"UserProfileEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"emailVerified":{"type":"boolean"},"image":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"role":{"allOf":[{"$ref":"#/components/schemas/UserRole"}]},"department":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/UserDepartmentEntity"}]},"university":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/UserUniversityEntity"}]},"enrollmentYear":{"type":"number","nullable":true},"yearLevel":{"type":"number","nullable":true},"shouldShowUpdateMajorPopup":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"postCount":{"type":"number"},"commentCount":{"type":"number"},"savedCount":{"type":"number"},"followerCount":{"type":"number"},"followingCount":{"type":"number"},"isFollowing":{"type":"boolean","nullable":true},"publicKey":{"type":"string","nullable":true}},"required":["id","name","email","emailVerified","role","shouldShowUpdateMajorPopup","createdAt","postCount","commentCount","savedCount","followerCount","followingCount"]},"UpdateProfileDto":{"type":"object","properties":{"name":{"type":"string","maxLength":100},"image":{"type":"string","maxLength":500,"format":"uri"},"bio":{"type":"string","maxLength":300}}},"UpdateAcademicProfileDto":{"type":"object","properties":{"departmentId":{"type":"string","nullable":true,"maxLength":50},"universityId":{"type":"string","nullable":true,"maxLength":50},"enrollmentYear":{"type":"number","nullable":true,"minimum":1950,"maximum":2100}}},"UpdatePublicKeyDto":{"type":"object","properties":{"publicKey":{"type":"string","description":"RSA-OAEP public key in JWK format"}},"required":["publicKey"]},"UpdateKeyBackupDto":{"type":"object","properties":{"keyBackup":{"type":"string","description":"Passphrase-encrypted private key transfer payload (PBKDF2 + AES-GCM JSON blob). Opaque to the server."}},"required":["keyBackup"]},"FollowUserEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true},"publicKey":{"type":"string","nullable":true}},"required":["id","name"]},"PresenceStatusDto":{"type":"object","properties":{"userId":{"type":"string"},"status":{"type":"number","enum":[0,1]},"lastSeen":{"type":"number"}},"required":["userId","status"]},"ChatMessageUserEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true},"publicKey":{"type":"string","nullable":true}},"required":["id","name"]},"ChatRoomParticipantEntity":{"type":"object","properties":{"id":{"type":"string"},"roomId":{"type":"string"},"userId":{"type":"string"},"lastReadAt":{"format":"date-time","type":"string"},"joinedAt":{"format":"date-time","type":"string"},"user":{"$ref":"#/components/schemas/ChatMessageUserEntity"},"encryptedRoomKey":{"type":"string","nullable":true}},"required":["id","roomId","userId","lastReadAt","joinedAt","user"]},"ChatMessageParentEntity":{"type":"object","properties":{"id":{"type":"string"},"roomId":{"type":"string"},"userId":{"type":"string","nullable":true},"type":{"type":"string","enum":["TEXT","IMAGE","LINK","SYSTEM","FILE"]},"content":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"fileUrl":{"type":"string","nullable":true},"fileName":{"type":"string","nullable":true},"linkUrl":{"type":"string","nullable":true},"parentId":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"deletedAt":{"type":"string","nullable":true},"user":{"$ref":"#/components/schemas/ChatMessageUserEntity"}},"required":["id","roomId","type","createdAt","updatedAt"]},"ChatMessageEntity":{"type":"object","properties":{"id":{"type":"string"},"roomId":{"type":"string"},"userId":{"type":"string","nullable":true},"type":{"type":"string","enum":["TEXT","IMAGE","LINK","SYSTEM","FILE"]},"content":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"fileUrl":{"type":"string","nullable":true},"fileName":{"type":"string","nullable":true},"linkUrl":{"type":"string","nullable":true},"parentId":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"deletedAt":{"type":"string","nullable":true},"user":{"$ref":"#/components/schemas/ChatMessageUserEntity"},"parent":{"$ref":"#/components/schemas/ChatMessageParentEntity"}},"required":["id","roomId","type","createdAt","updatedAt"]},"ChatRoomEntity":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["DM","GROUP"]},"name":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"participants":{"type":"array","items":{"$ref":"#/components/schemas/ChatRoomParticipantEntity"}},"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessageEntity"}}},"required":["id","type","createdAt","updatedAt","participants"]},"PaginatedMessagesEntity":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessageEntity"}},"nextCursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","hasMore"]},"EncryptedRoomKeyDto":{"type":"object","properties":{"userId":{"type":"string"},"encryptedKey":{"type":"string"}},"required":["userId","encryptedKey"]},"CreateRoomDto":{"type":"object","properties":{"type":{"type":"string","enum":["DM","GROUP"]},"participantIds":{"type":"array","items":{"type":"string"}},"name":{"type":"string","maxLength":30},"imageUrl":{"type":"string","maxLength":500},"encryptedRoomKeys":{"type":"array","items":{"$ref":"#/components/schemas/EncryptedRoomKeyDto"}}},"required":["type","participantIds"]},"SendMessageDto":{"type":"object","properties":{"content":{"type":"string"},"type":{"type":"string","enum":["TEXT","IMAGE","LINK","SYSTEM","FILE"]},"imageUrl":{"type":"string"},"fileUrl":{"type":"string"},"fileName":{"type":"string"},"linkUrl":{"type":"string"},"parentId":{"type":"string"}}},"UpdateMessageDto":{"type":"object","properties":{"content":{"type":"string"}},"required":["content"]},"DeleteMessageResponseDto":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"UpgradeEncryptionDto":{"type":"object","properties":{"encryptedRoomKeys":{"type":"array","items":{"$ref":"#/components/schemas/EncryptedRoomKeyDto"}}},"required":["encryptedRoomKeys"]},"LinkPreviewResponseDto":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"siteName":{"type":"string"},"images":{"type":"array","items":{"type":"string"}},"image":{"type":"string"},"url":{"type":"string"}},"required":["title"]},"UpdateChatRoomDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":50},"imageUrl":{"type":"string","maxLength":500}}},"InviteMembersDto":{"type":"object","properties":{"userIds":{"type":"array","items":{"type":"string"}},"encryptedRoomKeys":{"type":"array","items":{"$ref":"#/components/schemas/EncryptedRoomKeyDto"}}},"required":["userIds"]},"NotificationEntity":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"message":{"type":"string"},"read":{"type":"boolean"},"postId":{"type":"string","nullable":true},"requestId":{"type":"string","nullable":true},"chatRoomId":{"type":"string","nullable":true},"examId":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"}},"required":["id","type","message","read","postId","requestId","chatRoomId","examId","createdAt"]},"CreateDepartmentDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":100}},"required":["name"]},"DepartmentEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"courseCount":{"type":"number"}},"required":["id","name","courseCount"]},"DeptCourseEntity":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"]},"DepartmentWithCoursesEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"courseCount":{"type":"number"},"courses":{"type":"array","items":{"$ref":"#/components/schemas/DeptCourseEntity"}}},"required":["id","name","courseCount","courses"]},"UpdateDepartmentDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":100}}},"CreatePostDto":{"type":"object","properties":{"type":{"type":"string","enum":["NOTE","OLD_QUESTION","EXERCISE"]},"courseId":{"type":"string","description":"Course ID. Must belong to the authenticated user department."},"title":{"type":"string","minLength":3,"maxLength":200},"description":{"type":"string","maxLength":2000},"isAnonymous":{"type":"boolean","default":false},"externalUrl":{"type":"string","maxLength":500},"examYear":{"type":"number","minimum":1900,"maximum":2100},"moduleNumber":{"type":"number","minimum":1,"maximum":20},"year":{"type":"number","minimum":1,"maximum":6},"semester":{"type":"number","minimum":1,"maximum":3},"tags":{"example":["Linear Algebra","Calculus"],"description":"Array of tag names (max 5 tags)","type":"array","items":{"type":"string"}}},"required":["type","courseId","title","description","moduleNumber","year","semester"]},"PostType":{"type":"string","enum":["NOTE","OLD_QUESTION","EXERCISE"]},"PostStatus":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"PostPublicationStatus":{"type":"string","enum":["PUBLISHED","PENDING_REVIEW","REJECTED"]},"PostAuthorDeptEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"PostAuthorEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true},"enrollmentYear":{"type":"number","nullable":true},"department":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostAuthorDeptEntity"}]}},"required":["id","name"]},"PostCourseDeptEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"PostCourseEntity":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"},"department":{"$ref":"#/components/schemas/PostCourseDeptEntity"}},"required":["id","code","name","department"]},"IngestStatus":{"type":"string","enum":["PENDING","PROCESSING","READY","FAILED","UNSUPPORTED"]},"PostFileEntity":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"},"size":{"type":"number"},"mimeType":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"downloads":{"type":"number"},"ingestStatus":{"allOf":[{"$ref":"#/components/schemas/IngestStatus"}]},"ingestedAt":{"format":"date-time","type":"string","nullable":true}},"required":["id","key","name","size","mimeType","createdAt","downloads","ingestStatus"]},"PostCountEntity":{"type":"object","properties":{"comments":{"type":"number"},"savedBy":{"type":"number"}},"required":["comments","savedBy"]},"PostTagEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"color":{"type":"string"}},"required":["id","name","slug","color"]},"PostDetailEntity":{"type":"object","properties":{"id":{"type":"string"},"type":{"allOf":[{"$ref":"#/components/schemas/PostType"}]},"status":{"allOf":[{"$ref":"#/components/schemas/PostStatus"}]},"publicationStatus":{"allOf":[{"$ref":"#/components/schemas/PostPublicationStatus"}]},"trendingScore":{"type":"number"},"isAnonymous":{"type":"boolean","default":false},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"externalUrl":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"summarizedAt":{"format":"date-time","type":"string","nullable":true},"contentWarning":{"type":"string","nullable":true},"examYear":{"type":"number","nullable":true},"moduleNumber":{"type":"number","nullable":true},"year":{"type":"number","nullable":true},"semester":{"type":"number","nullable":true},"shortCode":{"type":"string"},"isOwner":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"author":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostAuthorEntity"}]},"course":{"$ref":"#/components/schemas/PostCourseEntity"},"files":{"type":"array","items":{"$ref":"#/components/schemas/PostFileEntity"}},"_count":{"$ref":"#/components/schemas/PostCountEntity"},"savedByCurrentUser":{"type":"boolean"},"views":{"type":"number"},"reactionCounts":{"type":"object","additionalProperties":{"type":"number"},"description":"Map of ReactionType to count"},"userReaction":{"type":"string","nullable":true},"tags":{"type":"array","items":{"$ref":"#/components/schemas/PostTagEntity"}}},"required":["id","type","status","publicationStatus","trendingScore","isAnonymous","shortCode","isOwner","createdAt","updatedAt","course","files","_count","savedByCurrentUser","views","reactionCounts","tags"]},"PostEntity":{"type":"object","properties":{"id":{"type":"string"},"type":{"allOf":[{"$ref":"#/components/schemas/PostType"}]},"status":{"allOf":[{"$ref":"#/components/schemas/PostStatus"}]},"publicationStatus":{"allOf":[{"$ref":"#/components/schemas/PostPublicationStatus"}]},"trendingScore":{"type":"number"},"isAnonymous":{"type":"boolean","default":false},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"externalUrl":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"summarizedAt":{"format":"date-time","type":"string","nullable":true},"contentWarning":{"type":"string","nullable":true},"examYear":{"type":"number","nullable":true},"moduleNumber":{"type":"number","nullable":true},"year":{"type":"number","nullable":true},"semester":{"type":"number","nullable":true},"shortCode":{"type":"string"},"isOwner":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"author":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostAuthorEntity"}]},"course":{"$ref":"#/components/schemas/PostCourseEntity"},"files":{"type":"array","items":{"$ref":"#/components/schemas/PostFileEntity"}},"_count":{"$ref":"#/components/schemas/PostCountEntity"},"savedByCurrentUser":{"type":"boolean"},"views":{"type":"number"},"reactionCounts":{"type":"object","additionalProperties":{"type":"number"},"description":"Map of ReactionType to count"},"userReaction":{"type":"string","nullable":true},"tags":{"type":"array","items":{"$ref":"#/components/schemas/PostTagEntity"}}},"required":["id","type","status","publicationStatus","trendingScore","isAnonymous","shortCode","isOwner","createdAt","updatedAt","course","files","_count","savedByCurrentUser","views","reactionCounts","tags"]},"PaginatedPostEntity":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PostEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["items","total","page","limit","totalPages"]},"AiIndexState":{"type":"string","enum":["unsupported","preparing","ready","failed"],"description":"'unsupported' — nothing on this post can be indexed. 'preparing' — at least one supported file is still pending or processing. 'ready' — indexing has settled and at least one supported file was indexed. 'failed' — indexing has settled and none succeeded."},"AiIndexStatusDto":{"type":"object","properties":{"state":{"description":"'unsupported' — nothing on this post can be indexed. 'preparing' — at least one supported file is still pending or processing. 'ready' — indexing has settled and at least one supported file was indexed. 'failed' — indexing has settled and none succeeded.","allOf":[{"$ref":"#/components/schemas/AiIndexState"}]},"indexedChunks":{"type":"number","description":"Live count of post_chunk rows for this post. Deliberately not a percentage: the total chunk count is unknowable until chunking finishes, so any ratio would be invented."},"supportedFiles":{"type":"number","description":"Files on this post whose mime type can be indexed"},"readyFiles":{"type":"number","description":"Supported files that finished indexing successfully"}},"required":["state","indexedChunks","supportedFiles","readyFiles"]},"ReactToPostDto":{"type":"object","properties":{"type":{"type":"string","enum":["HELPFUL","LOVE","FIRE","WOW","SALUTE","FUNNY"]}},"required":["type"]},"UpdateablePostStatus":{"type":"string","enum":["APPROVED","REJECTED"]},"UpdatePostStatusDto":{"type":"object","properties":{"status":{"allOf":[{"$ref":"#/components/schemas/UpdateablePostStatus"}]}},"required":["status"]},"UpdatePostDto":{"type":"object","properties":{"title":{"type":"string","minLength":3,"maxLength":200},"description":{"type":"string","maxLength":2000},"isAnonymous":{"type":"boolean","default":false},"externalUrl":{"type":"string","maxLength":500},"examYear":{"type":"number","minimum":1900,"maximum":2100},"moduleNumber":{"type":"number","minimum":1,"maximum":20},"year":{"type":"number","minimum":1,"maximum":6},"semester":{"type":"number","minimum":1,"maximum":3},"tags":{"example":["Linear Algebra","Calculus"],"description":"Array of tag names (max 5 tags)","type":"array","items":{"type":"string"}}}},"AiChatMessageDto":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string","maxLength":4000}},"required":["role","content"]},"AiChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/AiChatMessageDto"}}},"required":["messages"]},"AiChatCitationDto":{"type":"object","properties":{"chunkId":{"type":"string"},"pageNum":{"type":"number","nullable":true,"description":"Null for .docx, which has no pages"},"fileId":{"type":"string","description":"Which uploaded file this chunk came from"},"fileName":{"type":"string","description":"Display name of the file, for attributing the page"},"snippet":{"type":"string","description":"Short excerpt of the cited chunk"}},"required":["chunkId","pageNum","fileId","fileName","snippet"]},"AiChatResponseDto":{"type":"object","properties":{"reply":{"type":"string","description":"AI reply text, or \"OFF_TOPIC\" sentinel"},"offTopic":{"type":"boolean","description":"True when the question was unrelated to the document"},"citations":{"type":"array","items":{"$ref":"#/components/schemas/AiChatCitationDto"}}},"required":["reply","offTopic","citations"]},"TagPostDto":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"}}},"required":["tags"]},"CommentUserEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true}},"required":["id","name"]},"CommentEntity":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"},"userId":{"type":"string"},"postId":{"type":"string"},"parentId":{"type":"string","nullable":true},"deletedAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"user":{"$ref":"#/components/schemas/CommentUserEntity"},"children":{"description":"Nested replies for this comment.","type":"array","items":{"$ref":"#/components/schemas/CommentEntity"}}},"required":["id","content","userId","postId","createdAt","updatedAt","user"]},"CreateCommentDto":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":2000},"parentId":{"type":"string","description":"Parent comment ID when creating a nested reply."}},"required":["content"]},"UpdateCommentDto":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":2000},"parentId":{"type":"string","description":"Parent comment ID when creating a nested reply."}}},"DownloadUrlEntity":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"ConfirmFileUploadDto":{"type":"object","properties":{"key":{"type":"string","maxLength":500},"name":{"type":"string","maxLength":255},"size":{"type":"number","minimum":1},"mimeType":{"type":"string","maxLength":255}},"required":["key","name","size","mimeType"]},"FileEntity":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"},"size":{"type":"number"},"mimeType":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"downloads":{"type":"number"}},"required":["id","key","name","size","mimeType","createdAt","downloads"]},"StatsOverviewEntity":{"type":"object","properties":{"totalUsers":{"type":"number"},"totalPosts":{"type":"number"},"totalComments":{"type":"number"},"totalReactions":{"type":"number"}},"required":["totalUsers","totalPosts","totalComments","totalReactions"]},"TopPostEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"shortCode":{"type":"string"},"views":{"type":"number"},"reactionCount":{"type":"number"},"authorName":{"type":"string","nullable":true}},"required":["id","title","shortCode","views","reactionCount","authorName"]},"TopUserEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true},"postCount":{"type":"number"},"departmentName":{"type":"string","nullable":true}},"required":["id","name","image","postCount","departmentName"]},"StatsEntity":{"type":"object","properties":{"overview":{"$ref":"#/components/schemas/StatsOverviewEntity"},"topPostsByViews":{"type":"array","items":{"$ref":"#/components/schemas/TopPostEntity"}},"topPostsByReactions":{"type":"array","items":{"$ref":"#/components/schemas/TopPostEntity"}},"topUsers":{"type":"array","items":{"$ref":"#/components/schemas/TopUserEntity"}}},"required":["overview","topPostsByViews","topPostsByReactions","topUsers"]},"CreatePostRequestDto":{"type":"object","properties":{"title":{"type":"string","maxLength":200},"description":{"type":"string","maxLength":2000},"courseId":{"type":"string"}},"required":["title","courseId"]},"PostRequestAuthorEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true}},"required":["id","name"]},"PostRequestCourseEntity":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"]},"PostRequestFulfilledByEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string","nullable":true},"shortCode":{"type":"string"}},"required":["id","shortCode"]},"PostRequestEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string","enum":["OPEN","FULFILLED"]},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"upvoteCount":{"type":"number"},"isUpvoted":{"type":"boolean"},"author":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostRequestAuthorEntity"}]},"course":{"$ref":"#/components/schemas/PostRequestCourseEntity"},"fulfilledByPost":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostRequestFulfilledByEntity"}]}},"required":["id","title","status","createdAt","updatedAt","upvoteCount","isUpvoted","course"]},"PaginatedPostRequestEntity":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PostRequestEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["items","total","page","limit","totalPages"]},"FulfillmentSuggestionPostEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string","nullable":true},"shortCode":{"type":"string"},"type":{"type":"string","enum":["NOTE","OLD_QUESTION","EXERCISE"]},"author":{"$ref":"#/components/schemas/PostRequestAuthorEntity"}},"required":["id","shortCode","type","author"]},"PostRequestFulfillmentEntity":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"user":{"$ref":"#/components/schemas/PostRequestAuthorEntity"},"post":{"$ref":"#/components/schemas/FulfillmentSuggestionPostEntity"}},"required":["id","createdAt","user","post"]},"PostRequestDetailEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string","enum":["OPEN","FULFILLED"]},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"upvoteCount":{"type":"number"},"isUpvoted":{"type":"boolean"},"author":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostRequestAuthorEntity"}]},"course":{"$ref":"#/components/schemas/PostRequestCourseEntity"},"fulfilledByPost":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/PostRequestFulfilledByEntity"}]},"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/PostRequestFulfillmentEntity"}}},"required":["id","title","status","createdAt","updatedAt","upvoteCount","isUpvoted","course","suggestions"]},"CreateFulfillmentSuggestionDto":{"type":"object","properties":{"postId":{"type":"string","description":"ID of the post to suggest as fulfillment"}},"required":["postId"]},"CreateReportDto":{"type":"object","properties":{"reason":{"type":"string","enum":["SPAM","OFFENSIVE","COPYRIGHT","OTHER"],"description":"Reason for report"},"comment":{"type":"string","description":"Optional context/details for the report"}},"required":["reason"]},"ReportPostDepartmentEntity":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"ReportPostCourseEntity":{"type":"object","properties":{"code":{"type":"string"},"department":{"$ref":"#/components/schemas/ReportPostDepartmentEntity"}},"required":["code","department"]},"ReportPostAuthorEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"ReportPostEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string","nullable":true},"type":{"type":"string"},"course":{"$ref":"#/components/schemas/ReportPostCourseEntity"},"author":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/ReportPostAuthorEntity"}]}},"required":["id","type","course"]},"ReportReporterEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"ReportAdminActionEntity":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string"},"reason":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"}},"required":["id","action","createdAt"]},"ReportDetail":{"type":"object","properties":{"id":{"type":"string"},"postId":{"type":"string"},"userId":{"type":"string"},"reason":{"type":"string","enum":["SPAM","OFFENSIVE","COPYRIGHT","OTHER"]},"comment":{"type":"string","nullable":true},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"createdAt":{"format":"date-time","type":"string"},"post":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/ReportPostEntity"}]},"reporter":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/ReportReporterEntity"}]},"adminAction":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/ReportAdminActionEntity"}]}},"required":["id","postId","userId","reason","status","createdAt"]},"PaginatedReportsEntity":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/ReportDetail"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["reports","total","page","limit"]},"CreateReadingListDto":{"type":"object","properties":{"name":{"type":"string","example":"Finals Revision"},"description":{"type":"string","example":"Materials for final exam prep"},"isPublic":{"type":"boolean","default":false}},"required":["name"]},"ReadingListEntity":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"isPublic":{"type":"boolean"},"postCount":{"type":"number"},"postIds":{"type":"array","items":{"type":"string"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","userId","name","isPublic","postCount","postIds","createdAt","updatedAt"]},"UpdateReadingListDto":{"type":"object","properties":{"name":{"type":"string","example":"Finals Revision"},"description":{"type":"string","example":"Materials for final exam prep"},"isPublic":{"type":"boolean","default":false}}},"CreateFeedbackDto":{"type":"object","properties":{"type":{"type":"string","enum":["FEEDBACK","BUG_REPORT"],"description":"Type of feedback"},"message":{"type":"string","description":"Feedback message","minLength":10,"maxLength":2000}},"required":["type","message"]},"FeedbackUserEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"FeedbackEntity":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["FEEDBACK","BUG_REPORT"]},"message":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"user":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/FeedbackUserEntity"}]}},"required":["id","type","message","createdAt"]},"PaginatedFeedbackEntity":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FeedbackEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"QuizCourseEntity":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"]},"QuizListItemEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"courseId":{"type":"string"},"course":{"$ref":"#/components/schemas/QuizCourseEntity"},"questionsCount":{"type":"number"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","title","courseId","course","questionsCount","createdAt"]},"PaginatedQuizzesEntity":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/QuizListItemEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"StudentStatsEntity":{"type":"object","properties":{"totalAttempts":{"type":"number"},"averageScore":{"type":"number"},"bestScore":{"type":"number"}},"required":["totalAttempts","averageScore","bestScore"]},"RecentSessionQuizEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"courseId":{"type":"string"}},"required":["id","title","courseId"]},"RecentSessionEntity":{"type":"object","properties":{"id":{"type":"string"},"score":{"type":"number"},"totalPoints":{"type":"number"},"timeSpentSec":{"type":"number","nullable":true},"attemptedAt":{"format":"date-time","type":"string"},"completedAt":{"type":"string","nullable":true},"quiz":{"$ref":"#/components/schemas/RecentSessionQuizEntity"}},"required":["id","score","totalPoints","attemptedAt","quiz"]},"StudentProgressEntity":{"type":"object","properties":{"stats":{"$ref":"#/components/schemas/StudentStatsEntity"},"recentSessions":{"type":"array","items":{"$ref":"#/components/schemas/RecentSessionEntity"}}},"required":["stats","recentSessions"]},"QuizQuestionEntity":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"},"options":{"type":"array","items":{"type":"string"}},"correctAnswer":{"type":"number"},"difficulty":{"type":"string","enum":["easy","medium","hard"]},"explanation":{"type":"string","nullable":true}},"required":["id","content","options","correctAnswer","difficulty"]},"QuizEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"courseId":{"type":"string"},"isPublished":{"type":"boolean"},"questionsCount":{"type":"number"},"questions":{"type":"array","items":{"$ref":"#/components/schemas/QuizQuestionEntity"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","title","courseId","isPublished","questionsCount","questions","createdAt","updatedAt"]},"QuestionAttemptEntity":{"type":"object","properties":{"id":{"type":"string"},"questionId":{"type":"string"},"studentAnswer":{"type":"number","nullable":true},"isCorrect":{"type":"boolean","nullable":true}},"required":["id","questionId"]},"QuizSessionEntity":{"type":"object","properties":{"id":{"type":"string"},"score":{"type":"number"},"totalPoints":{"type":"number"},"timeSpentSec":{"type":"number","nullable":true},"completedAt":{"type":"string","nullable":true},"quiz":{"$ref":"#/components/schemas/QuizEntity"},"questionAttempts":{"type":"array","items":{"$ref":"#/components/schemas/QuestionAttemptEntity"}}},"required":["id","score","totalPoints","quiz","questionAttempts"]},"GenerateQuizResponseEntity":{"type":"object","properties":{"quizId":{"type":"string"},"questions":{"type":"array","items":{"$ref":"#/components/schemas/QuizQuestionEntity"}}},"required":["quizId","questions"]},"GenerateFromPostDto":{"type":"object","properties":{"postId":{"type":"string","description":"Post ID with an AI summary to generate quiz from"},"questionCount":{"type":"number","minimum":1,"maximum":100,"default":20}},"required":["postId"]},"GenerateBulkDto":{"type":"object","properties":{"courseId":{"type":"string","description":"Course to generate one quiz per outlined module for"}},"required":["courseId"]},"GenerateBulkCreatedEntity":{"type":"object","properties":{"moduleNumber":{"type":"number"},"quizId":{"type":"string"},"questionsCount":{"type":"number"}},"required":["moduleNumber","quizId","questionsCount"]},"GenerateBulkFailedEntity":{"type":"object","properties":{"moduleNumber":{"type":"number"},"error":{"type":"string"}},"required":["moduleNumber","error"]},"GenerateBulkResponseEntity":{"type":"object","properties":{"created":{"type":"array","items":{"$ref":"#/components/schemas/GenerateBulkCreatedEntity"}},"failed":{"type":"array","items":{"$ref":"#/components/schemas/GenerateBulkFailedEntity"}}},"required":["created","failed"]},"UpdateQuestionDto":{"type":"object","properties":{"content":{"type":"string"},"options":{"type":"array","items":{"type":"string"}},"correctAnswer":{"type":"number","minimum":0,"maximum":3},"explanation":{"type":"string"},"difficulty":{"type":"string","enum":["easy","medium","hard"]}}},"SubmitQuizAnswerDto":{"type":"object","properties":{"questionId":{"type":"string"},"answerIndex":{"type":"number","nullable":true}},"required":["questionId","answerIndex"]},"SubmitQuizDto":{"type":"object","properties":{"answers":{"type":"array","items":{"$ref":"#/components/schemas/SubmitQuizAnswerDto"}},"timeSpentSec":{"type":"number","description":"Total time spent in seconds"}},"required":["answers"]},"QuizAttemptResultEntity":{"type":"object","properties":{"questionId":{"type":"string"},"isCorrect":{"type":"boolean"},"explanation":{"type":"string","nullable":true}},"required":["questionId","isCorrect"]},"SubmitQuizResponseEntity":{"type":"object","properties":{"sessionId":{"type":"string"},"score":{"type":"number"},"totalPoints":{"type":"number"},"percentage":{"type":"number"},"results":{"type":"array","items":{"$ref":"#/components/schemas/QuizAttemptResultEntity"}}},"required":["sessionId","score","totalPoints","percentage","results"]},"DeckEntity":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["QUEUED","GENERATING","READY","FAILED"]},"prompt":{"type":"string"},"title":{"type":"string","nullable":true},"slideCount":{"type":"number"},"language":{"type":"string"},"template":{"type":"string"},"error":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"completedAt":{"format":"date-time","type":"string","nullable":true},"queueAhead":{"type":"number","nullable":true},"etaSeconds":{"type":"number","nullable":true},"queueAheadIsApproximate":{"type":"boolean","nullable":true,"description":"True when the exact position is beyond the scan limit"},"hasPdf":{"type":"boolean","description":"A PDF render exists, so the deck can be previewed in-app"},"canEdit":{"type":"boolean","description":"The generator can still act on this deck"},"editorUrl":{"type":"string","nullable":true,"description":"Where to point the editor frame. Null when no editor host is configured."},"tone":{"type":"string"},"verbosity":{"type":"string"},"scheduledFor":{"format":"date-time","type":"string","nullable":true,"description":"Set when the deck is held until the owner's allowance frees up"},"attempts":{"type":"number","description":"Attempts made so far"},"maxAttempts":{"type":"number","description":"Attempts before the deck is given up on"},"progressPhase":{"type":"string","nullable":true,"enum":["starting","outline","layout","slides","assets","finishing"],"description":"Which stage of generation the deck is in"},"progressDone":{"type":"number","nullable":true,"description":"Slides finished so far"},"progressTotal":{"type":"number","nullable":true,"description":"The generator's own slide total, which may differ from slideCount"},"shareToken":{"type":"string","nullable":true,"description":"The deck share token, or null when it is not shared. Owner-only."}},"required":["id","status","prompt","slideCount","language","template","shareToken","createdAt","hasPdf","canEdit","tone","verbosity","attempts","maxAttempts"]},"PaginatedDecksEntity":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeckEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["data","total","page","limit"]},"DeckQuotaEntity":{"type":"object","properties":{"used":{"type":"number"},"limit":{"type":"number","nullable":true,"description":"Decks per rolling 24h, or null for no limit (administrators)."},"resetsAt":{"format":"date-time","type":"string","description":"When the oldest slot in the window frees"},"nextSlotAt":{"format":"date-time","type":"string","nullable":true,"description":"When a deck submitted now would start. Null while under quota."}},"required":["used","limit","resetsAt"]},"DeckTemplateEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true}},"required":["id","name"]},"CreateDeckDto":{"type":"object","properties":{"prompt":{"type":"string","description":"What the deck should be about","example":"The causes and consequences of the 1997 Asian financial crisis"},"slideCount":{"type":"number","minimum":3,"maximum":14,"default":8},"language":{"type":"string","default":"English"},"template":{"type":"string","default":"general"},"tone":{"type":"string","enum":["default","casual","professional","funny","educational","sales_pitch"],"default":"default"},"verbosity":{"type":"string","enum":["concise","standard","text-heavy"],"default":"concise"},"instructions":{"type":"string","description":"Extra guidance for the generator"},"includeTitleSlide":{"type":"boolean","default":true},"includeTableOfContents":{"type":"boolean","default":false},"webSearch":{"type":"boolean","description":"Let the generator search the web","default":false}},"required":["prompt"]},"UpdateDeckDto":{"type":"object","properties":{"title":{"type":"string","description":"Display title, used for the heading, the library card and the download filename","minLength":1,"maxLength":120}}},"DeckDownloadEntity":{"type":"object","properties":{"url":{"type":"string"},"expiresIn":{"type":"number"}},"required":["url","expiresIn"]},"CreateExamDto":{"type":"object","properties":{"courseId":{"type":"string"},"title":{"type":"string","minLength":2,"maxLength":100},"startsAt":{"type":"string"},"endsAt":{"type":"string","nullable":true},"examRoom":{"type":"string","nullable":true,"maxLength":100},"notes":{"type":"string","nullable":true,"maxLength":1000}},"required":["courseId","title","startsAt"]},"ExamCourseEntity":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"},"department":{"$ref":"#/components/schemas/CourseDeptEntity"}},"required":["id","code","name","department"]},"ExamEntity":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"examRoom":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"startsAt":{"format":"date-time","type":"string"},"endsAt":{"format":"date-time","type":"string","nullable":true},"createdBy":{"type":"string"},"course":{"$ref":"#/components/schemas/ExamCourseEntity"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","title","startsAt","createdBy","course","createdAt","updatedAt"]},"UpdateExamDto":{"type":"object","properties":{"courseId":{"type":"string"},"title":{"type":"string","minLength":2,"maxLength":100},"startsAt":{"type":"string"},"endsAt":{"type":"string","nullable":true},"examRoom":{"type":"string","nullable":true,"maxLength":100},"notes":{"type":"string","nullable":true,"maxLength":1000}}},"UniversityEntity":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"shortName":{"type":"string"},"logoUrl":{"type":"string","nullable":true}},"required":["id","name","shortName"]},"DeckShareEntity":{"type":"object","properties":{"shareToken":{"type":"string","description":"Append to the deck share URL. Treat it as a credential."}},"required":["shareToken"]},"DeckShareRevokedEntity":{"type":"object","properties":{"revoked":{"type":"boolean"}},"required":["revoked"]},"SharedDeckEntity":{"type":"object","properties":{"title":{"type":"string","nullable":true},"slideCount":{"type":"number"},"template":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"formats":{"description":"Only the formats that exist; a failed preview render leaves no pdf.","type":"array","items":{"type":"string"}}},"required":["title","slideCount","template","createdAt","formats"]},"AuditLogEntity":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"actorId":{"type":"string","nullable":true},"actorName":{"type":"string","nullable":true},"actorRole":{"type":"string","nullable":true},"action":{"type":"string","description":"Dotted ., e.g. post.delete"},"targetType":{"type":"string","nullable":true},"targetId":{"type":"string","nullable":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true,"description":"Action-specific details"},"ip":{"type":"string","nullable":true}},"required":["id","createdAt","action"]},"PaginatedAuditLogsEntity":{"type":"object","properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/AuditLogEntity"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["logs","total","page","limit"]}}}}