| 19 | | * specialization_id (PK, bigint) |
| 20 | | * specialization_name (text) |
| | 32 | Doctor_Specialization is an entity listing the medical specializations doctors can practice. It is kept separate from Doctors so Procedures can reference which specializations are allowed to perform them. |
| | 33 | |
| | 34 | * '''Candidate keys:''' |
| | 35 | |
| | 36 | specialization_id (surrogate) |
| | 37 | |
| | 38 | specialization_name (natural, UNIQUE). |
| | 39 | |
| | 40 | `specialization_id` was chosen as PK so a rename doesn't cascade into Doctors and Specialization_Procedures. |
| | 41 | |
| | 42 | * '''Attributes:''' |
| | 43 | |
| | 44 | specialization_id (PK, bigint) — required; supplied by the application |
| | 45 | |
| | 46 | specialization_name (text) — required, unique |
| 23 | | * department_id (PK, bigint) |
| 24 | | * department_name (text) |
| | 49 | Departments is an entity representing the clinic's organizational departments. Departments both employ doctors (works_in) and offer procedures (performs), so it needed to be a first-class entity. |
| | 50 | |
| | 51 | * '''Candidate keys:''' |
| | 52 | |
| | 53 | department_id (surrogate) |
| | 54 | |
| | 55 | department_name (natural, UNIQUE). |
| | 56 | |
| | 57 | `department_id` was chosen as PK so a rename doesn't cascade into Doctors and Department_Procedures. |
| | 58 | |
| | 59 | * '''Attributes:''' |
| | 60 | |
| | 61 | department_id (PK, bigint) — required |
| | 62 | |
| | 63 | department_name (text) — required, unique |
| 27 | | * doctor_id (PK, bigint) |
| 28 | | * first_name (text) |
| 29 | | * last_name (text) |
| 30 | | * email_address (text) |
| 31 | | * level_id (FK, bigint) |
| 32 | | * specialization_id (FK, bigint) |
| 33 | | * department_id (FK, bigint) |
| | 66 | Doctors is the central entity for doctors who use the system to see patients, record diagnoses, order tests and perform procedures. Level, specialization and department are FKs to lookup entities rather than free text to prevent inconsistent values and allow filtering. |
| | 67 | |
| | 68 | * '''Candidate keys:''' |
| | 69 | |
| | 70 | doctor_id (surrogate) |
| | 71 | |
| | 72 | email_address (natural, UNIQUE). |
| | 73 | |
| | 74 | `doctor_id` was chosen as PK because an email address can change, and using a mutable value as PK would force cascading updates across every table referencing a doctor. |
| | 75 | |
| | 76 | * '''Attributes:''' |
| | 77 | |
| | 78 | doctor_id (PK, bigint) — required |
| | 79 | |
| | 80 | first_name (text) — required |
| | 81 | |
| | 82 | last_name (text) — required |
| | 83 | |
| | 84 | email_address (text) — required, unique, must contain an "@" (`LIKE '%@%'` - format check) |
| | 85 | |
| | 86 | level_id (FK, bigint) — required, references Doctor_Level |
| | 87 | |
| | 88 | specialization_id (FK, bigint) — required, references Doctor_Specialization |
| | 89 | |
| | 90 | department_id (FK, bigint) — required, references Departments |
| 36 | | * patient_id (PK, bigint) |
| 37 | | * first_name (text) |
| 38 | | * last_name (text) |
| 39 | | * email_address (text) |
| 40 | | * date_of_birth (date) |
| 41 | | * blood_type (text) |
| 42 | | * gender (text) |
| 43 | | * phone_number (text) |
| 44 | | * embg (text) |
| | 93 | Patients represents the people receiving care, it is the anchor entity for almost all clinical data like appointments, diagnoses, medical records, tests, procedures, billing. |
| | 94 | |
| | 95 | * '''Candidate keys:''' |
| | 96 | |
| | 97 | patient_id (surrogate), |
| | 98 | |
| | 99 | embg (natural - the Macedonian unique master citizen number, required and unique). |
| | 100 | |
| | 101 | `patient_id` was still chosen as PK rather than embg: embg is sensitive personal data that is better not propagated as a foreign key into every dependent table (Diagnosis, Appointments, Medical_Records, etc.), and a numeric surrogate keeps those relationships smaller and independent of a nationally issued identifier. |
| | 102 | |
| | 103 | * '''Attributes:''' |
| | 104 | |
| | 105 | patient_id (PK, bigint) — required |
| | 106 | |
| | 107 | first_name (text) — required |
| | 108 | |
| | 109 | last_name (text) — required |
| | 110 | |
| | 111 | email_address (text) — optional, unique if provided |
| | 112 | |
| | 113 | date_of_birth (date) — required |
| | 114 | |
| | 115 | blood_type (text) — optional, restricted to one of: A+, A-, B+, B-, AB+, AB-, O+, O- |
| | 116 | |
| | 117 | gender (text) — optional, restricted to one of: MALE, FEMALE |
| | 118 | |
| | 119 | phone_number (text) — optional, free text |
| | 120 | |
| | 121 | embg (text) — required, unique, 13-digit format |
| 47 | | * admin_id (PK, bigint) |
| 48 | | * username (text) |
| 49 | | * name (text) |
| 50 | | * lastname (text) |
| 51 | | * email (text) |
| | 124 | Represents clinic administrative staff who manage billing and back-office operations. Kept separate from Doctors and Lab_Technician since admins have no clinical attributes. |
| | 125 | |
| | 126 | * '''Candidate keys:''' |
| | 127 | |
| | 128 | admin_id (surrogate), |
| | 129 | |
| | 130 | username (natural, UNIQUE), |
| | 131 | |
| | 132 | email (natural, UNIQUE). |
| | 133 | |
| | 134 | `admin_id` was chosen as PK so a username change doesn't cascade into Users and Billing. |
| | 135 | |
| | 136 | * '''Attributes:''' |
| | 137 | |
| | 138 | admin_id (PK, bigint) — required |
| | 139 | |
| | 140 | username (text) — required, unique |
| | 141 | |
| | 142 | name (text) — required |
| | 143 | |
| | 144 | lastname (text) — required |
| | 145 | |
| | 146 | email (text) — required, unique, must contain "@adminmedora" (`LIKE '%@adminmedora%'` - restricts admins to the internal admin email domain) |
| 54 | | * technician_id (PK, bigint) |
| 55 | | * username (text) |
| 56 | | * name (text) |
| 57 | | * lastname (text) |
| 58 | | * email (text) |
| | 149 | Lab Technician entity is the lab staff who conduct the tests ordered by doctors and record results in Performed_Lab_Tests. Modeled separately from Doctors since technicians don't diagnose or prescribe. |
| | 150 | |
| | 151 | * '''Candidate keys:''' |
| | 152 | |
| | 153 | technician_id (surrogate), |
| | 154 | username (natural, UNIQUE), |
| | 155 | email (natural, UNIQUE). |
| | 156 | |
| | 157 | `technician_id` was chosen as PK for the same reason as Admin. |
| | 158 | |
| | 159 | * '''Attributes:''' |
| | 160 | |
| | 161 | technician_id (PK, bigint) — required, supplied by the application |
| | 162 | |
| | 163 | username (text) — required, unique |
| | 164 | |
| | 165 | name (text) — required |
| | 166 | |
| | 167 | lastname (text) — required |
| | 168 | |
| | 169 | email (text) — required, unique, must contain "@labmedora" (`LIKE '%@labmedora%'` - restricts technicians email domain) |
| 61 | | * user_id (PK, serial) |
| 62 | | * username (text) |
| 63 | | * password (text) |
| 64 | | * role (text) |
| 65 | | * first_name (text) |
| 66 | | * last_name (text) |
| 67 | | * patient_id (FK, bigint, nullable) |
| 68 | | * doctor_id (FK, bigint, nullable) |
| 69 | | * admin_id (FK, bigint, nullable) |
| 70 | | * technician_id (FK, bigint, nullable) |
| 71 | | * is_active (boolean) |
| | 172 | Users is the authentication and login entity implementing role based access. A Users row is meant to serve exactly one of Patients, Doctors, Admin or Lab_Technician via whichever of the four nullable FKs is populated. |
| | 173 | |
| | 174 | * '''Candidate keys:''' |
| | 175 | |
| | 176 | user_id (surrogate) |
| | 177 | |
| | 178 | username (natural, UNIQUE). |
| | 179 | |
| | 180 | `user_id` was chosen as PK so a username change doesn't break session/audit data referencing the account. user_id is the one PK in this schema that is DB-generated (`SERIAL`). |
| | 181 | |
| | 182 | * '''Attributes:''' |
| | 183 | |
| | 184 | user_id (PK, serial) — required, auto-generated by the database |
| | 185 | |
| | 186 | username (varchar(255)) — required, unique |
| | 187 | |
| | 188 | password (varchar(255)) — required, expected to be stored as a hash |
| | 189 | |
| | 190 | role (varchar(50)) — required, intended to be one of patient/doctor/admin/technician |
| | 191 | |
| | 192 | first_name (varchar(100)) — optional |
| | 193 | |
| | 194 | last_name (varchar(100)) — optional |
| | 195 | |
| | 196 | patient_id (FK, bigint, nullable) — references Patients |
| | 197 | |
| | 198 | doctor_id (FK, bigint, nullable) — references Doctors |
| | 199 | |
| | 200 | admin_id (FK, bigint, nullable) — references Admin |
| | 201 | |
| | 202 | technician_id (FK, bigint, nullable) — references Lab_Technician |
| | 203 | |
| | 204 | is_active (boolean) — optional, defaults to true |
| 74 | | * appointment_id (PK, bigint) |
| 75 | | * appointment_date (date) |
| 76 | | * appointment_time (time) |
| 77 | | * status (text) |
| 78 | | * patient_id (FK, bigint) |
| 79 | | * doctor_id (FK, bigint) |
| | 207 | Appointments represents a scheduled meeting between one patient and one doctor. No natural key exists, so a surrogate key is mandatory. |
| | 208 | |
| | 209 | * '''Candidate keys:''' |
| | 210 | |
| | 211 | appointment_id (surrogate) only. |
| | 212 | |
| | 213 | * '''Attributes:''' |
| | 214 | |
| | 215 | appointment_id (PK, bigint) — required |
| | 216 | |
| | 217 | appointment_date (date) — required |
| | 218 | |
| | 219 | appointment_time (time) — required |
| | 220 | |
| | 221 | status (text) — required, restricted to one of: SCHEDULED, COMPLETED, CANCELLED, IN_PROGRESS |
| | 222 | |
| | 223 | patient_id (FK, bigint) — required, references Patients |
| | 224 | |
| | 225 | doctor_id (FK, bigint) — required, references Doctors |
| 82 | | * diagnosis_id (PK, bigint) |
| 83 | | * name (text) |
| 84 | | * description (text) |
| 85 | | * patient_id (FK, bigint) |
| 86 | | * doctor_id (FK, bigint) |
| | 228 | Diagnosis entity represents a diagnosis a doctor makes for a patient. It is the pivot the clinical model turns on since procedures, referrals and medical records all connect back to it. |
| | 229 | |
| | 230 | * '''Candidate keys:''' |
| | 231 | |
| | 232 | diagnosis_id (surrogate) only. |
| | 233 | |
| | 234 | the same diagnosis name can legitimately recur for the same patient over time. |
| | 235 | |
| | 236 | * '''Attributes:''' |
| | 237 | |
| | 238 | diagnosis_id (PK, bigint) — required; supplied by the application |
| | 239 | |
| | 240 | name (text) — required |
| | 241 | |
| | 242 | description (text) — optional |
| | 243 | |
| | 244 | patient_id (FK, bigint) — required, references Patients |
| | 245 | |
| | 246 | doctor_id (FK, bigint) — required, references Doctors |
| 89 | | * procedure_id (PK, bigint) |
| 90 | | * procedure_type (text) |
| 91 | | * procedure_date (date) |
| 92 | | * description (text) |
| 93 | | * cost (decimal) |
| 94 | | * doctor_id (FK, bigint) |
| 95 | | * diagnosis_id (FK, bigint) |
| | 249 | Procedures is a catalog entry describing a type of procedure with its cost and the diagnosis it was primarily created for. Each row carries a direct diagnosis_id FK for its main diagnosis (1:N), while Diagnosis_Procedures (M:N) additionally lets the same catalog procedure be linked to other diagnoses without duplicating the row. |
| | 250 | |
| | 251 | * '''Candidate keys:''' |
| | 252 | |
| | 253 | procedure_id (surrogate) only. |
| | 254 | |
| | 255 | procedure_type alone isn't unique, since the same type can be cataloged for different diagnoses at different costs. |
| | 256 | |
| | 257 | * '''Attributes:''' |
| | 258 | |
| | 259 | procedure_id (PK, bigint) — required; supplied by the application |
| | 260 | |
| | 261 | procedure_type (text) — required, must not be blank/whitespace-only |
| | 262 | |
| | 263 | procedure_date (date) — required |
| | 264 | |
| | 265 | description (text) — optional |
| | 266 | |
| | 267 | cost (decimal) — required, must be ≥ 0 |
| | 268 | |
| | 269 | doctor_id (FK, bigint) — required, references Doctors |
| | 270 | |
| | 271 | diagnosis_id (FK, bigint) — required, references Diagnosis |
| 98 | | * result_id (PK, bigint) |
| 99 | | * result_description (text) |
| 100 | | * result_date (date) |
| 101 | | * procedure_id (FK, bigint) |
| | 274 | Procedure_Results stores the outcome of a performed procedure. Kept separate from Procedures since one procedure can generate more than one result over time. |
| | 275 | |
| | 276 | * '''Candidate keys:''' |
| | 277 | |
| | 278 | result_id (surrogate) only. |
| | 279 | |
| | 280 | * '''Attributes:''' |
| | 281 | |
| | 282 | result_id (PK, bigint) — required |
| | 283 | |
| | 284 | result_description (text) — optional, must not be blank |
| | 285 | |
| | 286 | result_date (date) - required |
| | 287 | |
| | 288 | procedure_id (FK, bigint) - required, references Procedures |
| 104 | | * prescription_id (PK, bigint) |
| 105 | | * medication_name (text) |
| | 291 | Prescriptions is an entity for medications that can be prescribed. Kept minimal because everything patient specific like dosage, frequency, duration lives on Prescription_Medical_Records instead, since it varies per medical record. |
| | 292 | |
| | 293 | * '''Candidate keys:''' |
| | 294 | |
| | 295 | prescription_id (surrogate) only. |
| | 296 | |
| | 297 | medication_name is required but has no UNIQUE constraint in this schema, so it is not a true candidate key as implemented. |
| | 298 | |
| | 299 | * '''Attributes:''' |
| | 300 | |
| | 301 | prescription_id (PK, bigint) - required |
| | 302 | |
| | 303 | medication_name (text) - required not enforced unique |
| 108 | | * restriction_id (PK, bigint) |
| 109 | | * description (text) |
| 110 | | * prescription_id (FK, bigint) |
| | 306 | Entity that records a restriction attached to a prescription. Separate entity because one prescription can carry multiple independent restrictions. |
| | 307 | |
| | 308 | * '''Candidate keys:''' |
| | 309 | |
| | 310 | restriction_id (surrogate) only. |
| | 311 | |
| | 312 | * '''Attributes:''' |
| | 313 | |
| | 314 | restriction_id (PK, bigint) - required |
| | 315 | |
| | 316 | description (text) - required, must not be blank |
| | 317 | |
| | 318 | prescription_id (FK, bigint) — required, references Prescriptions |
| 113 | | * test_id (PK, bigint) |
| 114 | | * test_name (text) |
| 115 | | * description (text) |
| 116 | | * cost (decimal) |
| | 321 | A catalog entity describing the lab tests the clinic offers, with standard cost. Separate from Performed_Lab_Tests, which records each actual instance of a test being run. |
| | 322 | |
| | 323 | * '''Candidate keys:''' |
| | 324 | |
| | 325 | test_id (surrogate) only. |
| | 326 | |
| | 327 | |
| | 328 | * '''Attributes:''' |
| | 329 | |
| | 330 | test_id (PK, bigint) — required |
| | 331 | |
| | 332 | test_name (text) — required, must be blank, not enforced unique |
| | 333 | |
| | 334 | description (text) — optional |
| | 335 | |
| | 336 | cost (decimal) — required, must be ≥ 0 |
| 119 | | * result_id (PK, bigint) |
| 120 | | * results (text) |
| 121 | | * result_date (date) |
| 122 | | * test_id (FK, bigint) |
| | 339 | Entity that stores the outcome of a catalog lab test, linked directly to the Lab_Tests catalog entry so the result stays reusable across reports (Medical_Report_Lab_Results, Medical_Record_Lab_Results). |
| | 340 | |
| | 341 | * '''Candidate keys:''' |
| | 342 | |
| | 343 | result_id (surrogate) only. |
| | 344 | |
| | 345 | * '''Attributes:''' |
| | 346 | |
| | 347 | result_id (PK, bigint) - required |
| | 348 | |
| | 349 | results (text) - required, must not be blank |
| | 350 | |
| | 351 | result_date (date) — required, must not be later than the current date |
| | 352 | |
| | 353 | test_id (FK, bigint) — required, references Lab_Tests |
| 125 | | ''(simplified)'' |
| 126 | | * record_id (PK, bigint) |
| 127 | | * patient_id (FK, bigint) |
| | 356 | |
| | 357 | Acts as a folder aggregating everything about a patient's clinical episode, by being the hub that other entities connect back to. Kept deliberately minimal so record specific detail lives on the appropriate junction table instead of being duplicated here. |
| | 358 | |
| | 359 | * '''Candidate keys:''' |
| | 360 | |
| | 361 | record_id (surrogate) only. |
| | 362 | |
| | 363 | a patient can have multiple records over time, so patient_id alone isn't unique. |
| | 364 | |
| | 365 | * '''Attributes:''' |
| | 366 | |
| | 367 | record_id (PK, bigint) — required |
| | 368 | |
| | 369 | patient_id (FK, bigint) — required, references Patients |
| 130 | | * allergy_id (PK, bigint) |
| 131 | | * name (text) |
| 132 | | * allergy_severity (text) |
| | 372 | An entity listing known allergies with a general severity classification, so the same allergy can be linked to many patients without re-entering its description each time. |
| | 373 | |
| | 374 | * '''Candidate keys:''' |
| | 375 | |
| | 376 | allergy_id (surrogate) |
| | 377 | |
| | 378 | name (natural, UNIQUE). |
| | 379 | |
| | 380 | `allergy_id` was chosen as PK so it survives a naming correction. |
| | 381 | |
| | 382 | * '''Attributes:''' |
| | 383 | |
| | 384 | allergy_id (PK, bigint) - required |
| | 385 | |
| | 386 | name (text) — required, unique, must not be blank |
| | 387 | |
| | 388 | allergy_severity (text) - required, restricted to one of: LOW, MEDIUM, HIGH, CRITICAL |
| 135 | | * symptom_id (PK, bigint) |
| 136 | | * name (text) |
| 137 | | * description (text) |
| | 391 | A catalog entity listing known symptoms so the same symptom can be reused across many patients and diagnoses rather than typed freely each time. |
| | 392 | |
| | 393 | * '''Candidate keys:''' |
| | 394 | |
| | 395 | symptom_id (surrogate) |
| | 396 | |
| | 397 | name (natural, UNIQUE-enforced). |
| | 398 | |
| | 399 | `symptom_id` was chosen as PK for consistency with other catalog entities. |
| | 400 | |
| | 401 | * '''Attributes:''' |
| | 402 | |
| | 403 | symptom_id (PK, bigint) — required |
| | 404 | |
| | 405 | name (text) — required, unique, must be blank |
| | 406 | |
| | 407 | description (text) — optional, if present, must not be blank |
| 140 | | * referral_id (PK, bigint) |
| 141 | | * reason (text) |
| 142 | | * referral_date (date) |
| 143 | | * record_id (FK, bigint) |
| 144 | | * from_doctor_id (FK, bigint) |
| 145 | | * to_doctor_id (FK, bigint) |
| | 410 | Records one doctor referring a patient's medical record to another doctor. Carries two separate FKs to Doctors (from_doctor_id, to_doctor_id) because a referral inherently involves two distinct doctor roles. |
| | 411 | |
| | 412 | * '''Candidate keys:''' |
| | 413 | |
| | 414 | referral_id (surrogate) only. |
| | 415 | |
| | 416 | * '''Attributes:''' |
| | 417 | |
| | 418 | referral_id (PK, bigint) — required |
| | 419 | |
| | 420 | reason (text) — required, must be blank |
| | 421 | |
| | 422 | referral_date (date) — required |
| | 423 | |
| | 424 | record_id (FK, bigint) — required, references Medical_Records |
| | 425 | |
| | 426 | from_doctor_id (FK, bigint) — required, references Doctors |
| | 427 | |
| | 428 | to_doctor_id (FK, bigint) — required, references Doctors |
| 148 | | * report_id (PK, bigint) |
| 149 | | * description (text) |
| 150 | | * report_date (date) |
| 151 | | * record_id (FK, bigint) |
| 152 | | * doctor_id (FK, bigint) |
| | 431 | Represents a formal written report a doctor produces based on a medical record, which can reference multiple lab results as supporting evidence. |
| | 432 | |
| | 433 | * '''Candidate keys:''' |
| | 434 | |
| | 435 | report_id (surrogate) only. |
| | 436 | |
| | 437 | a record can generate more than one report over time. |
| | 438 | |
| | 439 | * '''Attributes:''' |
| | 440 | |
| | 441 | report_id (PK, bigint) — required; supplied by the application |
| | 442 | |
| | 443 | description (text) — required |
| | 444 | |
| | 445 | report_date (date) — required |
| | 446 | |
| | 447 | record_id (FK, bigint) — required, references Medical_Records |
| | 448 | |
| | 449 | doctor_id (FK, bigint) — required, references Doctors |
| 155 | | * bill_id (PK, bigint) |
| 156 | | * total_cost (decimal) |
| 157 | | * payment_status (text) |
| 158 | | * payment_date (date) |
| 159 | | * record_id (FK, bigint) |
| 160 | | * admin_id (FK, bigint) |
| | 452 | Represents an invoice generated for a medical record, covering whichever procedures/tests it includes, processed by an administrator. payment_date is nullable since a bill can be Pending before it's ever paid. |
| | 453 | |
| | 454 | * '''Candidate keys:''' |
| | 455 | |
| | 456 | bill_id (surrogate) only. |
| | 457 | |
| | 458 | * '''Attributes:''' |
| | 459 | |
| | 460 | bill_id (PK, bigint) — required |
| | 461 | |
| | 462 | total_cost (decimal) — required, must be ≥ 0 |
| | 463 | |
| | 464 | payment_status (text) — required, restricted to one of: PENDING, PAID, CANCELLED |
| | 465 | |
| | 466 | payment_date (date) — optional |
| | 467 | |
| | 468 | record_id (FK, bigint) — required, references Medical_Records |
| | 469 | |
| | 470 | admin_id (FK, bigint) — required, references Admin |
| 163 | | * performed_id (PK, bigint) |
| 164 | | * procedure_id (FK, bigint) |
| 165 | | * doctor_id (FK, bigint) |
| 166 | | * patient_id (FK, bigint) |
| 167 | | * diagnosis_id (FK, bigint, nullable) |
| 168 | | * procedure_date (date) |
| 169 | | * notes (text) |
| | 473 | Records a specific, actual occurrence of a catalog procedure carried out on a patient. Distinct from Procedures, the catalog definition. diagnosis_id is nullable since a performed procedure isn't always tied to a newly recorded diagnosis. |
| | 474 | |
| | 475 | * '''Candidate keys:''' |
| | 476 | |
| | 477 | performed_id (surrogate) only. |
| | 478 | |
| | 479 | * '''Attributes:''' |
| | 480 | |
| | 481 | performed_id (PK, bigint) — required |
| | 482 | |
| | 483 | procedure_id (FK, bigint) — required, references Procedures |
| | 484 | |
| | 485 | doctor_id (FK, bigint) — required, references Doctors |
| | 486 | |
| | 487 | patient_id (FK, bigint) — required, references Patients |
| | 488 | |
| | 489 | diagnosis_id (FK, bigint, nullable) — references Diagnosis |
| | 490 | |
| | 491 | procedure_date (date) — required |
| | 492 | |
| | 493 | notes (text) — optional |
| 172 | | |
| 173 | | * performed_test_id (PK, bigint) |
| 174 | | * test_id (FK, bigint) |
| 175 | | * patient_id (FK, bigint) |
| 176 | | * doctor_id (FK, bigint) |
| 177 | | * technician_id (FK, bigint) |
| 178 | | * test_date (date) |
| 179 | | * notes (text) |
| | 496 | Records a specific, actual occurrence of a catalog lab test carried out on a patient that is ordered by a doctor, conducted by a technician. |
| | 497 | |
| | 498 | * '''Candidate keys:''' |
| | 499 | |
| | 500 | performed_test_id (surrogate) only. |
| | 501 | |
| | 502 | * '''Attributes:''' |
| | 503 | |
| | 504 | performed_test_id (PK, bigint) — required |
| | 505 | |
| | 506 | test_id (FK, bigint) — required, references Lab_Tests |
| | 507 | |
| | 508 | patient_id (FK, bigint) — required, references Patients |
| | 509 | |
| | 510 | doctor_id (FK, bigint) — required, references Doctors |
| | 511 | |
| | 512 | technician_id (FK, bigint) — required, references Lab_Technician |
| | 513 | |
| | 514 | test_date (date) — required |
| | 515 | |
| | 516 | notes (text) — optional |
| 184 | | * prescription_id (FK, bigint) |
| 185 | | * record_id (FK, bigint) |
| 186 | | * dosage (text) |
| 187 | | * frequency (text) |
| 188 | | * duration (text) |
| 189 | | * notes (text) |
| | 521 | An associative (M:N) entity linking Prescriptions to Medical_Records. Carries its own attributes because dosage/frequency/duration are specific to the record a medication was prescribed within, not to the medication itself. |
| | 522 | |
| | 523 | * '''Candidate keys:''' |
| | 524 | |
| | 525 | the composite (prescription_id, record_id) — a medication should appear at most once per record. |
| | 526 | * '''Attributes:''' |
| | 527 | |
| | 528 | prescription_id (FK, bigint) — required, part of composite PK, references Prescriptions |
| | 529 | |
| | 530 | record_id (FK, bigint) — required, part of composite PK, references Medical_Records |
| | 531 | |
| | 532 | dosage (text) — required |
| | 533 | |
| | 534 | frequency (text) — required |
| | 535 | |
| | 536 | duration (text) — required |
| | 537 | |
| | 538 | notes (text) — optional |
| 192 | | * record_id (FK, bigint) |
| 193 | | * symptom_id (FK, bigint) |
| 194 | | * severity (text) |
| | 541 | An associative (M:N) entity linking Medical_Records to Symptoms. Intended to carry a per-record severity, since how severe a symptom is is specific to that record/visit, not the symptom catalog entry. |
| | 542 | |
| | 543 | * '''Candidate keys:''' |
| | 544 | |
| | 545 | the composite (record_id, symptom_id) - a symptom should appear at most once per record. |
| | 546 | * '''Attributes:''' |
| | 547 | |
| | 548 | record_id (FK, bigint) — required, part of composite PK, references Medical_Records |
| | 549 | |
| | 550 | symptom_id (FK, bigint) — required, part of composite PK, references Symptoms |
| | 551 | |
| | 552 | severity (text) — optional; no restricted value set enforced in the database |
| 197 | | * record_id (FK, bigint) |
| 198 | | * allergy_id (FK, bigint) |
| 199 | | * reaction (text) |
| 200 | | * severity (text) |
| | 555 | An associative (M:N) entity linking Medical_Records to Allergies. Intended to carry the reaction and severity observed for that patient within that specific record, distinct from the general allergy catalog entry. |
| | 556 | |
| | 557 | * '''Candidate keys:''' |
| | 558 | |
| | 559 | the composite (record_id, allergy_id) — an allergy should appear at most once per record. |
| | 560 | * '''Attributes:''' |
| | 561 | |
| | 562 | record_id (FK, bigint) — required, part of composite PK, references Medical_Records |
| | 563 | |
| | 564 | allergy_id (FK, bigint) — required, part of composite PK, references Allergies |
| | 565 | |
| | 566 | reaction (text) — optional |
| | 567 | |
| | 568 | severity (text) — optional |
| | 569 | |