| 6 | | In this phase we implement: |
| 7 | | * Indexes – faster searching/filtering in large tables |
| 8 | | * Constraints – enforce validity and prevent inconsistent records |
| 9 | | * Triggers – automate rules (price calculation, venue capacity control) |
| 10 | | * Views – simplify reporting queries and provide reusable reports |
| 11 | | |
| 12 | | == What we cover in this phase == |
| 13 | | * Indexes for frequent query patterns (events, bookings, RSVP) |
| 14 | | * Constraints for data validation + preventing overlapping bookings |
| 15 | | * Triggers to automate derived values (venue price) and enforce capacity |
| 16 | | * Views for simplified summaries (RSVP counts, confirmed bookings, guest counts) |
| 17 | | |
| 18 | | ---- |
| 19 | | |
| 20 | | == Indexes (Performance Improvement) == |
| 21 | | |
| 22 | | === Index: Event Date and Time Search Optimization === |
| 23 | | This improves performance when searching or filtering events by date and time interval. |
| 24 | | |
| 25 | | *Tables affected:* `event` |
| 26 | | *Index type:* B-tree composite indexes |
| | 4 | This phase focuses on implementing advanced database mechanisms that enforce business logic directly at the database level. |
| | 5 | Instead of relying only on application code, the database itself ensures correctness, prevents invalid states, and improves performance. |
| | 6 | In the Wedding Planner project, this is especially important because the system handles bookings, RSVPs and guest management where mistakes (double booking, invalid status values, capacity overflow) must be impossible. |
| | 7 | |
| | 8 | In this phase we implemented: |
| | 9 | * Indexes – to speed up searches and filtering |
| | 10 | * Constraints – to prevent inconsistent or invalid data (including overlap prevention) |
| | 11 | * Triggers – automation of derived fields and enforcing business rules |
| | 12 | * Views – simplified reporting and aggregated queries |
| | 13 | |
| | 14 | == Indexes == |
| | 15 | Indexes significantly improve performance for common queries such as scheduling, availability checks and RSVP filtering. |
| | 16 | |
| | 17 | === Index 1: Event date & time optimization === |
| | 18 | This index improves performance when searching or filtering events by date and start/end time (e.g., event timeline and schedule overview). |
| | 19 | |
| | 20 | *Table:* ''event'' |
| | 21 | *Type:* Composite B-tree index |
| 33 | | *Explanation:* |
| 34 | | The indexes store pre-sorted combinations of (`date`, `start_time`) and (`date`, `end_time`), which allows fast retrieval of events for a specific day/time window without scanning the entire table. |
| 35 | | |
| 36 | | --- |
| 37 | | |
| 38 | | === Index: Booking Status Filtering === |
| 39 | | These indexes optimize availability checks and booking filtering by date and status. |
| 40 | | |
| 41 | | *Tables affected:* `venue_booking`, `photographer_booking`, `band_booking` |
| 42 | | *Index type:* B-tree composite indexes |
| | 28 | *Why this matters:* |
| | 29 | Without indexes, PostgreSQL must scan the entire ''event'' table (Seq Scan) to find matching records. |
| | 30 | With indexes, it can quickly retrieve only the relevant events for a given wedding date and time range. |
| | 31 | |
| | 32 | === Index 2: Booking status filtering (availability checks) === |
| | 33 | These indexes optimize filtering bookings by date and status for venues, photographers and bands (used in availability endpoints and admin dashboards). |
| | 34 | |
| | 35 | *Tables:* ''venue_booking'', ''photographer_booking'', ''band_booking'' |
| | 36 | *Type:* Composite B-tree index |
| 50 | | *Explanation:* |
| 51 | | Booking records are organized by (`date`, `status`), allowing fast retrieval of rows such as: “confirmed bookings on a given date”. |
| 52 | | |
| 53 | | --- |
| 54 | | |
| 55 | | === Index: RSVP Status Filtering === |
| 56 | | This index speeds up reports of RSVP responses per event. |
| 57 | | |
| 58 | | *Table affected:* `event_rsvp` |
| 59 | | *Index type:* Composite B-tree index |
| | 44 | *Why this matters:* |
| | 45 | Availability checks would otherwise require full scans across booking tables. With indexes the system stays scalable as data grows. |
| | 46 | |
| | 47 | === Index 3: RSVP filtering per event === |
| | 48 | This index improves performance when retrieving RSVP responses for an event grouped by status. |
| | 49 | |
| | 50 | *Table:* ''event_rsvp'' |
| | 51 | *Type:* Composite B-tree index |
| 65 | | *Explanation:* |
| 66 | | RSVP rows are grouped by event and status, so queries like “all accepted guests for event X” are executed efficiently. |
| 67 | | |
| 68 | | ---- |
| 69 | | |
| 70 | | == Constraints (Data Integrity) == |
| 71 | | |
| 72 | | === Constraint: Prevent Overlapping Bookings === |
| 73 | | This prevents double-booking of the same venue/photographer/band at overlapping time intervals. |
| 74 | | |
| 75 | | To support this constraint, we use: |
| 76 | | * `btree_gist` extension |
| 77 | | * generated timestamp columns (`start_ts`, `end_ts`) |
| 78 | | * GiST exclusion constraints |
| | 57 | *Why this matters:* |
| | 58 | Queries such as “all accepted guests for event_id X” are much faster with this index. |
| | 59 | |
| | 60 | == Constraints == |
| | 61 | Constraints enforce correctness of the data and prevent invalid or inconsistent states. |
| | 62 | |
| | 63 | === Constraint 1: Prevent overlapping bookings (no double booking) === |
| | 64 | One of the most important business rules in Wedding Planner is that a resource cannot be booked twice in overlapping time intervals. |
| | 65 | This is enforced with EXCLUDE constraints using GiST indexes. |
| | 66 | |
| | 67 | First, we enable required extension: |
| 162 | | *Explanation:* |
| 163 | | If an invalid value is inserted or updated, PostgreSQL rejects the operation and keeps the database consistent. |
| 164 | | |
| 165 | | == Triggers (Automation of Business Logic) == |
| 166 | | |
| 167 | | === Trigger: Automatic Venue Price Calculation === |
| 168 | | This trigger calculates the total venue booking price based on: |
| 169 | | * venue price per guest |
| 170 | | * current number of guests for that wedding |
| 171 | | |
| 172 | | *Tables involved:* `venue_booking`, `venue`, `guest` |
| 173 | | *Trigger type:* BEFORE INSERT on `venue_booking` |
| | 154 | *Why this matters:* |
| | 155 | The database rejects invalid values automatically, ensuring consistent and predictable data for the application. |
| | 156 | |
| | 157 | == Triggers == |
| | 158 | Triggers automate important derived logic and enforce real-world constraints. |
| | 159 | |
| | 160 | === Trigger 1: Automatic venue price calculation === |
| | 161 | This trigger automatically calculates venue booking price if it is not provided, based on: |
| | 162 | * venue.price_per_guest |
| | 163 | * number of guests for the wedding |
| 196 | | *Reason for use:* |
| 197 | | This ensures price is always correct and prevents manual calculation errors inside the application. |
| 198 | | |
| 199 | | --- |
| 200 | | |
| 201 | | === Trigger: Venue Capacity Enforcement === |
| 202 | | This trigger prevents adding guests if the confirmed venue capacity will be exceeded. |
| 203 | | |
| 204 | | *Tables involved:* `guest`, `venue_booking`, `venue` |
| 205 | | *Trigger type:* BEFORE INSERT OR UPDATE on `guest` |
| | 186 | *Why this matters:* |
| | 187 | Price is a derived field. This ensures it is always correct and not dependent only on application-level calculations. |
| | 188 | |
| | 189 | === Trigger 2: Venue capacity enforcement === |
| | 190 | This trigger prevents inserting/updating guests when the number of guests exceeds the confirmed venue capacity. |
| 244 | | *Reason for use:* |
| 245 | | This enforces a real-world rule: guest count cannot exceed venue capacity. |
| 246 | | |
| 247 | | ---- |
| 248 | | |
| 249 | | == Views (Simplified Reports) == |
| 250 | | |
| 251 | | === View: RSVP summary per event === |
| 252 | | Shows RSVP counts per status for each event. |
| | 231 | *Why this matters:* |
| | 232 | This enforces a critical business rule: a wedding cannot have more guests than venue capacity. |
| | 233 | |
| | 234 | == Views == |
| | 235 | Views simplify reporting and provide useful aggregated results. |
| | 236 | |
| | 237 | === View 1: RSVP summary per event === |
| | 238 | This view returns counts of accepted/declined/pending RSVP answers for each event. |
| 321 | | In this phase we implemented advanced database mechanisms that improve scalability and correctness of our Wedding Planner system. |
| 322 | | Indexes help queries run faster as the number of bookings/events grows. |
| 323 | | Constraints enforce strict data rules and prevent invalid states, such as double-booking. |
| 324 | | Triggers automate derived values and business rules like venue capacity control. |
| 325 | | Finally, views provide reusable reports and simplify querying for common summaries. |
| | 309 | Phase P7 implements advanced database-level mechanisms for the Wedding Planner system. Indexes improve scalability and query performance, constraints prevent invalid states (especially double booking), triggers automate key business logic (price calculation and capacity enforcement), and views provide simplified reporting. |
| | 310 | With these mechanisms, the database becomes robust, consistent, and production-ready. |