feat(core): implement secure MVP core with dictionary search, auth, and CRUD
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import sqlite3
|
||||
import contextlib
|
||||
from typing import Generator
|
||||
from app import config
|
||||
|
||||
def get_db_connection() -> sqlite3.Connection:
|
||||
conn = sqlite3.connect(
|
||||
config.DB_PATH,
|
||||
timeout=15.0
|
||||
)
|
||||
conn.row_factory = sqlite3.Row
|
||||
conn.execute("PRAGMA journal_mode=WAL;")
|
||||
conn.execute("PRAGMA synchronous=NORMAL;")
|
||||
conn.execute("PRAGMA foreign_keys=ON;")
|
||||
return conn
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_db() -> Generator[sqlite3.Connection, None, None]:
|
||||
conn = get_db_connection()
|
||||
try:
|
||||
yield conn
|
||||
conn.commit()
|
||||
except Exception:
|
||||
conn.rollback()
|
||||
raise
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def init_db():
|
||||
config.DB_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
with get_db() as conn:
|
||||
conn.executescript("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE NOT NULL COLLATE NOCASE,
|
||||
password_hash TEXT NOT NULL,
|
||||
salt TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
token TEXT PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
user_agent TEXT,
|
||||
ip TEXT,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vocabulary_cards (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
term TEXT NOT NULL,
|
||||
translation TEXT NOT NULL,
|
||||
context_sentence TEXT,
|
||||
phonetic TEXT,
|
||||
audio_url TEXT,
|
||||
part_of_speech TEXT,
|
||||
definition_en TEXT,
|
||||
tags TEXT,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_vocab_user ON vocabulary_cards(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_vocab_term ON vocabulary_cards(term);
|
||||
CREATE INDEX IF NOT EXISTS idx_vocab_created ON vocabulary_cards(created_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dictionary_cache (
|
||||
query TEXT PRIMARY KEY COLLATE NOCASE,
|
||||
response_json TEXT NOT NULL,
|
||||
cached_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
""")
|
||||
Reference in New Issue
Block a user