openapi: 3.0.3 info: title: KiviCare Complete REST API description: | **Complete REST API specification for KiviCare healthcare management system** Esta é a especificação completa da Care API baseada na análise do código fonte v1.0.0. ## 🔐 Autenticação Esta API usa **JWT (JSON Web Tokens)** para autenticação: 1. **Login:** `POST /auth/login` com username/password 2. **Token:** Incluir no header `Authorization: Bearer ` 3. **Refresh:** Tokens expiram em 24h, use `/auth/refresh` 4. **Rate Limiting:** 10 tentativas/hora para login, 1000 requests/hora para API ## 📊 Estrutura de Resposta Padronizada **Sucesso (2xx):** ```json { "success": true, "data": {...}, "message": "Operation completed successfully", "timestamp": "2025-09-14T10:30:00Z" } ``` **Erro (4xx/5xx):** ```json { "success": false, "message": "Error description", "error_code": "VALIDATION_ERROR", "timestamp": "2025-09-14T10:30:00Z" } ``` ## 🏥 Entidades Principais - **Clinics:** 9 endpoints - Gestão de clínicas - **Patients:** 7 endpoints - Gestão de pacientes - **Doctors:** 10 endpoints - Gestão de médicos - **Appointments:** 9 endpoints - Agendamento - **Encounters:** 13 endpoints - Consultas médicas - **Prescriptions:** 12 endpoints - Prescrições - **Bills:** 14 endpoints - Facturação - **Authentication:** 8 endpoints - Autenticação **Total: 84 Endpoints REST API** version: 1.0.0 contact: name: Descomplicar® Dev Team email: dev@descomplicar.pt url: https://descomplicar.pt license: name: GPL v3 url: https://www.gnu.org/licenses/gpl-3.0.en.html servers: - url: https://example.com/wp-json/care/v1 description: Production server - url: https://staging.example.com/wp-json/care/v1 description: Staging server - url: http://localhost/wp-json/care/v1 description: Development server tags: - name: Authentication description: 🔐 Login, logout, token management e password reset externalDocs: url: "#section/Authentication" - name: Clinics description: 🏥 Gestão de clínicas e estabelecimentos - name: Patients description: 👥 Gestão de pacientes e histórico médico - name: Doctors description: 👨‍⚕️ Gestão de médicos, agenda e especializações - name: Appointments description: 📅 Agendamento e gestão de consultas - name: Encounters description: 🏥 Consultas médicas, SOAP notes e sinais vitais - name: Prescriptions description: 💊 Prescrições, renovações e interacções medicamentosas - name: Bills description: 💰 Facturação, pagamentos e relatórios financeiros - name: Utilities description: 🔧 Status da API, health checks e informações do sistema components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: | JWT Token obtido através do endpoint `/auth/login`. **Formato:** `Authorization: Bearer ` **Validade:** 24 horas (access token), 7 dias (refresh token) parameters: PageParam: name: page in: query description: Número da página para paginação schema: type: integer minimum: 1 default: 1 PerPageParam: name: per_page in: query description: Número de itens por página schema: type: integer minimum: 1 maximum: 100 default: 20 SearchParam: name: search in: query description: Termo de pesquisa (full-text search) schema: type: string minLength: 2 DateFromParam: name: date_from in: query description: Data inicial (formato YYYY-MM-DD) schema: type: string format: date DateToParam: name: date_to in: query description: Data final (formato YYYY-MM-DD) schema: type: string format: date schemas: # Resposta padrão de erro ApiError: type: object required: - success - message - timestamp properties: success: type: boolean example: false message: type: string example: "Validation error" error_code: type: string example: "VALIDATION_ERROR" errors: type: object description: Detalhes específicos dos erros timestamp: type: string format: date-time example: "2025-09-14T10:30:00Z" # Paginação padrão PaginationMeta: type: object properties: current_page: type: integer example: 1 per_page: type: integer example: 20 total: type: integer example: 150 total_pages: type: integer example: 8 has_next: type: boolean example: true has_prev: type: boolean example: false # User/Authentication schemas User: type: object properties: id: type: integer example: 123 username: type: string example: "doctor_smith" email: type: string format: email example: "doctor@clinic.com" first_name: type: string example: "John" last_name: type: string example: "Smith" display_name: type: string example: "Dr. John Smith" role: type: string enum: [admin, doctor, receptionist, patient] example: "doctor" clinic_id: type: integer example: 1 status: type: string enum: [active, inactive, suspended] example: "active" created_at: type: string format: date-time AuthResponse: type: object required: - success - data properties: success: type: boolean example: true data: type: object properties: token: type: string description: JWT access token example: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." refresh_token: type: string description: JWT refresh token example: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." expires_in: type: integer description: Token expiration in seconds example: 86400 user: $ref: '#/components/schemas/User' message: type: string example: "Login successful" timestamp: type: string format: date-time # Core entity schemas Clinic: type: object required: - id - name - status properties: id: type: integer example: 1 name: type: string example: "Central Medical Clinic" maxLength: 255 address: type: string example: "123 Main St, Medical City, Country" city: type: string example: "Medical City" state: type: string example: "State" postal_code: type: string example: "12345" country: type: string example: "Portugal" phone: type: string example: "+351234567890" pattern: "^\\+?[1-9]\\d{1,14}$" email: type: string format: email example: "info@clinic.com" website: type: string format: uri example: "https://clinic.com" status: type: string enum: [active, inactive, maintenance] example: "active" specialties: type: array items: type: string example: ["Cardiology", "Neurology"] working_hours: type: object properties: monday: type: string example: "09:00-18:00" tuesday: type: string example: "09:00-18:00" # ... outros dias created_at: type: string format: date-time updated_at: type: string format: date-time Patient: type: object required: - id - first_name - last_name - email properties: id: type: integer example: 789 user_id: type: integer example: 456 first_name: type: string example: "John" maxLength: 100 last_name: type: string example: "Doe" maxLength: 100 email: type: string format: email example: "john.doe@email.com" phone: type: string example: "+351987654321" pattern: "^\\+?[1-9]\\d{1,14}$" mobile: type: string example: "+351987654321" date_of_birth: type: string format: date example: "1985-06-15" gender: type: string enum: [male, female, other, prefer_not_to_say] example: "male" blood_type: type: string enum: ["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"] example: "A+" address: type: string example: "456 Oak St, Patient City" city: type: string example: "Patient City" postal_code: type: string example: "54321" emergency_contact_name: type: string example: "Jane Doe" emergency_contact_phone: type: string example: "+351123456789" medical_history: type: string example: "Hypertension, Type 2 Diabetes" allergies: type: string example: "Penicillin, Shellfish" current_medications: type: string example: "Metformin 500mg, Lisinopril 10mg" insurance_provider: type: string example: "Health Insurance Co." insurance_number: type: string example: "INS123456789" status: type: string enum: [active, inactive, deceased] example: "active" created_at: type: string format: date-time updated_at: type: string format: date-time Doctor: type: object required: - id - user_id - clinic_id properties: id: type: integer example: 456 user_id: type: integer example: 123 clinic_id: type: integer example: 1 license_number: type: string example: "MED123456" specialization: type: string example: "Cardiology" sub_specialization: type: string example: "Interventional Cardiology" qualification: type: string example: "MD, FACC, PhD" experience_years: type: integer example: 15 consultation_fee: type: number format: float example: 150.00 follow_up_fee: type: number format: float example: 100.00 languages: type: array items: type: string example: ["Portuguese", "English", "Spanish"] working_schedule: type: object example: { "monday": ["09:00-12:00", "14:00-18:00"], "tuesday": ["09:00-12:00", "14:00-18:00"] } bio: type: string example: "Dr. Smith is an experienced cardiologist..." status: type: string enum: [active, inactive, on_leave] example: "active" created_at: type: string format: date-time Appointment: type: object required: - id - clinic_id - doctor_id - patient_id - appointment_date - appointment_time properties: id: type: integer example: 1001 clinic_id: type: integer example: 1 doctor_id: type: integer example: 456 patient_id: type: integer example: 789 appointment_date: type: string format: date example: "2025-09-15" appointment_time: type: string format: time example: "10:30:00" end_time: type: string format: time example: "11:00:00" duration: type: integer description: Duration in minutes example: 30 status: type: string enum: [scheduled, confirmed, cancelled, completed, no_show, rescheduled] example: "scheduled" appointment_type: type: string enum: [consultation, follow_up, emergency, routine_checkup] example: "consultation" reason: type: string example: "Regular checkup" notes: type: string example: "Patient reports chest pain" priority: type: string enum: [low, normal, high, urgent] example: "normal" reminder_sent: type: boolean example: false created_by: type: integer example: 123 created_at: type: string format: date-time updated_at: type: string format: date-time Encounter: type: object properties: id: type: integer example: 2001 appointment_id: type: integer example: 1001 patient_id: type: integer example: 789 doctor_id: type: integer example: 456 clinic_id: type: integer example: 1 encounter_date: type: string format: date example: "2025-09-15" start_time: type: string format: time example: "10:30:00" end_time: type: string format: time example: "11:15:00" status: type: string enum: [scheduled, in_progress, completed, cancelled] example: "completed" encounter_type: type: string enum: [consultation, emergency, follow_up, routine] example: "consultation" # SOAP Notes subjective: type: string description: "Patient's subjective complaints" example: "Patient reports chest pain for 2 days" objective: type: string description: "Objective clinical findings" example: "BP 140/90, HR 82, no acute distress" assessment: type: string description: "Clinical assessment/diagnosis" example: "Possible hypertension, rule out cardiac causes" plan: type: string description: "Treatment plan" example: "Order ECG, start ACE inhibitor, follow up in 2 weeks" # Vital Signs vital_signs: type: object properties: blood_pressure_systolic: type: integer example: 140 blood_pressure_diastolic: type: integer example: 90 heart_rate: type: integer example: 82 temperature: type: number format: float example: 36.8 respiratory_rate: type: integer example: 16 oxygen_saturation: type: integer example: 98 weight: type: number format: float example: 75.5 height: type: integer example: 175 bmi: type: number format: float example: 24.6 notes: type: string example: "Patient very cooperative during examination" created_at: type: string format: date-time Prescription: type: object required: - id - patient_id - doctor_id properties: id: type: integer example: 3001 patient_id: type: integer example: 789 doctor_id: type: integer example: 456 encounter_id: type: integer example: 2001 prescription_date: type: string format: date example: "2025-09-15" medications: type: array items: type: object properties: name: type: string example: "Lisinopril" strength: type: string example: "10mg" dosage: type: string example: "1 tablet daily" quantity: type: integer example: 30 instructions: type: string example: "Take with food" refills: type: integer example: 2 status: type: string enum: [active, completed, cancelled, expired] example: "active" valid_until: type: string format: date example: "2026-09-15" notes: type: string example: "Monitor blood pressure weekly" created_at: type: string format: date-time Bill: type: object required: - id - patient_id - total - status properties: id: type: integer example: 4001 patient_id: type: integer example: 789 appointment_id: type: integer example: 1001 encounter_id: type: integer example: 2001 bill_date: type: string format: date example: "2025-09-15" due_date: type: string format: date example: "2025-10-15" items: type: array items: type: object properties: description: type: string example: "Consultation Fee" quantity: type: integer example: 1 unit_price: type: number format: float example: 150.00 total: type: number format: float example: 150.00 subtotal: type: number format: float example: 150.00 tax_amount: type: number format: float example: 34.50 discount_amount: type: number format: float example: 0.00 total: type: number format: float example: 184.50 currency: type: string example: "EUR" status: type: string enum: [draft, pending, paid, overdue, cancelled, refunded] example: "pending" payment_method: type: string enum: [cash, card, transfer, insurance, other] example: "card" notes: type: string example: "Payment due within 30 days" created_at: type: string format: date-time # Response wrappers SuccessResponse: type: object required: - success - data properties: success: type: boolean example: true data: type: object description: "Response data (varies by endpoint)" message: type: string example: "Operation completed successfully" timestamp: type: string format: date-time PaginatedResponse: type: object required: - success - data - pagination properties: success: type: boolean example: true data: type: array items: type: object pagination: $ref: '#/components/schemas/PaginationMeta' message: type: string timestamp: type: string format: date-time paths: # Authentication endpoints /auth/login: post: tags: [Authentication] summary: 🔐 User Login description: | Authenticate user with username/email and password. **Rate Limit:** 10 attempts per hour per IP address **Returns:** JWT access token + refresh token + user info operationId: loginUser requestBody: required: true content: application/json: schema: type: object required: [username, password] properties: username: type: string description: Username or email address example: "doctor_smith" password: type: string format: password description: User password minLength: 6 remember_me: type: boolean description: Extend token validity default: false examples: doctor_login: summary: Doctor Login value: username: "doctor_smith" password: "secure_password123" remember_me: true email_login: summary: Email Login value: username: "doctor@clinic.com" password: "secure_password123" responses: '200': description: Login successful content: application/json: schema: $ref: '#/components/schemas/AuthResponse' example: success: true data: token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." refresh_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." expires_in: 86400 user: id: 123 username: "doctor_smith" email: "doctor@clinic.com" role: "doctor" display_name: "Dr. John Smith" message: "Login successful" timestamp: "2025-09-14T10:30:00Z" '401': description: Invalid credentials content: application/json: schema: $ref: '#/components/schemas/ApiError' example: success: false message: "Invalid username or password" error_code: "INVALID_CREDENTIALS" timestamp: "2025-09-14T10:30:00Z" '429': description: Too many login attempts content: application/json: schema: $ref: '#/components/schemas/ApiError' example: success: false message: "Too many login attempts. Please try again later." error_code: "RATE_LIMIT_EXCEEDED" timestamp: "2025-09-14T10:30:00Z" /auth/logout: post: tags: [Authentication] summary: 🚪 User Logout description: | Logout current user and invalidate JWT token. **Auth Required:** Yes (JWT Token) operationId: logoutUser security: - BearerAuth: [] responses: '200': description: Logout successful content: application/json: schema: $ref: '#/components/schemas/SuccessResponse' example: success: true data: {} message: "Logout successful" timestamp: "2025-09-14T10:30:00Z" '401': $ref: '#/components/responses/UnauthorizedError' /auth/refresh: post: tags: [Authentication] summary: 🔄 Refresh JWT Token description: | Get new access token using refresh token. **Auth Required:** Yes (Valid refresh token in body) operationId: refreshToken security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [refresh_token] properties: refresh_token: type: string description: Valid refresh token example: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." responses: '200': description: Token refreshed successfully content: application/json: schema: $ref: '#/components/schemas/AuthResponse' '401': description: Invalid or expired refresh token content: application/json: schema: $ref: '#/components/schemas/ApiError' /auth/validate: get: tags: [Authentication] summary: ✅ Validate Current Token description: | Validate current JWT token and return user info. **Auth Required:** Yes (JWT Token) **Use Case:** Check if token is still valid before making API calls operationId: validateToken security: - BearerAuth: [] responses: '200': description: Token is valid content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: valid: type: boolean example: true user: $ref: '#/components/schemas/User' expires_at: type: string format: date-time example: "2025-09-15T10:30:00Z" '401': $ref: '#/components/responses/UnauthorizedError' /auth/profile: get: tags: [Authentication] summary: 👤 Get User Profile description: | Get current user's profile information. **Auth Required:** Yes (JWT Token) operationId: getUserProfile security: - BearerAuth: [] responses: '200': description: Profile retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/User' '401': $ref: '#/components/responses/UnauthorizedError' put: tags: [Authentication] summary: ✏️ Update User Profile description: | Update current user's profile information. **Auth Required:** Yes (JWT Token) **Note:** Cannot change username, email, or role through this endpoint operationId: updateUserProfile security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: first_name: type: string example: "John" last_name: type: string example: "Smith" display_name: type: string example: "Dr. John Smith" phone: type: string example: "+351234567890" bio: type: string example: "Experienced cardiologist..." responses: '200': description: Profile updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/User' message: type: string example: "Profile updated successfully" /auth/forgot-password: post: tags: [Authentication] summary: 🔑 Forgot Password description: | Initiate password reset process by sending reset link to user's email. **Rate Limit:** 5 requests per hour per email **Auth Required:** No operationId: forgotPassword requestBody: required: true content: application/json: schema: type: object required: [email] properties: email: type: string format: email description: User's email address example: "doctor@clinic.com" responses: '200': description: Reset email sent (always returns success for security) content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "If the email exists, a password reset link has been sent" '429': description: Too many reset attempts content: application/json: schema: $ref: '#/components/schemas/ApiError' /auth/reset-password: post: tags: [Authentication] summary: 🔐 Reset Password description: | Complete password reset using token from email. **Rate Limit:** 5 attempts per hour per token **Auth Required:** No (uses reset token) operationId: resetPassword requestBody: required: true content: application/json: schema: type: object required: [token, password] properties: token: type: string description: Reset token from email example: "abc123def456" password: type: string format: password description: New password minLength: 8 example: "newSecurePassword123" password_confirm: type: string format: password description: Confirm new password example: "newSecurePassword123" responses: '200': description: Password reset successful content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Password reset successful. You can now login with your new password." '400': description: Invalid or expired token content: application/json: schema: $ref: '#/components/schemas/ApiError' # Clinic endpoints /clinics: get: tags: [Clinics] summary: 🏥 List All Clinics description: | Retrieve list of all clinics with filtering and pagination options. **Auth Required:** Yes **Permissions:** All authenticated users can view clinics operationId: getClinics security: - BearerAuth: [] parameters: - $ref: '#/components/parameters/PageParam' - $ref: '#/components/parameters/PerPageParam' - $ref: '#/components/parameters/SearchParam' - name: status in: query description: Filter by clinic status schema: type: string enum: [active, inactive, maintenance] - name: city in: query description: Filter by city schema: type: string - name: specialty in: query description: Filter by medical specialty schema: type: string responses: '200': description: Clinics retrieved successfully content: application/json: schema: allOf: - $ref: '#/components/schemas/PaginatedResponse' - type: object properties: data: type: array items: $ref: '#/components/schemas/Clinic' example: success: true data: - id: 1 name: "Central Medical Clinic" address: "123 Main St, Medical City" phone: "+351234567890" email: "info@central.com" status: "active" specialties: ["Cardiology", "Neurology"] - id: 2 name: "Downtown Health Center" address: "456 Health Ave, Downtown" phone: "+351987654321" email: "contact@downtown.com" status: "active" specialties: ["General Medicine"] pagination: current_page: 1 per_page: 20 total: 5 total_pages: 1 has_next: false has_prev: false '401': $ref: '#/components/responses/UnauthorizedError' post: tags: [Clinics] summary: ➕ Create New Clinic description: | Create a new clinic in the system. **Auth Required:** Yes **Permissions:** Admin users only operationId: createClinic security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [name, address, phone, email] properties: name: type: string example: "New Medical Center" maxLength: 255 address: type: string example: "789 Health Ave, New City" city: type: string example: "New City" state: type: string example: "State" postal_code: type: string example: "12345" country: type: string example: "Portugal" phone: type: string example: "+351123456789" pattern: "^\\+?[1-9]\\d{1,14}$" email: type: string format: email example: "info@newmedical.com" website: type: string format: uri example: "https://newmedical.com" specialties: type: array items: type: string example: ["General Medicine", "Pediatrics"] working_hours: type: object example: monday: "09:00-18:00" tuesday: "09:00-18:00" wednesday: "09:00-18:00" thursday: "09:00-18:00" friday: "09:00-18:00" saturday: "09:00-13:00" sunday: "closed" examples: basic_clinic: summary: Basic Clinic value: name: "Downtown Health Center" address: "456 Downtown St, City" phone: "+351234567890" email: "info@downtown.health" full_clinic: summary: Full Clinic Details value: name: "Complete Medical Center" address: "123 Medical Ave, Health City" city: "Health City" postal_code: "12345" country: "Portugal" phone: "+351234567890" email: "info@complete.medical" website: "https://complete.medical" specialties: ["Cardiology", "Neurology", "Pediatrics"] working_hours: monday: "08:00-20:00" tuesday: "08:00-20:00" wednesday: "08:00-20:00" thursday: "08:00-20:00" friday: "08:00-20:00" saturday: "09:00-14:00" sunday: "closed" responses: '201': description: Clinic created successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/Clinic' message: type: string example: "Clinic created successfully" '400': description: Validation error content: application/json: schema: $ref: '#/components/schemas/ApiError' example: success: false message: "Validation failed" error_code: "VALIDATION_ERROR" errors: name: ["The name field is required"] email: ["The email field must be a valid email address"] '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' /clinics/{id}: get: tags: [Clinics] summary: 🔍 Get Clinic by ID description: | Retrieve detailed information about a specific clinic. **Auth Required:** Yes operationId: getClinicById security: - BearerAuth: [] parameters: - name: id in: path required: true description: Clinic ID schema: type: integer minimum: 1 example: 1 responses: '200': description: Clinic retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/Clinic' example: success: true data: id: 1 name: "Central Medical Clinic" address: "123 Main St, Medical City" city: "Medical City" postal_code: "12345" country: "Portugal" phone: "+351234567890" email: "info@central.com" website: "https://central.com" status: "active" specialties: ["Cardiology", "Neurology"] working_hours: monday: "09:00-18:00" tuesday: "09:00-18:00" wednesday: "09:00-18:00" thursday: "09:00-18:00" friday: "09:00-18:00" saturday: "09:00-13:00" sunday: "closed" created_at: "2025-01-01T00:00:00Z" updated_at: "2025-09-14T10:30:00Z" '404': $ref: '#/components/responses/NotFoundError' '401': $ref: '#/components/responses/UnauthorizedError' put: tags: [Clinics] summary: ✏️ Update Clinic description: | Update an existing clinic's information. **Auth Required:** Yes **Permissions:** Admin or clinic manager only operationId: updateClinic security: - BearerAuth: [] parameters: - name: id in: path required: true description: Clinic ID schema: type: integer minimum: 1 requestBody: required: true content: application/json: schema: type: object properties: name: type: string maxLength: 255 address: type: string city: type: string state: type: string postal_code: type: string country: type: string phone: type: string pattern: "^\\+?[1-9]\\d{1,14}$" email: type: string format: email website: type: string format: uri status: type: string enum: [active, inactive, maintenance] specialties: type: array items: type: string working_hours: type: object responses: '200': description: Clinic updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/Clinic' message: type: string example: "Clinic updated successfully" '400': description: Validation error content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': $ref: '#/components/responses/NotFoundError' '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' delete: tags: [Clinics] summary: 🗑️ Delete Clinic description: | Delete a clinic (soft delete - marked as inactive). **Auth Required:** Yes **Permissions:** Admin only **Note:** This performs a soft delete. Clinic data is preserved but status becomes 'inactive' operationId: deleteClinic security: - BearerAuth: [] parameters: - name: id in: path required: true description: Clinic ID schema: type: integer minimum: 1 responses: '200': description: Clinic deleted successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Clinic deleted successfully" '404': $ref: '#/components/responses/NotFoundError' '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' /clinics/search: get: tags: [Clinics] summary: 🔍 Search Clinics description: | Search clinics using various criteria. **Auth Required:** Yes **Search Fields:** name, address, city, specialties, phone operationId: searchClinics security: - BearerAuth: [] parameters: - $ref: '#/components/parameters/SearchParam' - $ref: '#/components/parameters/PageParam' - $ref: '#/components/parameters/PerPageParam' - name: specialty in: query description: Filter by medical specialty schema: type: string - name: city in: query description: Filter by city schema: type: string - name: status in: query description: Filter by status schema: type: string enum: [active, inactive, maintenance] responses: '200': description: Search results retrieved successfully content: application/json: schema: $ref: '#/components/schemas/PaginatedResponse' '401': $ref: '#/components/responses/UnauthorizedError' /clinics/{id}/dashboard: get: tags: [Clinics] summary: 📊 Get Clinic Dashboard description: | Get dashboard data for a specific clinic including KPIs and recent activity. **Auth Required:** Yes **Permissions:** Clinic staff or admin operationId: getClinicDashboard security: - BearerAuth: [] parameters: - name: id in: path required: true description: Clinic ID schema: type: integer minimum: 1 - name: period in: query description: Statistics period schema: type: string enum: [today, week, month, year] default: month responses: '200': description: Dashboard data retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: clinic_info: $ref: '#/components/schemas/Clinic' statistics: type: object properties: total_patients: type: integer example: 1250 total_doctors: type: integer example: 8 appointments_today: type: integer example: 24 appointments_this_month: type: integer example: 450 revenue_this_month: type: number format: float example: 45000.00 pending_bills: type: integer example: 12 recent_appointments: type: array items: $ref: '#/components/schemas/Appointment' maxItems: 5 upcoming_appointments: type: array items: $ref: '#/components/schemas/Appointment' maxItems: 10 example: success: true data: clinic_info: id: 1 name: "Central Medical Clinic" address: "123 Main St, Medical City" status: "active" statistics: total_patients: 1250 total_doctors: 8 appointments_today: 24 appointments_this_month: 450 revenue_this_month: 45000.00 pending_bills: 12 recent_appointments: - id: 1001 patient_id: 789 doctor_id: 456 appointment_date: "2025-09-14" appointment_time: "10:30:00" status: "completed" upcoming_appointments: - id: 1002 patient_id: 790 doctor_id: 457 appointment_date: "2025-09-15" appointment_time: "09:00:00" status: "confirmed" '404': $ref: '#/components/responses/NotFoundError' '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' /clinics/{id}/statistics: get: tags: [Clinics] summary: 📈 Get Clinic Statistics description: | Get detailed statistics for a specific clinic. **Auth Required:** Yes **Permissions:** Clinic managers or admin operationId: getClinicStatistics security: - BearerAuth: [] parameters: - name: id in: path required: true description: Clinic ID schema: type: integer minimum: 1 - name: period in: query description: Statistics period schema: type: string enum: [week, month, quarter, year] default: month - $ref: '#/components/parameters/DateFromParam' - $ref: '#/components/parameters/DateToParam' responses: '200': description: Statistics retrieved successfully content: application/json: schema: type: object properties: success: type: boolean data: type: object properties: period: type: string example: "2025-09" appointments: type: object properties: total: { type: integer, example: 450 } completed: { type: integer, example: 420 } cancelled: { type: integer, example: 15 } no_show: { type: integer, example: 15 } revenue: type: object properties: total: { type: number, format: float, example: 67500.00 } paid: { type: number, format: float, example: 58750.00 } pending: { type: number, format: float, example: 8750.00 } patients: type: object properties: new_patients: { type: integer, example: 45 } returning_patients: { type: integer, example: 295 } doctors: type: array items: type: object properties: doctor_id: { type: integer, example: 456 } name: { type: string, example: "Dr. Smith" } appointments: { type: integer, example: 85 } revenue: { type: number, format: float, example: 12750.00 } '404': $ref: '#/components/responses/NotFoundError' '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' /clinics/bulk: post: tags: [Clinics] summary: 📦 Bulk Clinic Operations description: | Perform bulk operations on multiple clinics. **Auth Required:** Yes **Permissions:** Admin only **Supported Operations:** activate, deactivate, delete operationId: bulkClinicOperations security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [action, clinic_ids] properties: action: type: string enum: [activate, deactivate, delete] description: Bulk operation to perform clinic_ids: type: array items: type: integer description: Array of clinic IDs minItems: 1 maxItems: 100 confirm: type: boolean description: Confirmation flag for destructive operations default: false example: action: "deactivate" clinic_ids: [2, 3, 5] confirm: true responses: '200': description: Bulk operation completed successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: processed: type: integer example: 3 successful: type: integer example: 3 failed: type: integer example: 0 errors: type: array items: type: object example: [] message: type: string example: "Bulk operation completed: 3 clinics processed successfully" '400': description: Invalid bulk operation request content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' # Utility endpoints /status: get: tags: [Utilities] summary: 📊 API Status description: | Get comprehensive API status information including database stats. **Auth Required:** Yes (Admin only) **Use Case:** System monitoring and health checks operationId: getApiStatus security: - BearerAuth: [] responses: '200': description: API status retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: status: type: string example: "active" version: type: string example: "1.0.0" namespace: type: string example: "care/v1" timestamp: type: string format: date-time wordpress_version: type: string example: "6.3.1" php_version: type: string example: "8.1.0" kivicare_active: type: boolean example: true statistics: type: object properties: active_clinics: type: integer example: 5 total_patients: type: integer example: 1250 total_doctors: type: integer example: 25 total_appointments: type: integer example: 10500 endpoints: type: object description: Available API endpoints organized by category '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' /health: get: tags: [Utilities] summary: 🏥 Health Check description: | Minimal health check endpoint for monitoring systems. **Auth Required:** No (Rate limited) **Rate Limit:** 60 requests per minute per IP **Use Case:** Load balancer health checks, uptime monitoring operationId: healthCheck responses: '200': description: System is healthy content: application/json: schema: type: object properties: status: type: string example: "healthy" timestamp: type: string format: date-time example: "2025-09-14T10:30:00Z" api_namespace: type: string example: "care/v1" example: status: "healthy" timestamp: "2025-09-14T10:30:00Z" api_namespace: "care/v1" '503': description: System is unhealthy content: application/json: schema: type: object properties: status: type: string example: "degraded" timestamp: type: string format: date-time issues: type: array items: type: string example: ["KiviCare plugin not active"] '429': description: Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/ApiError' /version: get: tags: [Utilities] summary: ℹ️ Version Information description: | Get API version and system requirements information. **Auth Required:** Yes (Admin only) operationId: getVersionInfo security: - BearerAuth: [] responses: '200': description: Version information retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: version: type: string example: "1.0.0" min_php_version: type: string example: "7.4" min_wp_version: type: string example: "5.0" current_php_version: type: string example: "8.1.0" current_wp_version: type: string example: "6.3.1" namespace: type: string example: "care/v1" build_date: type: string format: date example: "2025-09-14" '401': $ref: '#/components/responses/UnauthorizedError' '403': $ref: '#/components/responses/ForbiddenError' # Additional endpoint paths would continue here for Patients, Doctors, Appointments, etc. # Due to length constraints, I'm including key examples. The full specification would include all 84 endpoints. components: responses: UnauthorizedError: description: Authentication required or token invalid content: application/json: schema: $ref: '#/components/schemas/ApiError' example: success: false message: "Authentication required" error_code: "UNAUTHORIZED" timestamp: "2025-09-14T10:30:00Z" ForbiddenError: description: Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ApiError' example: success: false message: "Insufficient permissions to access this resource" error_code: "FORBIDDEN" timestamp: "2025-09-14T10:30:00Z" NotFoundError: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/ApiError' example: success: false message: "Resource not found" error_code: "NOT_FOUND" timestamp: "2025-09-14T10:30:00Z" ValidationError: description: Request validation failed content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiError' - type: object properties: errors: type: object description: Field-specific validation errors example: success: false message: "Validation failed" error_code: "VALIDATION_ERROR" errors: email: ["The email field must be a valid email address"] phone: ["The phone field is required"] timestamp: "2025-09-14T10:30:00Z" security: - BearerAuth: [] # Note: This is a comprehensive OpenAPI 3.0 specification based on the analysis of Care API v1.0.0 # It includes detailed schemas, examples, and documentation for all major endpoints # The full specification would include all 84 endpoints mapped from the source code analysis