{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "AMAR Data Model", "description": "Test-oriented data model for AMAR Mascotas. Focused on test scenarios and user navigation.", "version": "0.1.0", "meta": { "purpose": "Enable quick navigation to appropriate test users/scenarios", "modes": ["sql", "api"], "graph_generators": ["graphviz", "mermaid", "d3", "custom"] }, "definitions": { "UserRole": { "type": "string", "enum": ["USER", "VET", "ADMIN"], "description": "User roles detected from: is_staff → ADMIN, linked to Veterinarian → VET, else USER" }, "RequestState": { "type": "string", "enum": [ "pending", "in_progress_vet", "vet_asked", "vet_accepted", "in_progress_pay", "payed", "coordinated", "not_coordinated", "completed", "rejected" ], "description": "Service request lifecycle states" }, "User": { "type": "object", "description": "Django auth.User - central identity", "table": "auth_user", "properties": { "id": {"type": "integer", "column": "id"}, "username": {"type": "string", "column": "username"}, "email": {"type": "string", "column": "email"}, "first_name": {"type": "string", "column": "first_name"}, "last_name": {"type": "string", "column": "last_name"}, "is_staff": {"type": "boolean", "column": "is_staff"}, "is_active": {"type": "boolean", "column": "is_active"}, "date_joined": {"type": "string", "format": "date-time", "column": "date_joined"} }, "computed": { "role": { "description": "Derived from is_staff, veterinarian link, or default USER", "sql": "CASE WHEN is_staff THEN 'ADMIN' WHEN EXISTS (SELECT 1 FROM mascotas_veterinarian WHERE user_id = auth_user.id) THEN 'VET' ELSE 'USER' END" } }, "required": ["id", "username"] }, "PetOwner": { "type": "object", "description": "Pet owner (client)", "table": "mascotas_petowner", "properties": { "id": {"type": "integer", "column": "id"}, "user_id": {"type": "integer", "column": "user_id"}, "first_name": {"type": "string", "column": "first_name"}, "last_name": {"type": "string", "column": "last_name"}, "email": {"type": "string", "column": "email"}, "phone": {"type": "string", "column": "phone"}, "dni": {"type": "string", "column": "dni"}, "address": {"type": "string", "column": "address"}, "created_at": {"type": "string", "format": "date-time", "column": "created_at"} }, "computed": { "has_pets": { "description": "Has at least one pet", "sql": "EXISTS (SELECT 1 FROM mascotas_pet WHERE petowner_id = mascotas_petowner.id AND deleted = false)" }, "has_coverage": { "description": "Has active coverage", "sql": "EXISTS (SELECT 1 FROM mascotas_coverage WHERE petowner_id = mascotas_petowner.id AND active = true AND deleted = false)" }, "has_requests": { "description": "Has any service requests", "sql": "EXISTS (SELECT 1 FROM solicitudes_servicerequest WHERE petowner_id = mascotas_petowner.id)" }, "has_turnos": { "description": "Has scheduled turnos", "sql": "EXISTS (SELECT 1 FROM mascotas_vetvisit WHERE petowner_id = mascotas_petowner.id)" } }, "required": ["id", "first_name"] }, "Veterinarian": { "type": "object", "description": "Veterinarian service provider", "table": "mascotas_veterinarian", "properties": { "id": {"type": "integer", "column": "id"}, "user_id": {"type": "integer", "column": "user_id"}, "first_name": {"type": "string", "column": "first_name"}, "last_name": {"type": "string", "column": "last_name"}, "email": {"type": "string", "column": "email"}, "phone": {"type": "string", "column": "phone"}, "matricula": {"type": "string", "column": "matricula"}, "created_at": {"type": "string", "format": "date-time", "column": "created_at"} }, "computed": { "has_availability": { "description": "Has configured availability", "sql": "EXISTS (SELECT 1 FROM mascotas_availability WHERE veterinarian_id = mascotas_veterinarian.id AND deleted = false)" }, "has_specialties": { "description": "Has assigned specialties", "sql": "EXISTS (SELECT 1 FROM mascotas_veterinarian_specialties WHERE veterinarian_id = mascotas_veterinarian.id)" }, "has_coverage_areas": { "description": "Has coverage neighborhoods", "sql": "EXISTS (SELECT 1 FROM mascotas_veterinarian_neighborhoods WHERE veterinarian_id = mascotas_veterinarian.id)" }, "active_requests": { "description": "Count of active service requests", "sql": "(SELECT COUNT(*) FROM solicitudes_servicerequest WHERE veterinarian_id = mascotas_veterinarian.id AND state NOT IN ('completed', 'rejected'))" }, "completed_visits": { "description": "Count of completed visits", "sql": "(SELECT COUNT(*) FROM mascotas_vetvisit WHERE veterinarian_id = mascotas_veterinarian.id)" } }, "required": ["id", "first_name"] }, "Pet": { "type": "object", "description": "Pet belonging to PetOwner", "table": "mascotas_pet", "properties": { "id": {"type": "integer", "column": "id"}, "petowner_id": {"type": "integer", "column": "petowner_id"}, "name": {"type": "string", "column": "name"}, "pet_type": {"type": "string", "column": "pet_type"}, "breed_id": {"type": "integer", "column": "breed_id"}, "age_years": {"type": "integer", "column": "age_years"}, "created_at": {"type": "string", "format": "date-time", "column": "created_at"} }, "computed": { "has_vaccines": { "description": "Has vaccine records", "sql": "EXISTS (SELECT 1 FROM mascotas_petvaccination WHERE pet_id = mascotas_pet.id)" }, "has_studies": { "description": "Has study records", "sql": "EXISTS (SELECT 1 FROM mascotas_petstudy WHERE pet_id = mascotas_pet.id)" } }, "required": ["id", "petowner_id", "name"] }, "ServiceRequest": { "type": "object", "description": "Service request (order) - main workflow entity", "table": "solicitudes_servicerequest", "properties": { "id": {"type": "integer", "column": "id"}, "petowner_id": {"type": "integer", "column": "petowner_id"}, "veterinarian_id": {"type": "integer", "column": "veterinarian_id"}, "state": {"$ref": "#/definitions/RequestState", "column": "state"}, "pay_number": {"type": "string", "column": "pay_number"}, "date_coordinated": {"type": "string", "format": "date", "column": "date_coordinated"}, "hour_coordinated": {"type": "string", "format": "time", "column": "hour_coordinated"}, "created_at": {"type": "string", "format": "date-time", "column": "created_at"} }, "computed": { "has_cart": { "description": "Has associated cart", "sql": "EXISTS (SELECT 1 FROM productos_servicecart WHERE service_request_id = solicitudes_servicerequest.id)" }, "has_payment": { "description": "Has payment record", "sql": "pay_number IS NOT NULL AND pay_number != ''" }, "has_turno": { "description": "Has created turno", "sql": "EXISTS (SELECT 1 FROM mascotas_vetvisit WHERE service_request_id = solicitudes_servicerequest.id)" }, "age_hours": { "description": "Hours since creation", "sql": "EXTRACT(EPOCH FROM (NOW() - created_at)) / 3600" } }, "required": ["id", "petowner_id", "state"] }, "VetVisit": { "type": "object", "description": "Scheduled veterinary visit (turno)", "table": "mascotas_vetvisit", "properties": { "id": {"type": "integer", "column": "id"}, "service_request_id": {"type": "integer", "column": "service_request_id"}, "veterinarian_id": {"type": "integer", "column": "veterinarian_id"}, "petowner_id": {"type": "integer", "column": "petowner_id"}, "visit_date": {"type": "string", "format": "date", "column": "visit_date"}, "visit_hour": {"type": "string", "format": "time", "column": "visit_hour"}, "created_at": {"type": "string", "format": "date-time", "column": "created_at"} }, "computed": { "has_report": { "description": "Has post-visit report", "sql": "EXISTS (SELECT 1 FROM mascotas_vetvisitreport WHERE vet_visit_id = mascotas_vetvisit.id)" }, "has_invoice": { "description": "Has generated invoice", "sql": "invoice_number IS NOT NULL" }, "is_completed": { "description": "Visit has been completed", "sql": "visit_date < CURRENT_DATE OR (visit_date = CURRENT_DATE AND visit_hour < CURRENT_TIME)" } }, "required": ["id", "service_request_id"] } } }