{ "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"] } }, "/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/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" } } ], "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/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/{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/{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/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}": { "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}/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/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/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/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/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/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/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"] } }, "/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/rooms/{id}/read": { "post": { "operationId": "ChatController_markAsRead", "parameters": [ { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "201": { "description": "" } }, "tags": ["chat"] } }, "/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/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"] } } }, "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"] }, "purpose": { "type": "string", "enum": ["profile-picture", "post-attachment"] } }, "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"] }, "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" } } }, "UserRole": { "type": "string", "enum": ["STUDENT", "MODERATOR", "ADMIN"] }, "UserDepartmentEntity": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "code": { "type": "string" } }, "required": ["id", "name", "code"] }, "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, "allOf": [{ "$ref": "#/components/schemas/UserDepartmentEntity" }] }, "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 } }, "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 }, "enrollmentYear": { "type": "number", "nullable": true, "minimum": 1950, "maximum": 2100 } } }, "FollowUserEntity": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "image": { "type": "string", "nullable": true } }, "required": ["id", "name"] }, "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", "ASSIGNMENT"] }, "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", "ASSIGNMENT"] }, "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, "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"] }, "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" } }, "required": ["id", "key", "name", "size", "mimeType", "createdAt", "downloads"] }, "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, "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", "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, "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", "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"] }, "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" } } } }, "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." } } }, "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 }, "createdAt": { "format": "date-time", "type": "string" } }, "required": ["id", "type", "message", "read", "postId", "requestId", "createdAt"] }, "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, "allOf": [{ "$ref": "#/components/schemas/PostRequestAuthorEntity" }] }, "course": { "$ref": "#/components/schemas/PostRequestCourseEntity" }, "fulfilledByPost": { "nullable": true, "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", "ASSIGNMENT"] }, "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, "allOf": [{ "$ref": "#/components/schemas/PostRequestAuthorEntity" }] }, "course": { "$ref": "#/components/schemas/PostRequestCourseEntity" }, "fulfilledByPost": { "nullable": true, "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"] }, "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": "object", "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)" } }, "required": ["id", "slug", "ownerId", "createdAt", "updatedAt", "visibility", "hasPassword"] }, "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" } }, "required": [ "roomSlug", "sessionId", "userId", "displayName", "isAnonymous", "isViewOnly", "ownerId" ] }, "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, "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, "allOf": [{ "$ref": "#/components/schemas/ReportPostEntity" }] }, "reporter": { "nullable": true, "allOf": [{ "$ref": "#/components/schemas/ReportReporterEntity" }] }, "adminAction": { "nullable": true, "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"] }, "ChatMessageUserEntity": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "image": { "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" } }, "required": ["id", "roomId", "userId", "lastReadAt", "joinedAt", "user"] }, "ChatMessageEntity": { "type": "object", "properties": { "id": { "type": "string" }, "roomId": { "type": "string" }, "userId": { "type": "string", "nullable": true }, "type": { "type": "string", "enum": ["TEXT", "IMAGE", "LINK", "SYSTEM"] }, "content": { "type": "string", "nullable": true }, "imageUrl": { "type": "string", "nullable": true }, "linkUrl": { "type": "string", "nullable": true }, "createdAt": { "format": "date-time", "type": "string" }, "updatedAt": { "format": "date-time", "type": "string" }, "user": { "$ref": "#/components/schemas/ChatMessageUserEntity" } }, "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"] }, "CreateRoomDto": { "type": "object", "properties": { "type": { "type": "string", "enum": ["DM", "GROUP"] }, "participantIds": { "type": "array", "items": { "type": "string" } }, "name": { "type": "string" } }, "required": ["type", "participantIds"] }, "SendMessageDto": { "type": "object", "properties": { "content": { "type": "string" }, "type": { "type": "string", "enum": ["TEXT", "IMAGE", "LINK", "SYSTEM"] }, "imageUrl": { "type": "string" }, "linkUrl": { "type": "string" } } }, "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, "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"] }, "QuizListItemEntity": { "type": "object", "properties": { "id": { "type": "string" }, "title": { "type": "string" }, "description": { "type": "string", "nullable": true }, "courseId": { "type": "string" }, "course": { "type": "object" }, "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"] }, "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": { "type": "object" } }, "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"] }, "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"] } } } }