digraph DataModel { // Graph settings rankdir=TB compound=true splines=ortho node [shape=record, style="filled", fontname="Helvetica", fontsize=10] edge [fontname="Helvetica", fontsize=8] label="AMAR Mascotas - Data Model (Entity Relationships)\n\n" labelloc="t" fontsize=16 fontname="Helvetica-Bold" // === USERS & AUTHENTICATION === subgraph cluster_auth { label="Users & Authentication" style="rounded,filled" fillcolor="#E8F5E9" color="#2E7D32" auth_user [label="{auth.User|id: PK\luser name: str\lemail: str\lis_staff: bool\lis_superuser: bool\l}", fillcolor="#C8E6C9"] } // === PET OWNERS & PETS === subgraph cluster_mascotas_owners { label="Pet Owners & Pets" style="rounded,filled" fillcolor="#E3F2FD" color="#1565C0" petowner [label="{PetOwner|id: PK\lemail: str (unique)\lphone: str\lfirst_name: str\llast_name: str\lneighborhood_id: FK\lcampaign_id: FK (opt)\lgeo_latitude: float\lgeo_longitude: float\laddress: str\l}", fillcolor="#BBDEFB"] pet [label="{Pet|id: PK\lowner_id: FK\lname: str\lpet_type: DOG/CAT\lbreed_id: FK (opt)\lgender: M/F\lage: int\lweight: decimal\lheight: decimal\lbirth_date: date\lallergies: text\lneutered: bool\lis_deceased: bool\lstate: puppy/adult/...\lprofile_picture: file\l}", fillcolor="#BBDEFB"] petvaccine [label="{PetVaccine|id: PK\lpet_id: FK\lvaccine_id: FK\lapplication_date: date\lnext_application: date\l}", fillcolor="#90CAF9"] petstudy [label="{PetStudy|id: PK\lpet_id: FK\lstudy_id: FK\ldate: date\lresult: text\limages: files\l}", fillcolor="#90CAF9"] } // === VETERINARIANS === subgraph cluster_veterinarians { label="Veterinarians" style="rounded,filled" fillcolor="#FFF3E0" color="#E65100" veterinarian [label="{Veterinarian|id: PK\luser_id: FK\llicense: str\lemail: str\lphone: str\l}", fillcolor="#FFE0B2"] availability [label="{Availability|id: PK\lveterinarian_id: FK\lstart_day: 0-6\lend_day: 0-6\lstart_time: time\lend_time: time\l}", fillcolor="#FFCC80"] unavailability [label="{Unavailability|id: PK\lveterinarian_id: FK\lstart_date: date\lend_date: date\lstart_time: time\lend_time: time\lreason: str\l}", fillcolor="#FFCC80"] vet_specialty [label="{M2M: Vet-Specialty|veterinarian_id: FK\lspecialty_id: FK\l}", shape=diamond, fillcolor="#FFB74D"] vet_neighborhood [label="{M2M: Vet-Neighborhood|veterinarian_id: FK\lneighborhood_id: FK\l}", shape=diamond, fillcolor="#FFB74D"] } // === SERVICES & PRICING === subgraph cluster_productos { label="Services & Pricing" style="rounded,filled" fillcolor="#F3E5F5" color="#7B1FA2" grupo [label="{Group|id: PK\lname: str\ldescription: text\l}", fillcolor="#E1BEE7"] category [label="{Category|id: PK\lgroup_id: FK\lname: str\ldescription: text\lvalue: int (order)\l}", fillcolor="#E1BEE7"] service [label="{Service|id: PK\lname: str\ldescription: text\lspecialty_id: FK\lcategory_id: FK\lduration: int (min)\lmodality: onsite/online\lpayment_sign_req: bool\lpet_type_filter: str\lage_filter: str\lweight_range: str\l}", fillcolor="#CE93D8"] prices [label="{Prices|id: PK\lservice_id: FK\lveterinarian_id: FK (opt)\lprice: decimal\lprofessional_fee: decimal\lpayment_sign: decimal\lfrom_date: date\lto_date: date\lactive: bool\l}", fillcolor="#BA68C8"] discounts [label="{Discounts|id: PK\lservice_id: FK\ldiscount: decimal (%)\lfrom_date: date\lto_date: date\lactive: bool\l}", fillcolor="#BA68C8"] servicecombo [label="{ServiceCombo|id: PK\lname: str\ldescription: text\ldiscount_percent: decimal\ldiscount_fixed: decimal\l}", fillcolor="#E1BEE7"] } // === CART & CHECKOUT === subgraph cluster_cart { label="Cart & Checkout" style="rounded,filled" fillcolor="#E0F7FA" color="#00838F" cart [label="{Cart|id: PK\lpetowner_id: FK\lveterinarian_id: FK (opt)\luse_vet_prices: bool\lapply_turn_fee: bool\l}", fillcolor="#B2EBF2"] cartitem [label="{CartItem|id: PK\lcart_id: FK\lpet_id: FK (opt)\lservice_id: FK\lprice: decimal\lquantity: int\ltotal: decimal (calc)\l}", fillcolor="#80DEEA"] cartresumeitem [label="{CartResumeItem|id: PK\lcart_id: FK\lconcept: SUBTOTAL/\l DESCUENTO/\l ADELANTO/\l TOTAL/\l COSTO_SERVICIO\lamount: decimal\lorder: int\l}", fillcolor="#80DEEA"] cartpetreason [label="{CartPetReason|id: PK\lcart_id: FK\lpet_id: FK\lreason: text\l}", fillcolor="#80DEEA"] } // === SERVICE REQUESTS === subgraph cluster_solicitudes { label="Service Requests (Workflow)" style="rounded,filled" fillcolor="#FFEBEE" color="#C62828" servicerequest [label="{ServiceRequest|id: PK\lpetowner_id: FK\lcart_id: FK\lveterinarian_id: FK (opt)\lstate: pending/vet_asked/\l vet_accepted/coordinated/\l payed/Confirmado/...\lreason: text\ldays_requested: JSON\ldate_coordinated: datetime\lhour_coordinated: time\lpay_number: str\lcampaign_id: FK (opt)\lattended_by_id: FK (opt)\l}", fillcolor="#FFCDD2"] statehistory [label="{StateHistory|id: PK\lservice_request_id: FK\lstate: str\ladditional_data: JSON\lcreated_at: datetime\luser_id: FK\l}", fillcolor="#EF9A9A"] vetasked [label="{VeterinarianAsked|id: PK\lservice_request_id: FK\lveterinarian_id: FK\ldate_asked: datetime\ldate_answered: datetime\laccepted: bool\l}", fillcolor="#EF9A9A"] vetreminder [label="{ScheduledVetReminder|id: PK\lvet_asked_id: FK\lscheduled_for: datetime\lprocessed_at: datetime\lstatus: pending/sent/...\lcelery_task_id: str\l}", fillcolor="#E57373"] payreminder [label="{PaymentReminder|id: PK\lservice_request_id: FK\lscheduled_for: datetime\lprocessed_at: datetime\lstatus: pending/sent/...\l}", fillcolor="#E57373"] } // === VET VISITS === subgraph cluster_vetvisits { label="Veterinary Visits" style="rounded,filled" fillcolor="#FFFDE7" color="#F9A825" vetvisit [label="{VetVisit|id: PK\lservice_request_id: FK (opt)\lowner_id: FK\lveterinarian_id: FK\ldate: date\lhour: time\lvisit_type: clinical/\l vaccination/\l telemedicina\lvisit_state: PENDING/\l IN_PROGRESS/\l COMPLETED/\l NO_REPORT/\l CANCELLED\lreason: text\lobservations: text\lprice: decimal\ldeposit: decimal\lvet_fee: decimal\lpay_transaction: str\lgoogle_event_id: str\lafip_receipt_id: FK (opt)\l}", fillcolor="#FFF9C4"] vetvisitreport [label="{VetVisitReport|id: PK\lvisit_id: FK\lpet_id: FK\lreason: text\lphysical_exam: text\ldiagnosis: text\ltreatment: text\lpdf_file: file\l}", fillcolor="#FFF59D"] vetvisitfollowup [label="{VetVisitFollowUp|id: PK\lreport_id: FK\ldate: date\ldescription: text\l}", fillcolor="#FFF176"] vetvisitpetreason [label="{VetVisitPetReason|id: PK\lvisit_id: FK\lpet_id: FK\lreason: text\l}", fillcolor="#FFF176"] visit_pets [label="{M2M: Visit-Pets|vetvisit_id: FK\lpet_id: FK\l}", shape=diamond, fillcolor="#FFEE58"] } // === REFERENCE DATA === subgraph cluster_reference { label="Reference Data" style="rounded,filled" fillcolor="#ECEFF1" color="#455A64" specialty [label="{Specialty|id: PK\lname: str\l}", fillcolor="#CFD8DC"] neighborhood [label="{Neighborhood|id: PK\lname: str\ldistance_coefficient: decimal\lcoverage_area: GIS Polygon\l}", fillcolor="#CFD8DC"] province [label="{Province|id: PK\lname: str\l}", fillcolor="#CFD8DC"] locality [label="{Locality|id: PK\lprovince_id: FK\lname: str\l}", fillcolor="#CFD8DC"] petbreed [label="{PetBreed|id: PK\lname: str\lpet_type: DOG/CAT\l}", fillcolor="#CFD8DC"] vaccine [label="{Vaccine|id: PK\lname: str\lpet_type: DOG/CAT\lperiodicity: int (months)\l}", fillcolor="#CFD8DC"] study [label="{Study|id: PK\lname: str\lpet_type: DOG/CAT\lgroup_id: FK (opt)\l}", fillcolor="#CFD8DC"] campaign [label="{Campaign|id: PK\lname: str\lutm_source: str\lutm_medium: str\lis_active: bool\l}", fillcolor="#CFD8DC"] tag [label="{Tag|id: PK\lname: str (unique)\l}", fillcolor="#CFD8DC"] medication [label="{Medication|id: PK\lname: str\lgeneral_name_id: FK\ltype_id: FK\lpresentation_id: FK\lpet_type: str\l}", fillcolor="#CFD8DC"] turnfeegroup [label="{IndividualTurnFeeGroup|id: PK\lname: str\lfee_percentage: decimal\l}", fillcolor="#CFD8DC"] } // === AFIP/INVOICING === subgraph cluster_afip { label="AFIP Invoicing" style="rounded,filled" fillcolor="#FCE4EC" color="#AD1457" receipt [label="{Receipt|id: PK\ldocument_number: bigint\lreceipt_number: int\lissued_date: date\ltotal_amount: decimal\lnet_taxed: decimal\lcae: str\lcae_expiration: date\l}", fillcolor="#F8BBD9"] } // === RELATIONSHIPS === // Auth -> PetOwner/Vet auth_user -> petowner [label="1:1 opt", style=dashed, color="#2E7D32"] auth_user -> veterinarian [label="1:1", color="#2E7D32"] // PetOwner relationships petowner -> pet [label="1:N owns", color="#1565C0"] petowner -> neighborhood [label="N:1 lives in", color="#1565C0"] petowner -> campaign [label="N:1 opt", style=dashed, color="#666"] petowner -> cart [label="1:N", color="#00838F"] petowner -> servicerequest [label="1:N requests", color="#C62828"] petowner -> vetvisit [label="1:N as owner", color="#F9A825"] // Pet relationships pet -> petbreed [label="N:1 opt", style=dashed, color="#666"] pet -> petvaccine [label="1:N", color="#1565C0"] pet -> petstudy [label="1:N", color="#1565C0"] petvaccine -> vaccine [label="N:1", color="#666"] petstudy -> study [label="N:1", color="#666"] // Veterinarian relationships veterinarian -> vet_specialty [label="1:N", color="#E65100"] vet_specialty -> specialty [label="N:1", color="#E65100"] veterinarian -> vet_neighborhood [label="1:N coverage", color="#E65100"] vet_neighborhood -> neighborhood [label="N:1", color="#E65100"] veterinarian -> availability [label="1:N", color="#E65100"] veterinarian -> unavailability [label="1:N", color="#E65100"] veterinarian -> turnfeegroup [label="N:M", color="#E65100", style=dashed] // Service/Pricing relationships grupo -> category [label="1:N", color="#7B1FA2"] category -> service [label="1:N", color="#7B1FA2"] service -> specialty [label="N:1 opt", style=dashed, color="#7B1FA2"] service -> prices [label="1:N", color="#7B1FA2"] service -> discounts [label="1:N", color="#7B1FA2"] prices -> veterinarian [label="N:1 opt\n(vet-specific)", style=dashed, color="#7B1FA2"] // Cart relationships cart -> veterinarian [label="N:1 opt\n(assigned vet)", style=dashed, color="#00838F"] cart -> cartitem [label="1:N", color="#00838F"] cart -> cartresumeitem [label="1:N", color="#00838F"] cart -> cartpetreason [label="1:N", color="#00838F"] cartitem -> service [label="N:1", color="#00838F"] cartitem -> pet [label="N:1 opt", style=dashed, color="#00838F"] cartpetreason -> pet [label="N:1", color="#00838F"] // ServiceRequest relationships servicerequest -> cart [label="1:1", color="#C62828"] servicerequest -> veterinarian [label="N:1 opt\n(assigned)", style=dashed, color="#C62828"] servicerequest -> statehistory [label="1:N audit", color="#C62828"] servicerequest -> vetasked [label="1:N", color="#C62828"] servicerequest -> payreminder [label="1:N", color="#C62828"] servicerequest -> campaign [label="N:1 opt", style=dashed, color="#666"] servicerequest -> tag [label="N:M", color="#666"] vetasked -> veterinarian [label="N:1", color="#C62828"] vetasked -> vetreminder [label="1:N", color="#C62828"] // VetVisit relationships vetvisit -> servicerequest [label="1:1 opt\n(from request)", style=dashed, color="#F9A825"] vetvisit -> veterinarian [label="N:1", color="#F9A825"] vetvisit -> visit_pets [label="1:N", color="#F9A825"] visit_pets -> pet [label="N:1", color="#F9A825"] vetvisit -> vetvisitreport [label="1:N", color="#F9A825"] vetvisit -> vetvisitpetreason [label="1:N", color="#F9A825"] vetvisitreport -> pet [label="N:1", color="#F9A825"] vetvisitreport -> vetvisitfollowup [label="1:N", color="#F9A825"] vetvisitpetreason -> pet [label="N:1", color="#F9A825"] // AFIP vetvisit -> receipt [label="1:1 opt\n(invoice)", style=dashed, color="#AD1457"] // Geography province -> locality [label="1:N", color="#666"] }