-- Tasteby: Oracle ADB (23ai) Schema -- Run against Oracle ADB before starting the backend. -- 1. channels CREATE TABLE channels ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, channel_id VARCHAR2(50) NOT NULL, channel_name VARCHAR2(200) NOT NULL, channel_url VARCHAR2(500), is_active NUMBER(1) DEFAULT 1 NOT NULL, created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, CONSTRAINT pk_channels PRIMARY KEY (id), CONSTRAINT uq_channels_cid UNIQUE (channel_id) ); -- 2. videos CREATE TABLE videos ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, channel_id VARCHAR2(36) NOT NULL, video_id VARCHAR2(20) NOT NULL, title VARCHAR2(500) NOT NULL, url VARCHAR2(500) NOT NULL, published_at TIMESTAMP, transcript_text CLOB, status VARCHAR2(20) DEFAULT 'pending' NOT NULL, processed_at TIMESTAMP, created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, CONSTRAINT pk_videos PRIMARY KEY (id), CONSTRAINT uq_videos_vid UNIQUE (video_id), CONSTRAINT fk_videos_channel FOREIGN KEY (channel_id) REFERENCES channels(id), CONSTRAINT ck_videos_status CHECK (status IN ('pending','processing','done','error')) ); -- 3. restaurants CREATE TABLE restaurants ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, name VARCHAR2(200) NOT NULL, address VARCHAR2(500), region VARCHAR2(100), latitude NUMBER(10,7), longitude NUMBER(10,7), cuisine_type VARCHAR2(100), price_range VARCHAR2(50), phone VARCHAR2(50), website VARCHAR2(500), google_place_id VARCHAR2(200), created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, CONSTRAINT pk_restaurants PRIMARY KEY (id) ); -- 4. video_restaurants (N:M) CREATE TABLE video_restaurants ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, video_id VARCHAR2(36) NOT NULL, restaurant_id VARCHAR2(36) NOT NULL, foods_mentioned CLOB, evaluation CLOB, guests CLOB, air_date DATE, citation_text CLOB, created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, CONSTRAINT pk_video_restaurants PRIMARY KEY (id), CONSTRAINT fk_vr_video FOREIGN KEY (video_id) REFERENCES videos(id), CONSTRAINT fk_vr_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurants(id), CONSTRAINT uq_vr_video_rest UNIQUE (video_id, restaurant_id) ); -- JSON check constraints for CLOB JSON columns -- (Oracle 23ai supports IS JSON on CLOB) ALTER TABLE video_restaurants ADD CONSTRAINT ck_vr_foods CHECK (foods_mentioned IS JSON); ALTER TABLE video_restaurants ADD CONSTRAINT ck_vr_eval CHECK (evaluation IS JSON); ALTER TABLE video_restaurants ADD CONSTRAINT ck_vr_guests CHECK (guests IS JSON); -- 5. tasteby_users (NOT "users" — that table belongs to another project) CREATE TABLE tasteby_users ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, provider VARCHAR2(20) NOT NULL, provider_id VARCHAR2(200) NOT NULL, email VARCHAR2(200), nickname VARCHAR2(100), avatar_url VARCHAR2(500), created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, last_login_at TIMESTAMP, CONSTRAINT pk_tasteby_users PRIMARY KEY (id), CONSTRAINT uq_tasteby_users_provider UNIQUE (provider, provider_id), CONSTRAINT ck_tasteby_users_provider CHECK (provider IN ('google','apple')) ); -- 6. user_reviews CREATE TABLE user_reviews ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, user_id VARCHAR2(36) NOT NULL, restaurant_id VARCHAR2(36) NOT NULL, rating NUMBER(2,1) NOT NULL, review_text CLOB, visited_at DATE, created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, CONSTRAINT pk_user_reviews PRIMARY KEY (id), CONSTRAINT fk_ur_user FOREIGN KEY (user_id) REFERENCES tasteby_users(id), CONSTRAINT fk_ur_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurants(id), CONSTRAINT ck_ur_rating CHECK (rating BETWEEN 0.5 AND 5.0) ); -- 7. restaurant_vectors (semantic search) CREATE TABLE restaurant_vectors ( id VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL, restaurant_id VARCHAR2(36) NOT NULL, chunk_text CLOB NOT NULL, embedding VECTOR(1536, FLOAT32), created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, CONSTRAINT pk_restaurant_vectors PRIMARY KEY (id), CONSTRAINT fk_rv_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ); CREATE VECTOR INDEX idx_rv_embedding ON restaurant_vectors (embedding) ORGANIZATION NEIGHBOR PARTITIONS WITH DISTANCE COSINE; -- Useful indexes CREATE INDEX idx_videos_status ON videos(status); CREATE INDEX idx_videos_channel ON videos(channel_id); CREATE INDEX idx_vr_restaurant ON video_restaurants(restaurant_id); CREATE INDEX idx_ur_restaurant ON user_reviews(restaurant_id); CREATE INDEX idx_ur_user ON user_reviews(user_id);