{ "openapi": "3.0.3", "info": { "title": "Alrahma Unified API", "version": "1.0.0", "description": "HTTP endpoints that power the Alrahma platform. Routes are namespaced under `/api/v1` unless noted otherwise." }, "servers": [ { "url": "http://localhost:8000", "description": "Local development server" }, { "url": "https://localhost", "description": "Local HTTPS server" }, { "url": "{scheme}://{host}", "description": "Custom environment", "variables": { "scheme": { "default": "https", "enum": ["http", "https"] }, "host": { "default": "localhost:8000" } } } ], "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" } }, "schemas": { "ErrorResponse": { "type": "object", "properties": { "status": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Validation failed" }, "errors": { "type": "object", "additionalProperties": true } } }, "Pagination": { "type": "object", "properties": { "current_page": { "type": "integer", "example": 1 }, "per_page": { "type": "integer", "example": 20 }, "total": { "type": "integer", "example": 250 }, "total_pages": { "type": "integer", "example": 13 } } }, "PaginatedResponse": { "type": "object", "properties": { "status": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Students retrieved successfully" }, "data": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Student" } }, "pagination": { "$ref": "#/components/schemas/Pagination" } } } } }, "Student": { "type": "object", "properties": { "id": { "type": "integer", "example": 42 }, "firstname": { "type": "string", "example": "Ahmed" }, "lastname": { "type": "string", "example": "Rahman" }, "dob": { "type": "string", "format": "date", "example": "2013-04-22" }, "gender": { "type": "string", "enum": ["male", "female"] }, "parent_id": { "type": "integer" }, "current_class": { "type": "object", "nullable": true } } }, "AttendanceRecord": { "type": "object", "properties": { "id": { "type": "integer", "example": 321 }, "student_id": { "type": "integer", "example": 42 }, "class_section_id": { "type": "integer", "example": 8 }, "date": { "type": "string", "format": "date", "example": "2024-11-01" }, "status": { "type": "string", "enum": ["present", "absent", "late"] }, "notes": { "type": "string", "nullable": true } } }, "Invoice": { "type": "object", "properties": { "id": { "type": "integer", "example": 101 }, "parent_id": { "type": "integer", "example": 55 }, "status": { "type": "string", "example": "pending" }, "balance": { "type": "number", "format": "float", "example": 125.50 }, "description": { "type": "string" }, "school_year": { "type": "string", "example": "2024-2025" }, "semester": { "type": "string", "example": "Fall" } } }, "LoginRequest": { "type": "object", "required": ["email", "password"], "properties": { "email": { "type": "string", "format": "email", "example": "admin@example.com" }, "password": { "type": "string", "example": "secret" } } }, "LoginResponse": { "type": "object", "properties": { "status": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Login successful" }, "data": { "type": "object", "properties": { "token": { "type": "string", "example": "eyJ0eXAiOiJKV1QiLCJh..." }, "expires_in": { "type": "integer", "example": 3600 } } } } }, "RegisterRequest": { "type": "object", "required": ["firstname", "lastname", "email", "password", "captcha_answer"], "properties": { "firstname": { "type": "string", "example": "Yara" }, "lastname": { "type": "string", "example": "Khalil" }, "email": { "type": "string", "format": "email", "example": "parent@example.com" }, "password": { "type": "string", "example": "Str0ngPass!" }, "phone": { "type": "string", "example": "1234567890" }, "captcha_answer": { "type": "string", "example": "42" } } }, "UserSummary": { "type": "object", "properties": { "id": { "type": "integer", "example": 4321 }, "firstname": { "type": "string", "example": "Yara" }, "lastname": { "type": "string", "example": "Khalil" }, "email": { "type": "string", "format": "email", "example": "parent@example.com" }, "school_id": { "type": "string", "example": "SID-AB12CD34" }, "status": { "type": "string", "example": "active" } } }, "RegisterResponse": { "type": "object", "properties": { "status": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "User registered successfully" }, "data": { "type": "object", "properties": { "user": { "$ref": "#/components/schemas/UserSummary" }, "message": { "type": "string", "example": "Registration successful. Please check your email for verification." } } } } }, "ForgotPasswordRequest": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string", "format": "email", "example": "parent@example.com" } } }, "PasswordResetRequest": { "type": "object", "required": ["token", "password", "pass_confirm"], "properties": { "token": { "type": "string", "example": "abc123reset" }, "password": { "type": "string", "example": "Str0ngReset!" }, "pass_confirm": { "type": "string", "example": "Str0ngReset!" } } }, "SetPasswordRequest": { "type": "object", "required": ["user_id", "token", "password", "password_confirm"], "properties": { "user_id": { "type": "integer", "example": 4321 }, "token": { "type": "string", "example": "def456confirm" }, "password": { "type": "string", "example": "NewPass123!" }, "password_confirm": { "type": "string", "example": "NewPass123!" } } }, "MessageResponse": { "type": "object", "properties": { "status": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Check your inbox for the next steps." } } }, "LoginActivityRecord": { "type": "object", "properties": { "user_id": { "type": "integer", "example": 7 }, "email": { "type": "string", "format": "email", "example": "parent@example.com" }, "login_time": { "type": "string", "format": "date-time", "example": "2025-08-15T08:22:41" }, "logout_time": { "type": [ "string", "null" ], "format": "date-time", "example": null }, "ip_address": { "type": "string", "example": "192.0.2.55" }, "user_agent": { "type": "string", "example": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" } } }, "LoginActivityResponse": { "type": "object", "properties": { "status": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "activities": { "type": "array", "items": { "$ref": "#/components/schemas/LoginActivityRecord" } }, "pagination": { "$ref": "#/components/schemas/Pagination" } } }, "message": { "type": "string", "example": "Login activity retrieved" } } }, "WebRegisterForm": { "type": "object", "required": [ "firstname", "lastname", "gender", "email", "confirm_email", "cellphone", "address_street", "city", "state", "zip", "accept_school_policy", "captcha" ], "properties": { "firstname": { "type": "string", "example": "Amina" }, "lastname": { "type": "string", "example": "El-Sayed" }, "gender": { "type": "string", "enum": ["Male", "Female"], "example": "Female" }, "email": { "type": "string", "format": "email", "example": "parent@alrahma.org" }, "confirm_email": { "type": "string", "format": "email", "example": "parent@alrahma.org" }, "cellphone": { "type": "string", "example": "203-555-0147" }, "address_street": { "type": "string", "example": "123 Elm Street" }, "apt": { "type": "string", "example": "Apt 5" }, "city": { "type": "string", "example": "Hartford" }, "state": { "type": "string", "enum": ["CT", "ME", "MA", "NH", "NY", "RI", "VT"], "example": "CT" }, "zip": { "type": "string", "example": "06106" }, "accept_school_policy": { "type": "boolean", "example": true }, "captcha": { "type": "string", "example": "7F3Z" }, "is_parent": { "type": "boolean", "example": true }, "no_second_parent_info": { "type": "boolean", "example": false }, "second_firstname": { "type": "string", "example": "Maya" }, "second_lastname": { "type": "string", "example": "El-Sayed" }, "second_gender": { "type": "string", "enum": ["Male", "Female"], "example": "Female" }, "second_email": { "type": "string", "format": "email", "example": "co-parent@alrahma.org" }, "second_cellphone": { "type": "string", "example": "203-555-0189" } } }, "WebLoginForm": { "type": "object", "required": ["email", "password"], "properties": { "email": { "type": "string", "format": "email", "example": "parent@alrahma.org" }, "password": { "type": "string", "example": "SecurePass123!" } } }, "WebForgotPasswordForm": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string", "format": "email", "example": "parent@alrahma.org" } } }, "WebResetPasswordForm": { "type": "object", "required": ["token", "password", "pass_confirm"], "properties": { "token": { "type": "string", "example": "abc123reset" }, "password": { "type": "string", "example": "Str0ngReset!" }, "pass_confirm": { "type": "string", "example": "Str0ngReset!" } } }, "WebSetPasswordForm": { "type": "object", "required": ["user_id", "token", "password", "password_confirm"], "properties": { "user_id": { "type": "integer", "example": 4321 }, "token": { "type": "string", "example": "def456confirm" }, "password": { "type": "string", "example": "NewPass123!" }, "password_confirm": { "type": "string", "example": "NewPass123!" } } } }, "responses": { "UnauthorizedError": { "description": "Missing or invalid bearer token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "security": [ { "bearerAuth": [] } ], "x-controllers": [ { "name": "AdministratorController", "class": "App\\Http\\Controllers\\Api\\AdministratorController", "path": "app/Http/Controllers/Api/AdministratorController.php" }, { "name": "AssignmentController", "class": "App\\Http\\Controllers\\Api\\AssignmentController", "path": "app/Http/Controllers/Api/AssignmentController.php" }, { "name": "AttendanceController", "class": "App\\Http\\Controllers\\Api\\AttendanceController", "path": "app/Http/Controllers/Api/AttendanceController.php" }, { "name": "AttendanceTrackingController", "class": "App\\Http\\Controllers\\Api\\AttendanceTrackingController", "path": "app/Http/Controllers/Api/AttendanceTrackingController.php" }, { "name": "AuthorizedUsersController", "class": "App\\Http\\Controllers\\Api\\AuthorizedUsersController", "path": "app/Http/Controllers/Api/AuthorizedUsersController.php" }, { "name": "BaseApiController", "class": "App\\Http\\Controllers\\Api\\BaseApiController", "path": "app/Http/Controllers/Api/BaseApiController.php" }, { "name": "BroadcastEmailController", "class": "App\\Http\\Controllers\\Api\\BroadcastEmailController", "path": "app/Http/Controllers/Api/BroadcastEmailController.php" }, { "name": "CalendarController", "class": "App\\Http\\Controllers\\Api\\CalendarController", "path": "app/Http/Controllers/Api/CalendarController.php" }, { "name": "CiRequestAdapter", "class": "App\\Http\\Controllers\\Api\\CiRequestAdapter", "path": "app/Http/Controllers/Api/CiRequestAdapter.php" }, { "name": "ClassController", "class": "App\\Http\\Controllers\\Api\\ClassController", "path": "app/Http/Controllers/Api/ClassController.php" }, { "name": "ClassPreparationController", "class": "App\\Http\\Controllers\\Api\\ClassPreparationController", "path": "app/Http/Controllers/Api/ClassPreparationController.php" }, { "name": "CommunicationController", "class": "App\\Http\\Controllers\\Api\\CommunicationController", "path": "app/Http/Controllers/Api/CommunicationController.php" }, { "name": "ConfigurationController", "class": "App\\Http\\Controllers\\Api\\ConfigurationController", "path": "app/Http/Controllers/Api/ConfigurationController.php" }, { "name": "ContactController", "class": "App\\Http\\Controllers\\Api\\ContactController", "path": "app/Http/Controllers/Api/ContactController.php" }, { "name": "DiscountController", "class": "App\\Http\\Controllers\\Api\\DiscountController", "path": "app/Http/Controllers/Api/DiscountController.php" }, { "name": "EmailController", "class": "App\\Http\\Controllers\\Api\\EmailController", "path": "app/Http/Controllers/Api/EmailController.php" }, { "name": "EmailExtractorController", "class": "App\\Http\\Controllers\\Api\\EmailExtractorController", "path": "app/Http/Controllers/Api/EmailExtractorController.php" }, { "name": "EmergencyContactController", "class": "App\\Http\\Controllers\\Api\\EmergencyContactController", "path": "app/Http/Controllers/Api/EmergencyContactController.php" }, { "name": "EventController", "class": "App\\Http\\Controllers\\Api\\EventController", "path": "app/Http/Controllers/Api/EventController.php" }, { "name": "ExpenseController", "class": "App\\Http\\Controllers\\Api\\ExpenseController", "path": "app/Http/Controllers/Api/ExpenseController.php" }, { "name": "ExtraChargesController", "class": "App\\Http\\Controllers\\Api\\ExtraChargesController", "path": "app/Http/Controllers/Api/ExtraChargesController.php" }, { "name": "FamilyAdminController", "class": "App\\Http\\Controllers\\Api\\FamilyAdminController", "path": "app/Http/Controllers/Api/FamilyAdminController.php" }, { "name": "FamilyController", "class": "App\\Http\\Controllers\\Api\\FamilyController", "path": "app/Http/Controllers/Api/FamilyController.php" }, { "name": "FilesController", "class": "App\\Http\\Controllers\\Api\\FilesController", "path": "app/Http/Controllers/Api/FilesController.php" }, { "name": "FinalController", "class": "App\\Http\\Controllers\\Api\\FinalController", "path": "app/Http/Controllers/Api/FinalController.php" }, { "name": "FinancialController", "class": "App\\Http\\Controllers\\Api\\FinancialController", "path": "app/Http/Controllers/Api/FinancialController.php" }, { "name": "FlagController", "class": "App\\Http\\Controllers\\Api\\FlagController", "path": "app/Http/Controllers/Api/FlagController.php" }, { "name": "FrontendController", "class": "App\\Http\\Controllers\\Api\\FrontendController", "path": "app/Http/Controllers/Api/FrontendController.php" }, { "name": "GradingController", "class": "App\\Http\\Controllers\\Api\\GradingController", "path": "app/Http/Controllers/Api/GradingController.php" }, { "name": "HealthController", "class": "App\\Http\\Controllers\\Api\\HealthController", "path": "app/Http/Controllers/Api/HealthController.php" }, { "name": "HomeworkController", "class": "App\\Http\\Controllers\\Api\\HomeworkController", "path": "app/Http/Controllers/Api/HomeworkController.php" }, { "name": "HomeworkTrackingController", "class": "App\\Http\\Controllers\\Api\\HomeworkTrackingController", "path": "app/Http/Controllers/Api/HomeworkTrackingController.php" }, { "name": "InventoryController", "class": "App\\Http\\Controllers\\Api\\InventoryController", "path": "app/Http/Controllers/Api/InventoryController.php" }, { "name": "InvoiceController", "class": "App\\Http\\Controllers\\Api\\InvoiceController", "path": "app/Http/Controllers/Api/InvoiceController.php" }, { "name": "IpBanController", "class": "App\\Http\\Controllers\\Api\\IpBanController", "path": "app/Http/Controllers/Api/IpBanController.php" }, { "name": "LandingPageController", "class": "App\\Http\\Controllers\\Api\\LandingPageController", "path": "app/Http/Controllers/Api/LandingPageController.php" }, { "name": "LateSlipLogsController", "class": "App\\Http\\Controllers\\Api\\LateSlipLogsController", "path": "app/Http/Controllers/Api/LateSlipLogsController.php" }, { "name": "MessageController", "class": "App\\Http\\Controllers\\Api\\MessageController", "path": "app/Http/Controllers/Api/MessageController.php" }, { "name": "MessagesController", "class": "App\\Http\\Controllers\\Api\\MessagesController", "path": "app/Http/Controllers/Api/MessagesController.php" }, { "name": "MessagingController", "class": "App\\Http\\Controllers\\Api\\MessagingController", "path": "app/Http/Controllers/Api/MessagingController.php" }, { "name": "NavBuilderController", "class": "App\\Http\\Controllers\\Api\\NavBuilderController", "path": "app/Http/Controllers/Api/NavBuilderController.php" }, { "name": "NotificationController", "class": "App\\Http\\Controllers\\Api\\NotificationController", "path": "app/Http/Controllers/Api/NotificationController.php" }, { "name": "NotificationsController", "class": "App\\Http\\Controllers\\Api\\NotificationsController", "path": "app/Http/Controllers/Api/NotificationsController.php" }, { "name": "PageController", "class": "App\\Http\\Controllers\\Api\\PageController", "path": "app/Http/Controllers/Api/PageController.php" }, { "name": "ParentAttendanceReportController", "class": "App\\Http\\Controllers\\Api\\ParentAttendanceReportController", "path": "app/Http/Controllers/Api/ParentAttendanceReportController.php" }, { "name": "ParentController", "class": "App\\Http\\Controllers\\Api\\ParentController", "path": "app/Http/Controllers/Api/ParentController.php" }, { "name": "ParticipationController", "class": "App\\Http\\Controllers\\Api\\ParticipationController", "path": "app/Http/Controllers/Api/ParticipationController.php" }, { "name": "PaymentController", "class": "App\\Http\\Controllers\\Api\\PaymentController", "path": "app/Http/Controllers/Api/PaymentController.php" }, { "name": "PaymentNotificationController", "class": "App\\Http\\Controllers\\Api\\PaymentNotificationController", "path": "app/Http/Controllers/Api/PaymentNotificationController.php" }, { "name": "PaymentTransactionController", "class": "App\\Http\\Controllers\\Api\\PaymentTransactionController", "path": "app/Http/Controllers/Api/PaymentTransactionController.php" }, { "name": "PaypalTransactionsController", "class": "App\\Http\\Controllers\\Api\\PaypalTransactionsController", "path": "app/Http/Controllers/Api/PaypalTransactionsController.php" }, { "name": "PaypalWebhook", "class": "App\\Http\\Controllers\\Api\\PaypalWebhook", "path": "app/Http/Controllers/Api/PaypalWebhook.php" }, { "name": "PolicyController", "class": "App\\Http\\Controllers\\Api\\PolicyController", "path": "app/Http/Controllers/Api/PolicyController.php" }, { "name": "PreferencesController", "class": "App\\Http\\Controllers\\Api\\PreferencesController", "path": "app/Http/Controllers/Api/PreferencesController.php" }, { "name": "PrintablesReportsController", "class": "App\\Http\\Controllers\\Api\\PrintablesReportsController", "path": "app/Http/Controllers/Api/PrintablesReportsController.php" }, { "name": "ProjectController", "class": "App\\Http\\Controllers\\Api\\ProjectController", "path": "app/Http/Controllers/Api/ProjectController.php" }, { "name": "PurchaseOrderController", "class": "App\\Http\\Controllers\\Api\\PurchaseOrderController", "path": "app/Http/Controllers/Api/PurchaseOrderController.php" }, { "name": "QuizController", "class": "App\\Http\\Controllers\\Api\\QuizController", "path": "app/Http/Controllers/Api/QuizController.php" }, { "name": "RFIDController", "class": "App\\Http\\Controllers\\Api\\RFIDController", "path": "app/Http/Controllers/Api/RFIDController.php" }, { "name": "RefundController", "class": "App\\Http\\Controllers\\Api\\RefundController", "path": "app/Http/Controllers/Api/RefundController.php" }, { "name": "RegisterController", "class": "App\\Http\\Controllers\\Api\\RegisterController", "path": "app/Http/Controllers/Api/RegisterController.php" }, { "name": "ReimbursementController", "class": "App\\Http\\Controllers\\Api\\ReimbursementController", "path": "app/Http/Controllers/Api/ReimbursementController.php" }, { "name": "RolePermissionController", "class": "App\\Http\\Controllers\\Api\\RolePermissionController", "path": "app/Http/Controllers/Api/RolePermissionController.php" }, { "name": "RoleSwitcherController", "class": "App\\Http\\Controllers\\Api\\RoleSwitcherController", "path": "app/Http/Controllers/Api/RoleSwitcherController.php" }, { "name": "SchoolCalendarController", "class": "App\\Http\\Controllers\\Api\\SchoolCalendarController", "path": "app/Http/Controllers/Api/SchoolCalendarController.php" }, { "name": "ScoreCommentController", "class": "App\\Http\\Controllers\\Api\\ScoreCommentController", "path": "app/Http/Controllers/Api/ScoreCommentController.php" }, { "name": "ScoreController", "class": "App\\Http\\Controllers\\Api\\ScoreController", "path": "app/Http/Controllers/Api/ScoreController.php" }, { "name": "ScorePredictorController", "class": "App\\Http\\Controllers\\Api\\ScorePredictorController", "path": "app/Http/Controllers/Api/ScorePredictorController.php" }, { "name": "SendSMSController", "class": "App\\Http\\Controllers\\Api\\SendSMSController", "path": "app/Http/Controllers/Api/SendSMSController.php" }, { "name": "SessionController", "class": "App\\Http\\Controllers\\Api\\SessionController", "path": "app/Http/Controllers/Api/SessionController.php" }, { "name": "SessionTimeoutController", "class": "App\\Http\\Controllers\\Api\\SessionTimeoutController", "path": "app/Http/Controllers/Api/SessionTimeoutController.php" }, { "name": "SettingsController", "class": "App\\Http\\Controllers\\Api\\SettingsController", "path": "app/Http/Controllers/Api/SettingsController.php" }, { "name": "SlipPrinterController", "class": "App\\Http\\Controllers\\Api\\SlipPrinterController", "path": "app/Http/Controllers/Api/SlipPrinterController.php" }, { "name": "StaffController", "class": "App\\Http\\Controllers\\Api\\StaffController", "path": "app/Http/Controllers/Api/StaffController.php" }, { "name": "StatsController", "class": "App\\Http\\Controllers\\Api\\StatsController", "path": "app/Http/Controllers/Api/StatsController.php" }, { "name": "StudentController", "class": "App\\Http\\Controllers\\Api\\StudentController", "path": "app/Http/Controllers/Api/StudentController.php" }, { "name": "SupplierController", "class": "App\\Http\\Controllers\\Api\\SupplierController", "path": "app/Http/Controllers/Api/SupplierController.php" }, { "name": "SupplyCategoryController", "class": "App\\Http\\Controllers\\Api\\SupplyCategoryController", "path": "app/Http/Controllers/Api/SupplyCategoryController.php" }, { "name": "SupportController", "class": "App\\Http\\Controllers\\Api\\SupportController", "path": "app/Http/Controllers/Api/SupportController.php" }, { "name": "TeacherController", "class": "App\\Http\\Controllers\\Api\\TeacherController", "path": "app/Http/Controllers/Api/TeacherController.php" }, { "name": "TestDBController", "class": "App\\Http\\Controllers\\Api\\TestDBController", "path": "app/Http/Controllers/Api/TestDBController.php" }, { "name": "TimeController", "class": "App\\Http\\Controllers\\Api\\TimeController", "path": "app/Http/Controllers/Api/TimeController.php" }, { "name": "UiController", "class": "App\\Http\\Controllers\\Api\\UiController", "path": "app/Http/Controllers/Api/UiController.php" }, { "name": "UserController", "class": "App\\Http\\Controllers\\Api\\UserController", "path": "app/Http/Controllers/Api/UserController.php" }, { "name": "WhatsappController", "class": "App\\Http\\Controllers\\Api\\WhatsappController", "path": "app/Http/Controllers/Api/WhatsappController.php" }, { "name": "AuthController", "class": "App\\Http\\Controllers\\Api\\Auth\\AuthController", "path": "app/Http/Controllers/Api/Auth/AuthController.php" } ], "paths": { "/api/v1/register": { "post": { "operationId": "register", "tags": ["Auth"], "summary": "Create a parent account and trigger email verification", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterRequest" } } } }, "responses": { "201": { "description": "Parent account created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterResponse" } } } }, "422": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/auth/forgot-password": { "post": { "operationId": "forgotPassword", "tags": ["Auth"], "summary": "Request a password reset link", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ForgotPasswordRequest" } } } }, "responses": { "200": { "description": "Email sent (or queued)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "422": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/auth/reset-password": { "post": { "operationId": "resetPassword", "tags": ["Auth"], "summary": "Submit a new password using the reset token received via email", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PasswordResetRequest" } } } }, "responses": { "200": { "description": "Password changed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "422": { "description": "Validation or token error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/auth/set-password": { "post": { "operationId": "setPassword", "tags": ["Auth"], "summary": "Complete account setup by choosing a new password after email confirmation", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetPasswordRequest" } } } }, "responses": { "200": { "description": "Password saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "422": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/auth/login": { "post": { "operationId": "login", "tags": ["Auth"], "summary": "Issue a JWT for a valid user", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginRequest" } } } }, "responses": { "200": { "description": "Authentication successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginResponse" } } } }, "401": { "description": "Invalid credentials", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [] } }, "/api/v1/auth/me": { "get": { "operationId": "getCurrentUser", "tags": ["Auth"], "summary": "Return the authenticated user's profile", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Profile data" }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } } }, "/api/v1/auth/logout": { "post": { "operationId": "logout", "tags": ["Auth"], "summary": "Revoke the active token", "security": [ { "bearerAuth": [] } ], "responses": { "204": { "description": "Token revoked" }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } } }, "/api/v1/users/login-activity": { "get": { "operationId": "getLoginActivity", "tags": ["Users"], "summary": "Retrieve parent login activities for the management portal", "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 25 } } ], "responses": { "200": { "description": "Paginated login activity recorded for parents", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginActivityResponse" } } } }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } } }, "/api/v1/users": { "get": { "operationId": "listUsers", "tags": ["Users"], "summary": "List users", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 20 } }, { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["id", "firstname", "lastname", "email", "role"] } }, { "name": "order", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"] } } ], "responses": { "200": { "description": "Paginated user list" }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } }, "post": { "operationId": "createUser", "tags": ["Users"], "summary": "Create a new user", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["firstname", "lastname", "email", "password", "cellphone", "address_street", "city", "state", "zip", "accept_school_policy", "role_id"], "properties": { "firstname": {"type": "string"}, "lastname": {"type": "string"}, "email": {"type": "string", "format": "email"}, "password": {"type": "string"}, "cellphone": {"type": "string"}, "address_street": {"type": "string"}, "city": {"type": "string"}, "state": {"type": "string"}, "zip": {"type": "string"}, "accept_school_policy": {"type": "boolean"}, "role_id": {"type": "integer"} } } } } }, "responses": { "201": {"description": "User created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/students": { "get": { "operationId": "listStudents", "tags": ["Students"], "summary": "List students for the current school year", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 20 } }, { "name": "parent_id", "in": "query", "schema": { "type": "integer" } }, { "name": "class_id", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Paginated students", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedResponse" } } } }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } }, "post": { "operationId": "createStudent", "tags": ["Students"], "summary": "Register a new student", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Student" } } } }, "responses": { "201": { "description": "Student created" }, "401": { "$ref": "#/components/responses/UnauthorizedError" }, "422": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/students/{id}": { "get": { "operationId": "getStudent", "tags": ["Students"], "summary": "Retrieve a single student", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Student details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Student" } } } }, "401": { "$ref": "#/components/responses/UnauthorizedError" }, "404": { "description": "Not found" } } }, "patch": { "operationId": "updateStudent", "tags": ["Students"], "summary": "Update a student", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "firstname": {"type": "string"}, "lastname": {"type": "string"}, "dob": {"type": "string", "format": "date"}, "gender": {"type": "string", "enum": ["male", "female"]}, "parent_id": {"type": "integer"} } } } } }, "responses": { "200": {"description": "Student updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } }, "delete": { "operationId": "deleteStudent", "tags": ["Students"], "summary": "Delete a student", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Student deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/attendance": { "get": { "operationId": "listAttendance", "tags": ["Attendance"], "summary": "List attendance records", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 20 } }, { "name": "student_id", "in": "query", "schema": { "type": "integer" } }, { "name": "date", "in": "query", "schema": { "type": "string", "format": "date" } } ], "responses": { "200": { "description": "Paginated attendance records", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedResponse" } } } }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } }, "post": { "operationId": "createAttendance", "tags": ["Attendance"], "summary": "Create an attendance record", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AttendanceRecord" } } } }, "responses": { "201": { "description": "Record created" }, "401": { "$ref": "#/components/responses/UnauthorizedError" }, "409": { "description": "Duplicate for student/date" } } } }, "/api/v1/invoices": { "get": { "operationId": "listInvoices", "tags": ["Invoices"], "summary": "List invoices", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 20 } }, { "name": "parent_id", "in": "query", "schema": { "type": "integer" } }, { "name": "status", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Paginated invoices", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedResponse" } } } }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } }, "post": { "operationId": "createInvoice", "tags": ["Invoices"], "summary": "Create an invoice", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Invoice" } } } }, "responses": { "201": { "description": "Invoice created" }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } } }, "/api/v1/invoices/{id}": { "get": { "operationId": "getInvoice", "tags": ["Invoices"], "summary": "Show a single invoice", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Invoice details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Invoice" } } } }, "401": { "$ref": "#/components/responses/UnauthorizedError" }, "404": { "description": "Not found" } } }, "patch": { "operationId": "updateInvoice", "tags": ["Invoices"], "summary": "Update invoice attributes", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Invoice" } } } }, "responses": { "200": { "description": "Invoice updated" }, "401": { "$ref": "#/components/responses/UnauthorizedError" } } }, "delete": { "operationId": "deleteInvoice", "tags": ["Invoices"], "summary": "Delete an invoice", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Invoice deleted" }, "401": { "$ref": "#/components/responses/UnauthorizedError" }, "404": { "description": "Not found" } } } }, "/register": { "post": { "operationId": "webRegister", "tags": ["Web"], "summary": "Submit the legacy parent registration form", "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WebRegisterForm" } } } }, "responses": { "302": { "description": "Redirects to /register/success when registration completes." }, "422": { "description": "Validation issues cause a redirect back to the form with flash errors." } } } }, "/user/login": { "post": { "operationId": "webLogin", "tags": ["Web"], "summary": "Submit the legacy login form", "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WebLoginForm" } } } }, "responses": { "302": { "description": "Redirects to the dashboard when authentication succeeds." }, "401": { "description": "Invalid credentials or suspended account results in a redirect back with flash information." } } } }, "/processForgotPassword": { "post": { "operationId": "webForgotPassword", "tags": ["Web"], "summary": "Request a password reset link via the legacy form", "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WebForgotPasswordForm" } } } }, "responses": { "302": { "description": "Always redirects back to the form; success is indicated via flash data." } } } }, "/user/processResetPassword": { "post": { "operationId": "webResetPassword", "tags": ["Web"], "summary": "Submit a new password using the reset token from the email", "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WebResetPasswordForm" } } } }, "responses": { "200": { "description": "Renders the 'password_set_success' view when the token is valid." }, "302": { "description": "Invalid token or validation errors redirect to the home page or form." } } } }, "/user/save_password": { "post": { "operationId": "webSetPassword", "tags": ["Web"], "summary": "Save the password after confirming the email address", "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WebSetPasswordForm" } } } }, "responses": { "302": { "description": "Redirects to /user/password_set_success on success or back on failure." } } } }, "/api/v1/administrator/dashboard": { "get": { "operationId": "getAdministratorDashboard", "tags": ["Administrator"], "summary": "Returns counts for students, staff roles, and parents plus the four most recent login activities", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Dashboard data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/administrator/absence": { "get": { "operationId": "getAdministratorAbsence", "tags": ["Administrator"], "summary": "Get absence form data", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Absence form data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "submitAdministratorAbsence", "tags": ["Administrator"], "summary": "Submit absence request", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["dates", "reason"], "properties": { "dates": {"type": "array", "items": {"type": "string", "format": "date"}}, "reason_type": {"type": "string"}, "reason": {"type": "string"} } } } } }, "responses": { "200": {"description": "Absence submitted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/administrator/search": { "get": { "operationId": "searchAdministrator", "tags": ["Administrator"], "summary": "Search across users, students, parents, staff, and emergency contacts", "security": [{"bearerAuth": []}], "parameters": [{ "name": "q", "in": "query", "required": true, "schema": {"type": "string"} }], "responses": { "200": {"description": "Search results"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/assignments": { "get": { "operationId": "listAssignments", "tags": ["Assignments"], "summary": "List assignments", "security": [{"bearerAuth": []}], "parameters": [ {"name": "class_id", "in": "query", "schema": {"type": "integer"}}, {"name": "teacher_id", "in": "query", "schema": {"type": "integer"}}, {"name": "student_id", "in": "query", "schema": {"type": "integer"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated assignments"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createAssignment", "tags": ["Assignments"], "summary": "Create an assignment", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["title", "due_date", "class_id", "teacher_id"], "properties": { "title": {"type": "string"}, "due_date": {"type": "string", "format": "date"}, "class_id": {"type": "integer"}, "teacher_id": {"type": "integer"} } } } } }, "responses": { "201": {"description": "Assignment created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/assignments/{id}": { "get": { "operationId": "getAssignment", "tags": ["Assignments"], "summary": "Get a single assignment", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Assignment details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateAssignment", "tags": ["Assignments"], "summary": "Update an assignment", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": {"type": "string"}, "due_date": {"type": "string", "format": "date"}, "class_id": {"type": "integer"}, "teacher_id": {"type": "integer"} } } } } }, "responses": { "200": {"description": "Assignment updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteAssignment", "tags": ["Assignments"], "summary": "Delete an assignment", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Assignment deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/attendance/{id}": { "get": { "operationId": "getAttendance", "tags": ["Attendance"], "summary": "Get a single attendance record", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Attendance record"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateAttendance", "tags": ["Attendance"], "summary": "Update an attendance record", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": {"type": "string", "enum": ["present", "absent", "late"]}, "notes": {"type": "string"} } } } } }, "responses": { "200": {"description": "Attendance record updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteAttendance", "tags": ["Attendance"], "summary": "Delete an attendance record", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Attendance record deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/attendance/class/{class_section_id}": { "get": { "operationId": "getClassAttendance", "tags": ["Attendance"], "summary": "Get class roster with attendance status", "security": [{"bearerAuth": []}], "parameters": [ {"name": "class_section_id", "in": "path", "required": true, "schema": {"type": "integer"}}, {"name": "date", "in": "query", "schema": {"type": "string", "format": "date"}} ], "responses": { "200": {"description": "Class roster with attendance"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/attendance/class/{class_section_id}/record": { "post": { "operationId": "recordClassAttendance", "tags": ["Attendance"], "summary": "Record attendance for multiple students in a class", "security": [{"bearerAuth": []}], "parameters": [{"name": "class_section_id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["date", "records"], "properties": { "date": {"type": "string", "format": "date"}, "records": { "type": "array", "items": { "type": "object", "required": ["student_id", "status"], "properties": { "student_id": {"type": "integer"}, "status": {"type": "string", "enum": ["present", "absent", "late"]}, "reason": {"type": "string"} } } } } } } } }, "responses": { "200": {"description": "Attendance recorded"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/classes": { "get": { "operationId": "listClasses", "tags": ["Classes"], "summary": "List classes", "security": [{"bearerAuth": []}], "parameters": [ {"name": "grade", "in": "query", "schema": {"type": "string"}}, {"name": "teacher_id", "in": "query", "schema": {"type": "integer"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated classes"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/classes/{id}": { "get": { "operationId": "getClass", "tags": ["Classes"], "summary": "Get a single class", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Class details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/classes/{id}/students": { "get": { "operationId": "getClassStudents", "tags": ["Classes"], "summary": "Get students in a class", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "List of students"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/calendar": { "get": { "operationId": "listCalendarEvents", "tags": ["Calendar"], "summary": "List calendar events", "security": [{"bearerAuth": []}], "parameters": [ {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}}, {"name": "month", "in": "query", "schema": {"type": "integer"}}, {"name": "year", "in": "query", "schema": {"type": "integer"}} ], "responses": { "200": {"description": "Paginated calendar events"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createCalendarEvent", "tags": ["Calendar"], "summary": "Create a calendar event", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["title", "start_date"], "properties": { "title": {"type": "string"}, "start_date": {"type": "string", "format": "date"}, "description": {"type": "string"}, "end_date": {"type": "string", "format": "date"}, "location": {"type": "string"} } } } } }, "responses": { "201": {"description": "Event created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/calendar/{id}": { "get": { "operationId": "getCalendarEvent", "tags": ["Calendar"], "summary": "Get a single calendar event", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Event details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateCalendarEvent", "tags": ["Calendar"], "summary": "Update a calendar event", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": {"type": "string"}, "start_date": {"type": "string", "format": "date"}, "description": {"type": "string"}, "end_date": {"type": "string", "format": "date"}, "location": {"type": "string"} } } } } }, "responses": { "200": {"description": "Event updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteCalendarEvent", "tags": ["Calendar"], "summary": "Delete a calendar event", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Event deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/contact": { "post": { "operationId": "submitContact", "tags": ["Contact"], "summary": "Submit contact form", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["name", "email", "subject", "message"], "properties": { "name": {"type": "string"}, "email": {"type": "string", "format": "email"}, "subject": {"type": "string"}, "message": {"type": "string"} } } } } }, "responses": { "200": {"description": "Contact form submitted"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}, "500": {"description": "Server error"} }, "security": [] } }, "/api/v1/payments": { "get": { "operationId": "listPayments", "tags": ["Payments"], "summary": "List payments with optional filters", "security": [{"bearerAuth": []}], "parameters": [ {"name": "parent_id", "in": "query", "schema": {"type": "integer"}}, {"name": "status", "in": "query", "schema": {"type": "string"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated payments"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createPayment", "tags": ["Payments"], "summary": "Create a new payment plan", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["parent_id", "total_amount", "payment_date"], "properties": { "parent_id": {"type": "integer"}, "total_amount": {"type": "number"}, "payment_date": {"type": "string", "format": "date"}, "number_of_installments": {"type": "integer"}, "payment_type": {"type": "string"}, "semester": {"type": "string"}, "school_year": {"type": "string"} } } } } }, "responses": { "201": {"description": "Payment created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/payments/{id}": { "get": { "operationId": "getPayment", "tags": ["Payments"], "summary": "Get a single payment", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Payment details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updatePayment", "tags": ["Payments"], "summary": "Update payment fields", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "paid_amount": {"type": "number"}, "balance": {"type": "number"}, "status": {"type": "string"}, "payment_method": {"type": "string"}, "payment_date": {"type": "string", "format": "date"}, "check_number": {"type": "string"} } } } } }, "responses": { "200": {"description": "Payment updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deletePayment", "tags": ["Payments"], "summary": "Delete a payment", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Payment deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/payments/parent/{id}": { "get": { "operationId": "getPaymentsByParent", "tags": ["Payments"], "summary": "Get all payments for a specific parent", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Parent payments"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/payments/manual-pay-search": { "get": { "operationId": "searchManualPayment", "tags": ["Payments"], "summary": "Search for parent by email or phone and retrieve payment data", "security": [{"bearerAuth": []}], "parameters": [{"name": "search_term", "in": "query", "required": true, "schema": {"type": "string"}}], "responses": { "200": {"description": "Payment search results"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/payments/manual-pay-update": { "post": { "operationId": "updateManualPayment", "tags": ["Payments"], "summary": "Record a manual payment", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["invoice_id", "amount", "payment_method"], "properties": { "invoice_id": {"type": "integer"}, "amount": {"type": "number"}, "payment_method": {"type": "string", "enum": ["cash", "check", "card"]}, "check_number": {"type": "string"}, "payment_date": {"type": "string", "format": "date"} } } } } }, "responses": { "200": {"description": "Payment recorded"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/users/with-roles": { "get": { "operationId": "listUsersWithRoles", "tags": ["Users"], "summary": "List users with their roles", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Users with roles"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/users/{id}": { "patch": { "operationId": "updateUser", "tags": ["Users"], "summary": "Update user account/profile", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "firstname": {"type": "string"}, "lastname": {"type": "string"}, "email": {"type": "string", "format": "email"}, "cellphone": {"type": "string"}, "address_street": {"type": "string"}, "city": {"type": "string"}, "state": {"type": "string"}, "zip": {"type": "string"} } } } } }, "responses": { "200": {"description": "User updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteUser", "tags": ["Users"], "summary": "Delete a user", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "User deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/users/login-activity": { "get": { "operationId": "getUserLoginActivity", "tags": ["Users"], "summary": "Get paginated login history", "security": [{"bearerAuth": []}], "parameters": [ {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 25}} ], "responses": { "200": {"description": "Login activity"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/users/select-role": { "post": { "operationId": "selectUserRole", "tags": ["Users"], "summary": "Select and update the logged-in user's role", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["role"], "properties": { "role": {"type": "string"} } } } } }, "responses": { "200": {"description": "Role selected"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/user/profile": { "get": { "operationId": "getUserProfile", "tags": ["Users"], "summary": "Get the signed-in user's profile", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "User profile"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "patch": { "operationId": "updateUserProfile", "tags": ["Users"], "summary": "Update user profile", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "firstname": {"type": "string"}, "lastname": {"type": "string"}, "cellphone": {"type": "string"}, "address_street": {"type": "string"}, "apt": {"type": "string"}, "city": {"type": "string"}, "state": {"type": "string"}, "zip": {"type": "string"}, "gender": {"type": "string"}, "email": {"type": "string", "format": "email"}, "password": {"type": "string"}, "current_password": {"type": "string"} } } } } }, "responses": { "200": {"description": "Profile updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/teachers": { "get": { "operationId": "listTeachers", "tags": ["Teachers"], "summary": "List teachers and teacher assistants", "security": [{"bearerAuth": []}], "parameters": [ {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated teachers"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/teachers/{id}": { "get": { "operationId": "getTeacher", "tags": ["Teachers"], "summary": "Get teacher details with class assignments", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Teacher details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/teachers/{id}/classes": { "get": { "operationId": "getTeacherClasses", "tags": ["Teachers"], "summary": "Get class sections assigned to a teacher", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Teacher classes"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/teachers/class-view": { "get": { "operationId": "getTeacherClassView", "tags": ["Teachers"], "summary": "Get comprehensive class view data for logged-in teacher", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Class view data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/teachers/absence-form": { "get": { "operationId": "getTeacherAbsenceForm", "tags": ["Teachers"], "summary": "Get absence form data for logged-in teacher", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Absence form data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/teachers/absence": { "post": { "operationId": "submitTeacherAbsence", "tags": ["Teachers"], "summary": "Submit an absence/vacation request", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["dates", "reason"], "properties": { "dates": {"type": "array", "items": {"type": "string", "format": "date"}}, "reason": {"type": "string"}, "reason_type": {"type": "string"} } } } } }, "responses": { "200": {"description": "Absence submitted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/whatsapp": { "get": { "operationId": "getWhatsAppData", "tags": ["WhatsApp"], "summary": "Get initial data for WhatsApp management page", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "WhatsApp management data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/whatsapp/links": { "get": { "operationId": "listWhatsAppLinks", "tags": ["WhatsApp"], "summary": "List WhatsApp invite links", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "WhatsApp links"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "saveWhatsAppLink", "tags": ["WhatsApp"], "summary": "Create or update invite link for a class section", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["class_section_id", "invite_link"], "properties": { "class_section_id": {"type": "integer"}, "invite_link": {"type": "string"}, "active": {"type": "integer", "enum": [0, 1]}, "class_section_name": {"type": "string"} } } } } }, "responses": { "200": {"description": "Link saved"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/whatsapp/send-invites": { "post": { "operationId": "sendWhatsAppInvites", "tags": ["WhatsApp"], "summary": "Send WhatsApp invites in three modes", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["mode"], "properties": { "mode": {"type": "string", "enum": ["parents", "class", "all"]}, "parent_ids": {"type": "array", "items": {"type": "integer"}}, "class_section_id": {"type": "integer"} } } } } }, "responses": { "200": {"description": "Invites sent"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/whatsapp/parent-contacts": { "get": { "operationId": "getWhatsAppParentContacts", "tags": ["WhatsApp"], "summary": "Get flat list of all parent contacts", "security": [{"bearerAuth": []}], "parameters": [ {"name": "school_year", "in": "query", "schema": {"type": "string"}}, {"name": "semester", "in": "query", "schema": {"type": "string"}} ], "responses": { "200": {"description": "Parent contacts"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/whatsapp/parent-contacts-by-class": { "get": { "operationId": "getWhatsAppParentContactsByClass", "tags": ["WhatsApp"], "summary": "Get parent contacts grouped by class section", "security": [{"bearerAuth": []}], "parameters": [ {"name": "school_year", "in": "query", "schema": {"type": "string"}}, {"name": "semester", "in": "query", "schema": {"type": "string"}} ], "responses": { "200": {"description": "Parent contacts by class"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/whatsapp/memberships": { "post": { "operationId": "updateWhatsAppMembership", "tags": ["WhatsApp"], "summary": "Update WhatsApp group membership flags", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["class_section_id"], "properties": { "class_section_id": {"type": "integer"}, "primary_id": {"type": "integer"}, "second_id": {"type": "integer"}, "primary_member": {"type": ["string", "integer"]}, "second_member": {"type": ["string", "integer"]}, "school_year": {"type": "string"}, "semester": {"type": "string"} } } } } }, "responses": { "200": {"description": "Membership updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/health": { "get": { "operationId": "healthCheck", "tags": ["Health"], "summary": "Health check endpoint", "responses": { "200": {"description": "Health status"}, "503": {"description": "Service unavailable"} }, "security": [] } }, "/api/v1/landing": { "get": { "operationId": "getLandingPage", "tags": ["Landing"], "summary": "Get role-based dashboard data", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Landing page data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/landing/data": { "get": { "operationId": "getLandingPageData", "tags": ["Landing"], "summary": "Get basic landing page bootstrap data", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Landing page data"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/staff": { "get": { "operationId": "listStaff", "tags": ["Staff"], "summary": "List staff members", "security": [{"bearerAuth": []}], "parameters": [ {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}}, {"name": "role", "in": "query", "schema": {"type": "string"}} ], "responses": { "200": {"description": "Paginated staff"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createStaff", "tags": ["Staff"], "summary": "Create a new staff member", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["firstname", "lastname", "email", "role_name"], "properties": { "firstname": {"type": "string"}, "lastname": {"type": "string"}, "email": {"type": "string", "format": "email"}, "phone": {"type": "string"}, "role_name": {"type": "string"}, "school_year": {"type": "string"}, "status": {"type": "string"} } } } } }, "responses": { "201": {"description": "Staff created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/staff/{id}": { "get": { "operationId": "getStaff", "tags": ["Staff"], "summary": "Get a single staff member", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Staff details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateStaff", "tags": ["Staff"], "summary": "Update a staff member", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "firstname": {"type": "string"}, "lastname": {"type": "string"}, "email": {"type": "string", "format": "email"}, "phone": {"type": "string"}, "role_name": {"type": "string"}, "school_year": {"type": "string"}, "status": {"type": "string"} } } } } }, "responses": { "200": {"description": "Staff updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteStaff", "tags": ["Staff"], "summary": "Delete a staff member", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Staff deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/suppliers": { "get": { "operationId": "listSuppliers", "tags": ["Suppliers"], "summary": "List suppliers", "security": [{"bearerAuth": []}], "parameters": [ {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}}, {"name": "q", "in": "query", "schema": {"type": "string"}} ], "responses": { "200": {"description": "Paginated suppliers"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createSupplier", "tags": ["Suppliers"], "summary": "Create a new supplier", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["name"], "properties": { "name": {"type": "string"}, "email": {"type": "string", "format": "email"}, "phone": {"type": "string"}, "address": {"type": "string"}, "notes": {"type": "string"} } } } } }, "responses": { "201": {"description": "Supplier created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/suppliers/{id}": { "get": { "operationId": "getSupplier", "tags": ["Suppliers"], "summary": "Get a single supplier", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Supplier details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateSupplier", "tags": ["Suppliers"], "summary": "Update a supplier", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": {"type": "string"}, "email": {"type": "string", "format": "email"}, "phone": {"type": "string"}, "address": {"type": "string"}, "notes": {"type": "string"} } } } } }, "responses": { "200": {"description": "Supplier updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteSupplier", "tags": ["Suppliers"], "summary": "Delete a supplier", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Supplier deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/communications": { "get": { "operationId": "listCommunications", "tags": ["Communications"], "summary": "List communications", "security": [{"bearerAuth": []}], "parameters": [ {"name": "sender_id", "in": "query", "schema": {"type": "integer"}}, {"name": "receiver_id", "in": "query", "schema": {"type": "integer"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated communications"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "sendCommunication", "tags": ["Communications"], "summary": "Send a communication", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["sender_id", "receiver_id", "subject", "message"], "properties": { "sender_id": {"type": "integer"}, "receiver_id": {"type": "integer"}, "subject": {"type": "string"}, "message": {"type": "string"} } } } } }, "responses": { "201": {"description": "Communication sent"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/communications/{id}": { "delete": { "operationId": "deleteCommunication", "tags": ["Communications"], "summary": "Delete a communication", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Communication deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/configuration": { "get": { "operationId": "listConfiguration", "tags": ["Configuration"], "summary": "List configuration entries", "security": [{"bearerAuth": []}], "parameters": [ {"name": "key", "in": "query", "schema": {"type": "string"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated configuration"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createConfiguration", "tags": ["Configuration"], "summary": "Create a configuration entry", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["config_key", "config_value"], "properties": { "config_key": {"type": "string"}, "config_value": {"type": "string"} } } } } }, "responses": { "201": {"description": "Configuration created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/configuration/{id}": { "get": { "operationId": "getConfiguration", "tags": ["Configuration"], "summary": "Get a configuration entry", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Configuration details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateConfiguration", "tags": ["Configuration"], "summary": "Update a configuration entry", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "config_key": {"type": "string"}, "config_value": {"type": "string"} } } } } }, "responses": { "200": {"description": "Configuration updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteConfiguration", "tags": ["Configuration"], "summary": "Delete a configuration entry", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Configuration deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/configuration/key/{config_key}": { "get": { "operationId": "getConfigurationByKey", "tags": ["Configuration"], "summary": "Get configuration by key", "security": [{"bearerAuth": []}], "parameters": [{"name": "config_key", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": { "200": {"description": "Configuration value"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/discounts": { "get": { "operationId": "listDiscounts", "tags": ["Discounts"], "summary": "List discount vouchers", "security": [{"bearerAuth": []}], "parameters": [ {"name": "active", "in": "query", "schema": {"type": "boolean"}} ], "responses": { "200": {"description": "List of discounts"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/discounts/{code}": { "get": { "operationId": "getDiscountByCode", "tags": ["Discounts"], "summary": "Get discount by code", "security": [{"bearerAuth": []}], "parameters": [{"name": "code", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": { "200": {"description": "Discount details"}, "400": {"description": "Max usage reached"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found or inactive"} } } }, "/api/v1/discounts/apply": { "post": { "operationId": "applyDiscount", "tags": ["Discounts"], "summary": "Apply a discount code to an invoice", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["code", "invoice_id"], "properties": { "code": {"type": "string"}, "invoice_id": {"type": "integer"} } } } } }, "responses": { "200": {"description": "Discount applied"}, "400": {"description": "Invalid discount or already applied"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "500": {"description": "Server error"} } } }, "/api/v1/emergency-contacts": { "get": { "operationId": "listEmergencyContacts", "tags": ["Emergency Contacts"], "summary": "List emergency contacts", "security": [{"bearerAuth": []}], "parameters": [ {"name": "parent_id", "in": "query", "schema": {"type": "integer"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated emergency contacts"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createEmergencyContact", "tags": ["Emergency Contacts"], "summary": "Create an emergency contact", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["parent_id", "emergency_contact_name", "cellphone", "relation"], "properties": { "parent_id": {"type": "integer"}, "emergency_contact_name": {"type": "string"}, "cellphone": {"type": "string"}, "relation": {"type": "string"}, "email": {"type": "string", "format": "email"} } } } } }, "responses": { "201": {"description": "Emergency contact created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/emergency-contacts/{id}": { "get": { "operationId": "getEmergencyContact", "tags": ["Emergency Contacts"], "summary": "Get a single emergency contact", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Emergency contact details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateEmergencyContact", "tags": ["Emergency Contacts"], "summary": "Update an emergency contact", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "emergency_contact_name": {"type": "string"}, "cellphone": {"type": "string"}, "email": {"type": "string", "format": "email"}, "relation": {"type": "string"} } } } } }, "responses": { "200": {"description": "Emergency contact updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteEmergencyContact", "tags": ["Emergency Contacts"], "summary": "Delete an emergency contact", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Emergency contact deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/events": { "get": { "operationId": "listEvents", "tags": ["Events"], "summary": "List events", "security": [{"bearerAuth": []}], "parameters": [ {"name": "school_year", "in": "query", "schema": {"type": "string"}}, {"name": "upcoming", "in": "query", "schema": {"type": "boolean"}} ], "responses": { "200": {"description": "List of events"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createEvent", "tags": ["Events"], "summary": "Create a new event", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["event_name", "amount", "expiration_date"], "properties": { "event_name": {"type": "string"}, "amount": {"type": "number"}, "expiration_date": {"type": "string", "format": "date"}, "description": {"type": "string"}, "semester": {"type": "string"}, "school_year": {"type": "string"} } } } } }, "responses": { "201": {"description": "Event created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/events/{id}": { "get": { "operationId": "getEvent", "tags": ["Events"], "summary": "Get a single event", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Event details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateEvent", "tags": ["Events"], "summary": "Update an event", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "event_name": {"type": "string"}, "description": {"type": "string"}, "amount": {"type": "number"}, "expiration_date": {"type": "string", "format": "date"}, "semester": {"type": "string"}, "school_year": {"type": "string"} } } } } }, "responses": { "200": {"description": "Event updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteEvent", "tags": ["Events"], "summary": "Delete an event", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Event deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/expenses": { "get": { "operationId": "listExpenses", "tags": ["Expenses"], "summary": "List expenses", "security": [{"bearerAuth": []}], "parameters": [ {"name": "status", "in": "query", "schema": {"type": "string"}}, {"name": "category", "in": "query", "schema": {"type": "string"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated expenses"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createExpense", "tags": ["Expenses"], "summary": "Create an expense", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["category", "amount", "description", "date_of_purchase"], "properties": { "category": {"type": "string"}, "amount": {"type": "number"}, "description": {"type": "string"}, "date_of_purchase": {"type": "string", "format": "date"} } } } } }, "responses": { "201": {"description": "Expense created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/expenses/{id}": { "get": { "operationId": "getExpense", "tags": ["Expenses"], "summary": "Get a single expense", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Expense details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateExpense", "tags": ["Expenses"], "summary": "Update an expense", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "category": {"type": "string"}, "amount": {"type": "number"}, "description": {"type": "string"}, "date_of_purchase": {"type": "string", "format": "date"}, "status": {"type": "string"}, "status_reason": {"type": "string"} } } } } }, "responses": { "200": {"description": "Expense updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteExpense", "tags": ["Expenses"], "summary": "Delete an expense", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Expense deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/extra-charges": { "get": { "operationId": "listExtraCharges", "tags": ["Extra Charges"], "summary": "List extra charges", "security": [{"bearerAuth": []}], "parameters": [ {"name": "school_year", "in": "query", "schema": {"type": "string"}}, {"name": "semester", "in": "query", "schema": {"type": "string"}}, {"name": "status", "in": "query", "schema": {"type": "string"}}, {"name": "q", "in": "query", "schema": {"type": "string"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated extra charges"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "createExtraCharge", "tags": ["Extra Charges"], "summary": "Create an extra charge", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["parent_id", "title", "amount", "charge_type"], "properties": { "parent_id": {"type": "integer"}, "title": {"type": "string"}, "amount": {"type": "number"}, "charge_type": {"type": "string", "enum": ["add", "deduct"]}, "due_date": {"type": "string", "format": "date"}, "invoice_id": {"type": "integer"}, "description": {"type": "string"}, "school_year": {"type": "string"}, "semester": {"type": "string"} } } } } }, "responses": { "201": {"description": "Extra charge created"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/extra-charges/{id}": { "get": { "operationId": "getExtraCharge", "tags": ["Extra Charges"], "summary": "Get a single extra charge", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Extra charge details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } }, "patch": { "operationId": "updateExtraCharge", "tags": ["Extra Charges"], "summary": "Update an extra charge", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": {"type": "string"}, "description": {"type": "string"}, "amount": {"type": "number"}, "due_date": {"type": "string", "format": "date"}, "charge_type": {"type": "string", "enum": ["add", "deduct"]} } } } } }, "responses": { "200": {"description": "Extra charge updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "delete": { "operationId": "deleteExtraCharge", "tags": ["Extra Charges"], "summary": "Delete an extra charge", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Extra charge deleted"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/messages": { "get": { "operationId": "listMessages", "tags": ["Messages"], "summary": "List messages", "security": [{"bearerAuth": []}], "parameters": [ {"name": "type", "in": "query", "schema": {"type": "string", "enum": ["sent", "inbox"]}}, {"name": "read", "in": "query", "schema": {"type": "boolean"}} ], "responses": { "200": {"description": "Messages"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "post": { "operationId": "sendMessage", "tags": ["Messages"], "summary": "Send a message", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["subject", "message"], "properties": { "recipient_id": {"type": "integer"}, "recipient_role": {"type": "string"}, "subject": {"type": "string"}, "message": {"type": "string"}, "priority": {"type": "string", "enum": ["normal", "high", "low"]}, "status": {"type": "string", "enum": ["sent", "draft"]} } } } } }, "responses": { "201": {"description": "Message sent"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "422": {"description": "Validation error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}} } } }, "/api/v1/messages/{id}": { "get": { "operationId": "getMessage", "tags": ["Messages"], "summary": "Get a single message", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Message details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/messages/inbox": { "get": { "operationId": "getInboxMessages", "tags": ["Messages"], "summary": "Get inbox messages", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Inbox messages"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/messages/sent": { "get": { "operationId": "getSentMessages", "tags": ["Messages"], "summary": "Get sent messages", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Sent messages"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/notifications": { "get": { "operationId": "listNotifications", "tags": ["Notifications"], "summary": "List notifications", "security": [{"bearerAuth": []}], "parameters": [ {"name": "read", "in": "query", "schema": {"type": "boolean"}}, {"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}}, {"name": "per_page", "in": "query", "schema": {"type": "integer", "default": 20}} ], "responses": { "200": {"description": "Paginated notifications"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/notifications/{id}": { "get": { "operationId": "getNotification", "tags": ["Notifications"], "summary": "Get a single notification", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Notification details"}, "401": {"$ref": "#/components/responses/UnauthorizedError"}, "404": {"description": "Not found"} } } }, "/api/v1/notifications/{id}/read": { "post": { "operationId": "markNotificationRead", "tags": ["Notifications"], "summary": "Mark a notification as read", "security": [{"bearerAuth": []}], "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}], "responses": { "200": {"description": "Notification marked as read"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/settings": { "get": { "operationId": "getSettings", "tags": ["Settings"], "summary": "Get grouped configuration values", "security": [{"bearerAuth": []}], "responses": { "200": {"description": "Settings"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } }, "patch": { "operationId": "updateSettings", "tags": ["Settings"], "summary": "Update settings", "security": [{"bearerAuth": []}], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "responses": { "200": {"description": "Settings updated"}, "401": {"$ref": "#/components/responses/UnauthorizedError"} } } }, "/api/v1/time": { "get": { "operationId": "getServerTime", "tags": ["Time"], "summary": "Get server timestamp and timezone", "responses": { "200": {"description": "Server time information"} }, "security": [] } } } }