DDL, DML and Views: planora_ddl.sql

File planora_ddl.sql, 15.6 KB (added by 231035, 5 weeks ago)
Line 
1drop table if exists booking_amenities cascade;
2drop table if exists booking_discounts cascade;
3drop table if exists room_amenities cascade;
4drop table if exists property_amenities cascade;
5drop table if exists favorite_listings cascade;
6drop table if exists reviews cascade;
7drop table if exists payments cascade;
8drop table if exists bookings cascade;
9drop table if exists discounts cascade;
10drop table if exists availability_blocks cascade;
11drop table if exists availability_windows cascade;
12drop table if exists images cascade;
13drop table if exists cancellation_policies cascade;
14drop table if exists notifications cascade;
15drop table if exists rooms cascade;
16drop table if exists room_types cascade;
17drop table if exists properties cascade;
18drop table if exists listing_types cascade;
19drop table if exists amenities cascade;
20drop table if exists payment_methods cascade;
21drop table if exists hosts cascade;
22drop table if exists guests cascade;
23drop table if exists admins cascade;
24drop table if exists host_applications cascade;
25drop table if exists users cascade;
26drop table if exists addresses cascade;
27drop table if exists countries cascade;
28
29
30create table countries (
31 country_id BIGSERIAL PRIMARY KEY,
32 country_name varchar(255) NOT NULL,
33 country_code varchar(10) NOT NULL,
34 CONSTRAINT uq_countries_country_code_ci UNIQUE (country_code)
35);
36
37create table addresses (
38 address_id BIGSERIAL PRIMARY KEY,
39 country_id BIGINT NOT NULL REFERENCES countries(country_id) ON DELETE RESTRICT ON UPDATE CASCADE,
40 zip_code varchar(50) NOT NULL ,
41 street varchar(100) NOT NULL,
42 city varchar(100) NOT NULL
43);
44create table users (
45 user_id BIGSERIAL PRIMARY KEY ,
46 email varchar(255) ,
47 password_hash varchar(255),
48 first_name varchar(255) ,
49 last_name varchar(255) ,
50 phone varchar(30) ,
51 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
52 updated_at TIMESTAMP,
53 CONSTRAINT uq_users_email_ci UNIQUE (email)
54);
55
56INSERT INTO users (user_id, email, password_hash, first_name, last_name)
57VALUES (-1, 'unknown@system.local', 'UNKNOWN_HASH', 'Unknown', 'User');
58
59
60create table admins (
61 admin_id BIGSERIAL PRIMARY KEY ,
62 user_id BIGINT NOT NULL UNIQUE default -1
63 REFERENCES users(user_id)
64 ON DELETE SET DEFAULT
65 ON UPDATE CASCADE
66);
67
68INSERT INTO admins (admin_id, user_id)
69VALUES (-1, -1);
70
71
72drop table if exists guests cascade ;
73create table guests (
74 guest_id BIGSERIAL PRIMARY KEY,
75 user_id BIGINT NOT NULL UNIQUE default -1
76 REFERENCES users(user_id)
77 ON DELETE SET DEFAULT
78 ON UPDATE CASCADE
79);
80INSERT INTO guests (guest_id, user_id)
81VALUES (-1, -1);
82
83create table host_applications (
84 application_id BIGSERIAL PRIMARY KEY,
85 user_id BIGINT NOT NULL UNIQUE REFERENCES users(user_id) ON DELETE SET DEFAULT ON UPDATE CASCADE,
86 application_date DATE NOT NULL DEFAULT CURRENT_DATE,
87 status varchar(50) NOT NULL,
88 reviewed_by_admin_id BIGINT REFERENCES admins(admin_id) ON DELETE SET DEFAULT ON UPDATE CASCADE,
89 review_date DATE,
90 rejection_reason text,
91 CONSTRAINT ck_host_application_status CHECK (
92 status IN ('PENDING', 'APPROVED', 'REJECTED', 'UNDER_REVIEW')
93 ),
94 CONSTRAINT ck_host_application_rejected_reason CHECK (
95 (status = 'REJECTED' AND rejection_reason IS NOT NULL)
96 OR status <> 'REJECTED'
97 ),
98 CONSTRAINT ck_host_application_reviewed CHECK (
99 (status IN ('APPROVED', 'REJECTED') AND reviewed_by_admin_id IS NOT NULL AND review_date IS NOT NULL)
100 OR status NOT IN ('APPROVED', 'REJECTED')
101 )
102);
103
104create table hosts (
105 user_id BIGINT PRIMARY KEY REFERENCES users(user_id) ON DELETE set default ON UPDATE CASCADE,
106 application_id BIGINT UNIQUE REFERENCES host_applications(application_id) ON DELETE SET DEFAULT ON UPDATE CASCADE
107);
108
109create table listing_types (
110 listing_type_id BIGSERIAL PRIMARY KEY,
111 type_name varchar(255) NOT NULL UNIQUE,
112 description text
113);
114
115create table payment_methods (
116 payment_method_id BIGSERIAL PRIMARY KEY,
117 method_name varchar(255) NOT NULL UNIQUE,
118 description text
119);
120
121create table amenities (
122 amenity_id BIGSERIAL PRIMARY KEY,
123 amenity_name varchar(100) NOT NULL,
124 amenity_type varchar(255) NOT NULL,
125 description text,
126 is_included BOOLEAN NOT NULL DEFAULT FALSE,
127 price NUMERIC(10,2),
128 CONSTRAINT ck_amenity_price_nonnegative CHECK (price IS NULL OR price >= 0)
129);
130
131create table properties (
132 property_id BIGSERIAL PRIMARY KEY,
133 host_id BIGINT NOT NULL REFERENCES hosts(user_id) ON DELETE set default ON UPDATE CASCADE,
134 listing_type_id BIGINT NOT NULL REFERENCES listing_types(listing_type_id) ON DELETE restrict ON UPDATE CASCADE,
135 address_id BIGINT NOT NULL REFERENCES addresses(address_id) ON DELETE RESTRICT ON UPDATE CASCADE,
136 title varchar(255) NOT NULL,
137 description text,
138 base_price NUMERIC(10,2) NOT NULL,
139 max_guests INTEGER NOT NULL,
140 status varchar(30) NOT NULL,
141 created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
142 updated_at TIMESTAMP,
143 CONSTRAINT ck_property_price_nonnegative CHECK (base_price >= 0),
144 CONSTRAINT ck_property_max_guests_positive CHECK (max_guests > 0),
145 CONSTRAINT ck_property_status CHECK (
146 status IN ('DRAFT', 'ACTIVE', 'INACTIVE', 'ARCHIVED')
147 )
148);
149
150create table room_types (
151 room_type_id BIGSERIAL PRIMARY KEY,
152 type_name varchar(100) NOT NULL UNIQUE,
153 description text
154);
155
156create table rooms (
157 room_id BIGSERIAL PRIMARY KEY,
158 property_id BIGINT NOT NULL REFERENCES properties(property_id) ON DELETE CASCADE ON UPDATE CASCADE,
159 room_type_id BIGINT NOT NULL REFERENCES room_types(room_type_id) ON DELETE RESTRICT ON UPDATE CASCADE,
160 room_name varchar(100) NOT NULL,
161 capacity INTEGER NOT NULL,
162 price_per_night NUMERIC(10,2) NOT NULL,
163 description text,
164 status varchar(50) NOT NULL,
165 extra_capacity INTEGER NOT NULL DEFAULT 0,
166 extra_guest_price NUMERIC(10,2),
167 CONSTRAINT ck_room_capacity_positive CHECK (capacity > 0),
168 CONSTRAINT ck_room_extra_capacity_nonnegative CHECK (extra_capacity >= 0),
169 CONSTRAINT ck_room_price_nonnegative CHECK (price_per_night >= 0),
170 CONSTRAINT ck_room_extra_guest_price_nonnegative CHECK (
171 extra_guest_price IS NULL OR extra_guest_price >= 0
172 ),
173 CONSTRAINT ck_room_status CHECK (
174 status IN ('ACTIVE', 'INACTIVE', 'MAINTENANCE', 'UNAVAILABLE')
175 ),
176 CONSTRAINT uq_room_name_per_property UNIQUE (property_id, room_name)
177);
178
179create table availability_blocks (
180 availability_id BIGSERIAL PRIMARY KEY,
181 room_id BIGINT NOT NULL REFERENCES rooms(room_id) ON DELETE CASCADE ON UPDATE CASCADE,
182 blocked_from_date DATE NOT NULL,
183 blocked_to_date DATE NOT NULL,
184 blocked_from_time TIMESTAMP NOT NULL,
185 blocked_to_time TIMESTAMP NOT NULL,
186 description varchar(255),
187 CONSTRAINT ck_availability_date_range CHECK (blocked_to_date >= blocked_from_date),
188 CONSTRAINT ck_availability_time_range CHECK (blocked_to_time > blocked_from_time),
189 CONSTRAINT ck_availability_from_time_date CHECK (blocked_from_time::date = blocked_from_date),
190 CONSTRAINT ck_availability_to_time_date CHECK (blocked_to_time::date = blocked_to_date)
191);
192drop table if exists discounts cascade ;
193create table discounts (
194 discount_id BIGSERIAL PRIMARY KEY,
195 host_id BIGINT NOT NULL REFERENCES hosts(user_id) ON DELETE set default ON UPDATE CASCADE,
196 code varchar(255) NOT NULL,
197 title varchar(255) NOT NULL,
198 description text,
199 discount_type varchar(30) NOT NULL,
200 discount_value NUMERIC(10,2) NOT NULL,
201 valid_from DATE NOT NULL,
202 valid_to DATE NOT NULL,
203 is_active BOOLEAN NOT NULL DEFAULT TRUE,
204 CONSTRAINT uq_discounts_code_ci UNIQUE (code),
205 CONSTRAINT ck_discount_type CHECK (discount_type IN ('PERCENTAGE', 'FIXED')),
206 CONSTRAINT ck_discount_value_nonnegative CHECK (discount_value >= 0),
207 CONSTRAINT ck_discount_percentage_cap CHECK (
208 discount_type <> 'PERCENTAGE'
209 OR (discount_value >= 0 AND discount_value <= 100)
210 ),
211 CONSTRAINT ck_discount_fixed_positive CHECK (
212 discount_type <> 'FIXED' OR discount_value > 0
213 ),
214 CONSTRAINT ck_discount_valid_range CHECK (valid_to >= valid_from)
215);
216
217create table bookings (
218 booking_id BIGSERIAL PRIMARY KEY,
219 guest_id BIGINT NOT NULL REFERENCES guests(guest_id) ON DELETE set default ON UPDATE CASCADE,
220 room_id BIGINT NOT NULL REFERENCES rooms(room_id) ON DELETE restrict ON UPDATE CASCADE,
221 check_in_date DATE NOT NULL,
222 check_out_date DATE NOT NULL,
223 guests_count INTEGER NOT NULL,
224 total_price NUMERIC(10,2) NOT NULL,
225 booking_status varchar(30) NOT NULL,
226 booked_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
227 CONSTRAINT ck_booking_date_range CHECK (check_out_date > check_in_date),
228 CONSTRAINT ck_booking_guest_count_positive CHECK (guests_count > 0),
229 CONSTRAINT ck_booking_total_price_nonnegative CHECK (total_price >= 0),
230 CONSTRAINT ck_booking_status CHECK (
231 booking_status IN ('PENDING', 'CONFIRMED', 'CANCELLED', 'COMPLETED', 'NO_SHOW')
232 )
233);
234
235create table payments (
236 payment_id BIGSERIAL PRIMARY KEY,
237 booking_id BIGINT NOT NULL UNIQUE REFERENCES bookings(booking_id) ON DELETE restrict ON UPDATE CASCADE,
238 payment_method_id BIGINT NOT NULL REFERENCES payment_methods(payment_method_id) ON DELETE RESTRICT ON UPDATE CASCADE,
239 amount NUMERIC(10,2) NOT NULL,
240 payment_status varchar(30) NOT NULL,
241 paid_at TIMESTAMP,
242 CONSTRAINT ck_payment_amount_nonnegative CHECK (amount >= 0),
243 CONSTRAINT ck_payment_status CHECK (
244 payment_status IN ('PENDING', 'PAID', 'FAILED', 'REFUNDED', 'PARTIALLY_REFUNDED')
245 ),
246 CONSTRAINT ck_payment_paid_has_timestamp CHECK (
247 (payment_status = 'PAID' AND paid_at IS NOT NULL)
248 OR payment_status <> 'PAID'
249 )
250);
251create table reviews (
252 review_id BIGSERIAL PRIMARY KEY,
253 booking_id BIGINT NOT NULL UNIQUE REFERENCES bookings(booking_id) ON DELETE CASCADE ON UPDATE CASCADE,
254 guest_id BIGINT NOT NULL REFERENCES guests(guest_id) ON DELETE set default ON UPDATE CASCADE,
255 property_id BIGINT NOT NULL REFERENCES properties(property_id) ON DELETE CASCADE ON UPDATE CASCADE,
256 rating INTEGER NOT NULL,
257 comment text,
258 created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
259 CONSTRAINT ck_review_rating CHECK (rating BETWEEN 1 AND 5)
260);
261
262create table favorite_listings (
263 favorite_id BIGSERIAL PRIMARY KEY,
264 user_id BIGINT NOT NULL REFERENCES users(user_id) ON DELETE cascade ON UPDATE CASCADE,
265 property_id BIGINT NOT NULL REFERENCES properties(property_id) ON DELETE cascade ON UPDATE CASCADE,
266 created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
267 CONSTRAINT uq_favorite_listings_user_property UNIQUE (user_id, property_id)
268);
269
270create table notifications (
271 notification_id BIGSERIAL PRIMARY KEY,
272 user_id BIGINT NOT NULL REFERENCES users(user_id) ON DELETE set default ON UPDATE CASCADE,
273 message TEXT NOT NULL,
274 sent_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
275 is_read BOOLEAN NOT NULL DEFAULT FALSE
276);
277
278create table cancellation_policies (
279 policy_id BIGSERIAL PRIMARY KEY,
280 property_id BIGINT NOT NULL UNIQUE REFERENCES properties(property_id) ON DELETE CASCADE ON UPDATE CASCADE,
281 policy_name varchar(100) NOT NULL,
282 description TEXT,
283 refund_percentage INTEGER,
284 days_before_checking INTEGER,
285 CONSTRAINT ck_policy_refund_percentage CHECK (
286 refund_percentage IS NULL OR refund_percentage BETWEEN 0 AND 100
287 ),
288 CONSTRAINT ck_policy_days_nonnegative CHECK (
289 days_before_checking IS NULL OR days_before_checking >= 0
290 )
291);
292
293create table property_amenities (
294 property_id BIGINT NOT NULL REFERENCES properties(property_id) ON DELETE CASCADE ON UPDATE CASCADE,
295 amenity_id BIGINT NOT NULL REFERENCES amenities(amenity_id) ON DELETE CASCADE ON UPDATE CASCADE,
296 PRIMARY KEY (property_id, amenity_id)
297);
298
299create table room_amenities (
300 room_id BIGINT NOT NULL REFERENCES rooms(room_id) ON DELETE CASCADE ON UPDATE CASCADE,
301 amenity_id BIGINT NOT NULL REFERENCES amenities(amenity_id) ON DELETE CASCADE ON UPDATE CASCADE,
302 PRIMARY KEY (room_id, amenity_id)
303);
304
305
306create table booking_discounts (
307 booking_id BIGINT NOT NULL REFERENCES bookings(booking_id) ON DELETE CASCADE ON UPDATE CASCADE,
308 discount_id BIGINT NOT NULL REFERENCES discounts(discount_id) ON DELETE RESTRICT ON UPDATE CASCADE,
309 PRIMARY KEY (booking_id, discount_id)
310);
311
312create table booking_amenities (
313 booking_amenity_id BIGSERIAL PRIMARY KEY,
314 booking_id BIGINT NOT NULL REFERENCES bookings(booking_id) ON DELETE CASCADE ON UPDATE CASCADE,
315 amenity_id BIGINT NOT NULL REFERENCES amenities(amenity_id) ON DELETE RESTRICT ON UPDATE CASCADE,
316 quantity INTEGER NOT NULL DEFAULT 1,
317 CONSTRAINT uq_booking_amenities_booking_amenity UNIQUE (booking_id, amenity_id),
318 CONSTRAINT ck_booking_amenity_quantity_positive CHECK (quantity > 0)
319);
320
321create table images (
322 image_id BIGSERIAL PRIMARY KEY,
323 entity_type varchar(30) NOT NULL,
324 entity_id BIGINT NOT NULL,
325 property_id BIGINT REFERENCES properties(property_id) ON DELETE CASCADE ON UPDATE CASCADE,
326 room_id BIGINT REFERENCES rooms(room_id) ON DELETE CASCADE ON UPDATE CASCADE,
327 url varchar(255) NOT NULL,
328 alt_text varchar(255),
329 is_cover BOOLEAN NOT NULL DEFAULT FALSE,
330 sort_order INTEGER,
331 uploaded_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
332 CONSTRAINT ck_image_entity_type CHECK (entity_type IN ('PROPERTY', 'ROOM')),
333 CONSTRAINT ck_image_sort_order_nonnegative CHECK (sort_order IS NULL OR sort_order >= 0),
334 CONSTRAINT ck_image_exactly_one_owner CHECK (
335 (property_id IS NOT NULL AND room_id IS NULL AND entity_type = 'PROPERTY')
336 OR (property_id IS NULL AND room_id IS NOT NULL AND entity_type = 'ROOM')
337 ),
338 CONSTRAINT ck_image_entity_id_matches_owner CHECK (
339 (entity_type = 'PROPERTY' AND entity_id = property_id AND room_id IS NULL)
340 OR (entity_type = 'ROOM' AND entity_id = room_id AND property_id IS NULL)
341 )
342);
343
344drop table if exists availability_windows cascade ;
345CREATE TABLE availability_windows (
346 availability_window_id BIGSERIAL PRIMARY KEY,
347 room_id BIGINT NOT NULL REFERENCES rooms(room_id)
348 ON DELETE CASCADE ON UPDATE CASCADE,
349 available_date DATE NOT NULL,
350 status text not null
351);
352COMMIT;