rebuild(stage-12): deliver private review workflows
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlite3
|
||||
|
||||
from backend.database.migrations.runner import Migration
|
||||
|
||||
|
||||
def upgrade(connection: sqlite3.Connection) -> None:
|
||||
connection.execute("ALTER TABLE watchlist_entries ADD COLUMN remark TEXT NOT NULL DEFAULT ''")
|
||||
statements = (
|
||||
"""
|
||||
CREATE TABLE review_notes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
code TEXT NOT NULL DEFAULT '',
|
||||
stock_name TEXT NOT NULL DEFAULT '',
|
||||
trade_date TEXT NOT NULL,
|
||||
summary TEXT NOT NULL DEFAULT '',
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
plan TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(user_id, code, trade_date)
|
||||
)
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE trade_entries (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
trade_date TEXT NOT NULL,
|
||||
code TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
action TEXT NOT NULL CHECK (action IN ('buy','sell','add','trim','watch')),
|
||||
price REAL NOT NULL CHECK (price >= 0),
|
||||
quantity INTEGER NOT NULL DEFAULT 0 CHECK (quantity >= 0),
|
||||
position_pct REAL CHECK (position_pct BETWEEN 0 AND 100),
|
||||
pnl_amount REAL,
|
||||
pnl_pct REAL,
|
||||
emotion TEXT NOT NULL CHECK (
|
||||
emotion IN ('calm','confident','hesitant','anxious','impulsive')
|
||||
),
|
||||
tags_json TEXT NOT NULL DEFAULT '[]',
|
||||
thesis TEXT NOT NULL DEFAULT '',
|
||||
execution TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
)
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX trade_entries_user_date_idx
|
||||
ON trade_entries(user_id, trade_date DESC, id DESC)
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE alerts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
kind TEXT NOT NULL CHECK (kind IN ('manual','strategy_t1','strategy_t5')),
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
available_date TEXT NOT NULL,
|
||||
code TEXT NOT NULL DEFAULT '',
|
||||
dedupe_key TEXT NOT NULL,
|
||||
is_read INTEGER NOT NULL DEFAULT 0 CHECK (is_read IN (0,1)),
|
||||
read_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(user_id, dedupe_key)
|
||||
)
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX alerts_user_due_idx
|
||||
ON alerts(user_id, available_date, is_read, id DESC)
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE review_assistant_messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role TEXT NOT NULL CHECK (role IN ('user','assistant')),
|
||||
content TEXT NOT NULL,
|
||||
context_date TEXT NOT NULL,
|
||||
request_id TEXT REFERENCES llm_requests(id) ON DELETE SET NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('complete','stopped','error')),
|
||||
created_at TEXT NOT NULL
|
||||
)
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX review_assistant_user_idx
|
||||
ON review_assistant_messages(user_id, id DESC)
|
||||
""",
|
||||
)
|
||||
for statement in statements:
|
||||
connection.execute(statement)
|
||||
|
||||
|
||||
def downgrade(connection: sqlite3.Connection) -> None:
|
||||
for table in (
|
||||
"review_assistant_messages",
|
||||
"alerts",
|
||||
"trade_entries",
|
||||
"review_notes",
|
||||
):
|
||||
connection.execute(f"DROP TABLE {table}")
|
||||
connection.execute("ALTER TABLE watchlist_entries DROP COLUMN remark")
|
||||
|
||||
|
||||
MIGRATION = Migration(
|
||||
version=10,
|
||||
name="create_private_review_domain",
|
||||
signature="review:v1:notes-trades-alerts-assistant",
|
||||
upgrade=upgrade,
|
||||
downgrade=downgrade,
|
||||
)
|
||||
Reference in New Issue
Block a user