| 1 | -- Delete tables if they exist
|
|---|
| 2 | DROP TABLE IF EXISTS NEED_APPROVAL CASCADE;
|
|---|
| 3 | DROP TABLE IF EXISTS READING_LIST_ITEMS CASCADE;
|
|---|
| 4 | DROP TABLE IF EXISTS HAS_GENRE CASCADE;
|
|---|
| 5 | DROP TABLE IF EXISTS COLLABORATION CASCADE;
|
|---|
| 6 | DROP TABLE IF EXISTS COMMENT CASCADE;
|
|---|
| 7 | DROP TABLE IF EXISTS LIKES CASCADE;
|
|---|
| 8 | DROP TABLE IF EXISTS AI_SUGGESTION CASCADE;
|
|---|
| 9 | DROP TABLE IF EXISTS NOTIFICATION CASCADE;
|
|---|
| 10 | DROP TABLE IF EXISTS READING_LIST CASCADE;
|
|---|
| 11 | DROP TABLE IF EXISTS CHAPTER CASCADE;
|
|---|
| 12 | DROP TABLE IF EXISTS STORY CASCADE;
|
|---|
| 13 | DROP TABLE IF EXISTS WRITER CASCADE;
|
|---|
| 14 | DROP TABLE IF EXISTS REGULAR_USER CASCADE;
|
|---|
| 15 | DROP TABLE IF EXISTS ADMINS CASCADE;
|
|---|
| 16 | DROP TABLE IF EXISTS GENRE CASCADE;
|
|---|
| 17 | DROP TABLE IF EXISTS USERS CASCADE;
|
|---|
| 18 |
|
|---|
| 19 | -- Tables
|
|---|
| 20 |
|
|---|
| 21 | CREATE TABLE USERS(
|
|---|
| 22 | user_id SERIAL PRIMARY KEY,
|
|---|
| 23 | username VARCHAR(255) NOT NULL UNIQUE,
|
|---|
| 24 | email VARCHAR(255) NOT NULL UNIQUE,
|
|---|
| 25 | user_name VARCHAR(100) NOT NULL,
|
|---|
| 26 | surname VARCHAR(100) NOT NULL,
|
|---|
| 27 | password VARCHAR(255) NOT NULL,
|
|---|
| 28 | user_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 29 | user_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 30 | CONSTRAINT email_format CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
|
|---|
| 31 | );
|
|---|
| 32 |
|
|---|
| 33 | CREATE TABLE ADMINS(
|
|---|
| 34 | user_id INTEGER PRIMARY KEY,
|
|---|
| 35 | assigned_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 36 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 37 | ON DELETE CASCADE
|
|---|
| 38 | ON UPDATE CASCADE
|
|---|
| 39 | );
|
|---|
| 40 |
|
|---|
| 41 | CREATE TABLE REGULAR_USER(
|
|---|
| 42 | user_id INTEGER PRIMARY KEY,
|
|---|
| 43 | joined_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 44 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 45 | ON DELETE CASCADE
|
|---|
| 46 | ON UPDATE CASCADE
|
|---|
| 47 | );
|
|---|
| 48 |
|
|---|
| 49 | CREATE TABLE WRITER(
|
|---|
| 50 | user_id INTEGER PRIMARY KEY,
|
|---|
| 51 | bio TEXT,
|
|---|
| 52 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 53 | ON DELETE CASCADE
|
|---|
| 54 | ON UPDATE CASCADE
|
|---|
| 55 | );
|
|---|
| 56 |
|
|---|
| 57 | CREATE TABLE STORY(
|
|---|
| 58 | story_id SERIAL PRIMARY KEY,
|
|---|
| 59 | title VARCHAR(200) NOT NULL DEFAULT '',
|
|---|
| 60 | mature_content BOOLEAN NOT NULL,
|
|---|
| 61 | short_description VARCHAR(500) NOT NULL,
|
|---|
| 62 | image VARCHAR(2048),
|
|---|
| 63 | story_content TEXT NOT NULL,
|
|---|
| 64 | status VARCHAR(50) NOT NULL DEFAULT 'draft',
|
|---|
| 65 | user_id INTEGER NOT NULL,
|
|---|
| 66 | story_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 67 | story_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 68 | CONSTRAINT status_values CHECK (status IN ('draft', 'published', 'archived')),
|
|---|
| 69 | FOREIGN KEY (user_id) REFERENCES WRITER(user_id)
|
|---|
| 70 | ON DELETE CASCADE
|
|---|
| 71 | ON UPDATE CASCADE
|
|---|
| 72 | );
|
|---|
| 73 |
|
|---|
| 74 | CREATE TABLE CHAPTER(
|
|---|
| 75 | chapter_id SERIAL PRIMARY KEY,
|
|---|
| 76 | chapter_number INTEGER NOT NULL,
|
|---|
| 77 | chapter_name VARCHAR(100) NOT NULL,
|
|---|
| 78 | title VARCHAR(200) NOT NULL,
|
|---|
| 79 | chapter_content TEXT NOT NULL,
|
|---|
| 80 | word_count INTEGER CHECK (word_count >= 0),
|
|---|
| 81 | rating DECIMAL(3,2) CHECK (rating >= 0 AND rating <= 5),
|
|---|
| 82 | published_at TIMESTAMPTZ NOT NULL,
|
|---|
| 83 | view_count INTEGER DEFAULT 0 CHECK (view_count >= 0),
|
|---|
| 84 | story_id INTEGER NOT NULL,
|
|---|
| 85 | chapter_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 86 | chapter_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 87 | CONSTRAINT unique_chapter_number UNIQUE(story_id, chapter_number),
|
|---|
| 88 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 89 | ON DELETE CASCADE
|
|---|
| 90 | ON UPDATE CASCADE
|
|---|
| 91 | );
|
|---|
| 92 |
|
|---|
| 93 | CREATE TABLE GENRE(
|
|---|
| 94 | genre_id SERIAL PRIMARY KEY,
|
|---|
| 95 | genre_name VARCHAR(100) NOT NULL UNIQUE
|
|---|
| 96 | );
|
|---|
| 97 |
|
|---|
| 98 | CREATE TABLE READING_LIST(
|
|---|
| 99 | list_id SERIAL PRIMARY KEY,
|
|---|
| 100 | list_name VARCHAR(100) NOT NULL,
|
|---|
| 101 | list_content TEXT,
|
|---|
| 102 | is_public BOOLEAN NOT NULL,
|
|---|
| 103 | user_id INTEGER NOT NULL,
|
|---|
| 104 | list_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 105 | list_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 106 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 107 | ON DELETE CASCADE
|
|---|
| 108 | ON UPDATE CASCADE
|
|---|
| 109 | );
|
|---|
| 110 |
|
|---|
| 111 | CREATE TABLE NOTIFICATION(
|
|---|
| 112 | notification_id SERIAL PRIMARY KEY,
|
|---|
| 113 | notification_content TEXT NOT NULL,
|
|---|
| 114 | content_type VARCHAR(50) NOT NULL,
|
|---|
| 115 | is_read BOOLEAN DEFAULT FALSE,
|
|---|
| 116 | link VARCHAR(500),
|
|---|
| 117 | user_id INTEGER NOT NULL,
|
|---|
| 118 | story_id INTEGER NOT NULL,
|
|---|
| 119 | notification_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 120 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 121 | ON DELETE CASCADE
|
|---|
| 122 | ON UPDATE CASCADE,
|
|---|
| 123 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 124 | ON DELETE CASCADE
|
|---|
| 125 | ON UPDATE CASCADE
|
|---|
| 126 | );
|
|---|
| 127 |
|
|---|
| 128 | CREATE TABLE AI_SUGGESTION(
|
|---|
| 129 | suggestion_id SERIAL PRIMARY KEY,
|
|---|
| 130 | original_text TEXT NOT NULL,
|
|---|
| 131 | suggested_text TEXT NOT NULL,
|
|---|
| 132 | suggestion_type VARCHAR(50) NOT NULL,
|
|---|
| 133 | accepted BOOLEAN NOT NULL DEFAULT FALSE,
|
|---|
| 134 | suggestion_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 135 | applied_at TIMESTAMPTZ,
|
|---|
| 136 | story_id INTEGER NOT NULL,
|
|---|
| 137 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 138 | ON DELETE CASCADE
|
|---|
| 139 | ON UPDATE CASCADE
|
|---|
| 140 | );
|
|---|
| 141 |
|
|---|
| 142 | CREATE TABLE LIKES(
|
|---|
| 143 | user_id INTEGER,
|
|---|
| 144 | story_id INTEGER,
|
|---|
| 145 | liked_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 146 | CONSTRAINT like_pk PRIMARY KEY(user_id, story_id),
|
|---|
| 147 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 148 | ON DELETE CASCADE
|
|---|
| 149 | ON UPDATE CASCADE,
|
|---|
| 150 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 151 | ON DELETE CASCADE
|
|---|
| 152 | ON UPDATE CASCADE
|
|---|
| 153 | );
|
|---|
| 154 |
|
|---|
| 155 | CREATE TABLE COMMENT(
|
|---|
| 156 | comment_id SERIAL PRIMARY KEY,
|
|---|
| 157 | comment_content TEXT NOT NULL,
|
|---|
| 158 | user_id INTEGER NOT NULL,
|
|---|
| 159 | story_id INTEGER NOT NULL,
|
|---|
| 160 | comment_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 161 | comment_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 162 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 163 | ON DELETE CASCADE
|
|---|
| 164 | ON UPDATE CASCADE,
|
|---|
| 165 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 166 | ON DELETE CASCADE
|
|---|
| 167 | ON UPDATE CASCADE
|
|---|
| 168 | );
|
|---|
| 169 |
|
|---|
| 170 | CREATE TABLE COLLABORATION(
|
|---|
| 171 | user_id INTEGER,
|
|---|
| 172 | story_id INTEGER,
|
|---|
| 173 | role VARCHAR(50) NOT NULL,
|
|---|
| 174 | permission_level INTEGER,
|
|---|
| 175 | collab_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 176 | CONSTRAINT collaboration_pk PRIMARY KEY(user_id, story_id),
|
|---|
| 177 | FOREIGN KEY (user_id) REFERENCES USERS(user_id)
|
|---|
| 178 | ON DELETE CASCADE
|
|---|
| 179 | ON UPDATE CASCADE,
|
|---|
| 180 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 181 | ON DELETE CASCADE
|
|---|
| 182 | ON UPDATE CASCADE
|
|---|
| 183 | );
|
|---|
| 184 |
|
|---|
| 185 | CREATE TABLE HAS_GENRE(
|
|---|
| 186 | story_id INTEGER,
|
|---|
| 187 | genre_id INTEGER,
|
|---|
| 188 | CONSTRAINT has_genre_pk PRIMARY KEY(story_id, genre_id),
|
|---|
| 189 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 190 | ON DELETE CASCADE
|
|---|
| 191 | ON UPDATE CASCADE,
|
|---|
| 192 | FOREIGN KEY (genre_id) REFERENCES GENRE(genre_id)
|
|---|
| 193 | ON DELETE CASCADE
|
|---|
| 194 | ON UPDATE CASCADE
|
|---|
| 195 | );
|
|---|
| 196 |
|
|---|
| 197 | CREATE TABLE READING_LIST_ITEMS(
|
|---|
| 198 | list_id INTEGER,
|
|---|
| 199 | story_id INTEGER,
|
|---|
| 200 | added_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|---|
| 201 | CONSTRAINT reading_list_items_pk PRIMARY KEY(list_id, story_id),
|
|---|
| 202 | FOREIGN KEY (list_id) REFERENCES READING_LIST(list_id)
|
|---|
| 203 | ON DELETE CASCADE
|
|---|
| 204 | ON UPDATE CASCADE,
|
|---|
| 205 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 206 | ON DELETE CASCADE
|
|---|
| 207 | ON UPDATE CASCADE
|
|---|
| 208 | );
|
|---|
| 209 |
|
|---|
| 210 | CREATE TABLE NEED_APPROVAL(
|
|---|
| 211 | suggestion_id INTEGER,
|
|---|
| 212 | story_id INTEGER,
|
|---|
| 213 | chapter_id INTEGER,
|
|---|
| 214 | CONSTRAINT need_approval_pk PRIMARY KEY(suggestion_id, story_id, chapter_id),
|
|---|
| 215 | FOREIGN KEY (suggestion_id) REFERENCES AI_SUGGESTION(suggestion_id)
|
|---|
| 216 | ON DELETE CASCADE
|
|---|
| 217 | ON UPDATE CASCADE,
|
|---|
| 218 | FOREIGN KEY (story_id) REFERENCES STORY(story_id)
|
|---|
| 219 | ON DELETE CASCADE
|
|---|
| 220 | ON UPDATE CASCADE,
|
|---|
| 221 | FOREIGN KEY (chapter_id) REFERENCES CHAPTER(chapter_id)
|
|---|
| 222 | ON DELETE CASCADE
|
|---|
| 223 | ON UPDATE CASCADE
|
|---|
| 224 | ); |
|---|