Add backend/frontend scaffolding with Oracle ADB wallet config
- Backend: Spring Boot 3 + WebFlux, JWT auth, Oracle ADB wallet, 8 controllers/services/repositories (Auth~Tag), DTOs, exception handling - Frontend: Next.js 15, TypeScript, Tailwind CSS, AuthContext, 7 pages (dashboard, knowledge, chat, study, todos, habits, login) - DB: V1 migration with 12 tables including VECTOR(1024) + HNSW index - Ops: PM2 ecosystem config, deploy.sh, start-backend.sh - CLAUDE.md: DB credentials replaced with env var references Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
156
db/migration/V1__create_tables.sql
Normal file
156
db/migration/V1__create_tables.sql
Normal file
@@ -0,0 +1,156 @@
|
||||
-- ============================================
|
||||
-- SUNDOL Database Schema - Oracle 23ai
|
||||
-- ============================================
|
||||
|
||||
-- USERS
|
||||
CREATE TABLE users (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
email VARCHAR2(320) NOT NULL UNIQUE,
|
||||
display_name VARCHAR2(255),
|
||||
avatar_url VARCHAR2(1000),
|
||||
google_sub VARCHAR2(255) UNIQUE,
|
||||
refresh_token VARCHAR2(1000),
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- KNOWLEDGE_ITEMS
|
||||
CREATE TABLE knowledge_items (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL REFERENCES users(id),
|
||||
type VARCHAR2(20) NOT NULL,
|
||||
title VARCHAR2(500),
|
||||
source_url VARCHAR2(2000),
|
||||
raw_text CLOB,
|
||||
status VARCHAR2(20) DEFAULT 'PENDING' NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_ki_user_id ON knowledge_items(user_id);
|
||||
CREATE INDEX idx_ki_status ON knowledge_items(status);
|
||||
|
||||
-- KNOWLEDGE_CHUNKS
|
||||
CREATE TABLE knowledge_chunks (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
knowledge_item_id RAW(16) NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
|
||||
chunk_index NUMBER(10) NOT NULL,
|
||||
content CLOB NOT NULL,
|
||||
embedding VECTOR(1024, FLOAT32),
|
||||
token_count NUMBER(10),
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_kc_item_id ON knowledge_chunks(knowledge_item_id);
|
||||
|
||||
-- VECTOR index for semantic search
|
||||
CREATE VECTOR INDEX idx_kc_embedding ON knowledge_chunks(embedding)
|
||||
ORGANIZATION NEIGHBOR PARTITIONS
|
||||
DISTANCE COSINE
|
||||
WITH TARGET ACCURACY 95;
|
||||
|
||||
-- TAGS
|
||||
CREATE TABLE tags (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL REFERENCES users(id),
|
||||
name VARCHAR2(100) NOT NULL,
|
||||
color VARCHAR2(7) DEFAULT '#3b82f6',
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_tags_user_name ON tags(user_id, name);
|
||||
|
||||
-- KNOWLEDGE_ITEM_TAGS (many-to-many)
|
||||
CREATE TABLE knowledge_item_tags (
|
||||
knowledge_item_id RAW(16) NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
|
||||
tag_id RAW(16) NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (knowledge_item_id, tag_id)
|
||||
);
|
||||
|
||||
-- CHAT_SESSIONS
|
||||
CREATE TABLE chat_sessions (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL REFERENCES users(id),
|
||||
title VARCHAR2(500) DEFAULT 'New Chat',
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cs_user_id ON chat_sessions(user_id);
|
||||
|
||||
-- CHAT_MESSAGES
|
||||
CREATE TABLE chat_messages (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
session_id RAW(16) NOT NULL REFERENCES chat_sessions(id) ON DELETE CASCADE,
|
||||
role VARCHAR2(20) NOT NULL,
|
||||
content CLOB NOT NULL,
|
||||
source_chunks CLOB,
|
||||
tokens_used NUMBER(10),
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cm_session_id ON chat_messages(session_id);
|
||||
|
||||
-- TODOS
|
||||
CREATE TABLE todos (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL REFERENCES users(id),
|
||||
parent_id RAW(16) REFERENCES todos(id) ON DELETE CASCADE,
|
||||
title VARCHAR2(500) NOT NULL,
|
||||
description CLOB,
|
||||
status VARCHAR2(20) DEFAULT 'PENDING' NOT NULL,
|
||||
priority VARCHAR2(10) DEFAULT 'MEDIUM' NOT NULL,
|
||||
due_date DATE,
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_todos_user_id ON todos(user_id);
|
||||
CREATE INDEX idx_todos_parent_id ON todos(parent_id);
|
||||
|
||||
-- HABITS
|
||||
CREATE TABLE habits (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL REFERENCES users(id),
|
||||
name VARCHAR2(200) NOT NULL,
|
||||
description VARCHAR2(1000),
|
||||
habit_type VARCHAR2(10) DEFAULT 'BUILD' NOT NULL,
|
||||
target_days VARCHAR2(50) DEFAULT 'DAILY',
|
||||
color VARCHAR2(7) DEFAULT '#22c55e',
|
||||
streak_current NUMBER(10) DEFAULT 0,
|
||||
streak_best NUMBER(10) DEFAULT 0,
|
||||
is_active NUMBER(1) DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_habits_user_id ON habits(user_id);
|
||||
|
||||
-- HABIT_LOGS
|
||||
CREATE TABLE habit_logs (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
habit_id RAW(16) NOT NULL REFERENCES habits(id) ON DELETE CASCADE,
|
||||
log_date DATE NOT NULL,
|
||||
checked_in NUMBER(1) DEFAULT 1,
|
||||
note VARCHAR2(500),
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_hl_habit_date ON habit_logs(habit_id, log_date);
|
||||
|
||||
-- STUDY_CARDS
|
||||
CREATE TABLE study_cards (
|
||||
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
||||
user_id RAW(16) NOT NULL REFERENCES users(id),
|
||||
knowledge_item_id RAW(16) REFERENCES knowledge_items(id) ON DELETE SET NULL,
|
||||
front CLOB NOT NULL,
|
||||
back CLOB NOT NULL,
|
||||
ease_factor NUMBER(4,2) DEFAULT 2.50,
|
||||
interval_days NUMBER(10) DEFAULT 0,
|
||||
repetitions NUMBER(10) DEFAULT 0,
|
||||
next_review_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sc_user_review ON study_cards(user_id, next_review_at);
|
||||
Reference in New Issue
Block a user