Initial commit: Tasteby - YouTube restaurant map service
Backend (FastAPI + Oracle ADB), Frontend (Next.js), daemon worker. Features: channel/video/restaurant management, semantic search, Google OAuth, user reviews. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
127
backend/sql/schema.sql
Normal file
127
backend/sql/schema.sql
Normal file
@@ -0,0 +1,127 @@
|
||||
-- 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);
|
||||
Reference in New Issue
Block a user