chore: add spec-kit and standardize signatures
- Added GitHub spec-kit for development workflow - Standardized file signatures to Descomplicar® format - Updated development configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
335
specs/001-wordpress-plugin-para/contracts/admin-api.md
Normal file
335
specs/001-wordpress-plugin-para/contracts/admin-api.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# Admin API Contracts: Care Booking Block Plugin
|
||||
|
||||
**Feature**: WordPress Plugin para Controlo Seguro de Agendamentos KiviCare
|
||||
**Date**: 2025-09-10
|
||||
**Type**: WordPress AJAX API Contracts
|
||||
|
||||
## AJAX Endpoints
|
||||
|
||||
### 1. Get Restrictions List
|
||||
|
||||
**Endpoint**: `wp_ajax_care_booking_get_restrictions`
|
||||
**Method**: POST
|
||||
**Auth**: WordPress nonce verification
|
||||
**Capability**: `manage_options`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"action": "care_booking_get_restrictions",
|
||||
"nonce": "wp_nonce_string",
|
||||
"restriction_type": "doctor|service|all",
|
||||
"doctor_id": 123 // Optional: for service restrictions
|
||||
}
|
||||
```
|
||||
|
||||
**Response Success (200)**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"restrictions": [
|
||||
{
|
||||
"id": 1,
|
||||
"restriction_type": "doctor",
|
||||
"target_id": 123,
|
||||
"doctor_id": null,
|
||||
"is_blocked": true,
|
||||
"created_at": "2025-09-10 10:00:00",
|
||||
"updated_at": "2025-09-10 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response Error (400/403)**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": {
|
||||
"message": "Invalid nonce" | "Insufficient permissions" | "Invalid parameters"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Toggle Restriction
|
||||
|
||||
**Endpoint**: `wp_ajax_care_booking_toggle_restriction`
|
||||
**Method**: POST
|
||||
**Auth**: WordPress nonce verification
|
||||
**Capability**: `manage_options`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"action": "care_booking_toggle_restriction",
|
||||
"nonce": "wp_nonce_string",
|
||||
"restriction_type": "doctor|service",
|
||||
"target_id": 123,
|
||||
"doctor_id": 456, // Required for service restrictions
|
||||
"is_blocked": true
|
||||
}
|
||||
```
|
||||
|
||||
**Response Success (200)**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"message": "Restriction updated successfully",
|
||||
"restriction": {
|
||||
"id": 1,
|
||||
"restriction_type": "doctor",
|
||||
"target_id": 123,
|
||||
"doctor_id": null,
|
||||
"is_blocked": true,
|
||||
"updated_at": "2025-09-10 10:05:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response Error (400/403/500)**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": {
|
||||
"message": "Failed to update restriction" | "Target not found" | "Database error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Bulk Update Restrictions
|
||||
|
||||
**Endpoint**: `wp_ajax_care_booking_bulk_update`
|
||||
**Method**: POST
|
||||
**Auth**: WordPress nonce verification
|
||||
**Capability**: `manage_options`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"action": "care_booking_bulk_update",
|
||||
"nonce": "wp_nonce_string",
|
||||
"restrictions": [
|
||||
{
|
||||
"restriction_type": "doctor",
|
||||
"target_id": 123,
|
||||
"is_blocked": true
|
||||
},
|
||||
{
|
||||
"restriction_type": "service",
|
||||
"target_id": 456,
|
||||
"doctor_id": 123,
|
||||
"is_blocked": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response Success (200)**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"message": "Bulk update completed",
|
||||
"updated": 2,
|
||||
"errors": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response Error (400/500)**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": {
|
||||
"message": "Partial failure in bulk update",
|
||||
"updated": 1,
|
||||
"errors": [
|
||||
{
|
||||
"restriction": {
|
||||
"target_id": 456,
|
||||
"restriction_type": "service"
|
||||
},
|
||||
"error": "Target not found in KiviCare"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Get KiviCare Entities
|
||||
|
||||
**Endpoint**: `wp_ajax_care_booking_get_entities`
|
||||
**Method**: POST
|
||||
**Auth**: WordPress nonce verification
|
||||
**Capability**: `manage_options`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"action": "care_booking_get_entities",
|
||||
"nonce": "wp_nonce_string",
|
||||
"entity_type": "doctors|services",
|
||||
"doctor_id": 123 // Optional: for services by doctor
|
||||
}
|
||||
```
|
||||
|
||||
**Response Success (200)**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"entities": [
|
||||
{
|
||||
"id": 123,
|
||||
"name": "Dr. João Silva",
|
||||
"email": "joao@clinic.com",
|
||||
"is_blocked": true // Current restriction status
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## WordPress Hooks Integration Contracts
|
||||
|
||||
### 1. KiviCare Doctor List Filter
|
||||
|
||||
**Hook**: `kc_get_doctors_for_booking`
|
||||
**Type**: WordPress Filter
|
||||
**Priority**: 10
|
||||
|
||||
**Input**:
|
||||
```php
|
||||
$doctors = [
|
||||
['id' => 123, 'name' => 'Dr. João Silva', 'email' => 'joao@clinic.com'],
|
||||
['id' => 124, 'name' => 'Dr. Maria Santos', 'email' => 'maria@clinic.com']
|
||||
];
|
||||
```
|
||||
|
||||
**Output** (filtered):
|
||||
```php
|
||||
$doctors = [
|
||||
['id' => 124, 'name' => 'Dr. Maria Santos', 'email' => 'maria@clinic.com']
|
||||
// Dr. João Silva removed if blocked
|
||||
];
|
||||
```
|
||||
|
||||
### 2. KiviCare Service List Filter
|
||||
|
||||
**Hook**: `kc_get_services_by_doctor`
|
||||
**Type**: WordPress Filter
|
||||
**Priority**: 10
|
||||
|
||||
**Input**:
|
||||
```php
|
||||
$services = [
|
||||
['id' => 456, 'name' => 'Consulta Geral', 'doctor_id' => 123],
|
||||
['id' => 457, 'name' => 'Revisão', 'doctor_id' => 123]
|
||||
];
|
||||
$doctor_id = 123;
|
||||
```
|
||||
|
||||
**Output** (filtered):
|
||||
```php
|
||||
$services = [
|
||||
['id' => 456, 'name' => 'Consulta Geral', 'doctor_id' => 123]
|
||||
// 'Revisão' removed if blocked for this doctor
|
||||
];
|
||||
```
|
||||
|
||||
## CSS Injection Contract
|
||||
|
||||
### Dynamic CSS Generation
|
||||
|
||||
**Hook**: `wp_head`
|
||||
**Priority**: 20 (after theme styles)
|
||||
|
||||
**Generated CSS**:
|
||||
```css
|
||||
/* Dynamic CSS based on current restrictions */
|
||||
.kivicare-doctor[data-doctor-id="123"],
|
||||
.kivicare-service[data-service-id="456"][data-doctor-id="123"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Fallback for different KiviCare markup patterns */
|
||||
#doctor-123,
|
||||
#service-456-doctor-123,
|
||||
.doctor-selection option[value="123"],
|
||||
.service-selection option[value="456"] {
|
||||
display: none !important;
|
||||
}
|
||||
```
|
||||
|
||||
## Validation Contracts
|
||||
|
||||
### Input Validation Rules
|
||||
|
||||
**Doctor/Service Target Validation**:
|
||||
```php
|
||||
function validate_target_exists($target_id, $type) {
|
||||
// Must return boolean
|
||||
// true if target exists in KiviCare
|
||||
// false if target not found
|
||||
}
|
||||
```
|
||||
|
||||
**Nonce Validation**:
|
||||
```php
|
||||
function validate_nonce($nonce, $action) {
|
||||
// WordPress standard nonce verification
|
||||
return wp_verify_nonce($nonce, $action);
|
||||
}
|
||||
```
|
||||
|
||||
**Capability Validation**:
|
||||
```php
|
||||
function validate_user_capability() {
|
||||
// Check if user can manage options
|
||||
return current_user_can('manage_options');
|
||||
}
|
||||
```
|
||||
|
||||
## Error Response Contracts
|
||||
|
||||
### Standard Error Codes
|
||||
- `400`: Bad Request (invalid parameters)
|
||||
- `403`: Forbidden (insufficient permissions, invalid nonce)
|
||||
- `404`: Not Found (target entity not found)
|
||||
- `500`: Internal Server Error (database error, KiviCare not available)
|
||||
|
||||
### Error Message Format
|
||||
All error responses follow WordPress AJAX standard:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": {
|
||||
"message": "Human readable error message",
|
||||
"code": "ERROR_CODE_CONSTANT", // Optional
|
||||
"details": {} // Optional additional error context
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Contracts
|
||||
|
||||
### Response Time Targets
|
||||
- **Get Restrictions**: < 200ms
|
||||
- **Toggle Restriction**: < 300ms (includes cache invalidation)
|
||||
- **Bulk Update**: < 500ms for up to 50 items
|
||||
- **Get Entities**: < 400ms (with KiviCare data fetch)
|
||||
|
||||
### Cache Invalidation Contract
|
||||
When any restriction is modified:
|
||||
1. Clear `care_booking_doctors_blocked` transient
|
||||
2. Clear all `care_booking_services_blocked_{doctor_id}` transients
|
||||
3. Update `care_booking_restrictions_hash` with new hash
|
||||
4. Trigger WordPress action: `care_booking_restrictions_updated`
|
||||
|
||||
These contracts define the exact interface between the admin panel, the WordPress backend, and the frontend filtering system.
|
||||
Reference in New Issue
Block a user