feat: personalize and stream mentor chat

This commit is contained in:
leefer
2026-07-23 19:24:57 +08:00
parent 771882ebf0
commit 95789c837c
11 changed files with 876 additions and 104 deletions
+55
View File
@@ -257,6 +257,19 @@ class ReviewDatabase:
CREATE INDEX IF NOT EXISTS idx_mentor_messages_conversation
ON mentor_messages(user_id, mentor_id, trade_date, id DESC);
CREATE TABLE IF NOT EXISTS mentor_preferences (
user_id INTEGER NOT NULL,
mentor_id TEXT NOT NULL,
pinned INTEGER NOT NULL DEFAULT 0,
sort_order INTEGER NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL,
PRIMARY KEY (user_id, mentor_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_mentor_preferences_user_order
ON mentor_preferences(user_id, pinned DESC, sort_order, mentor_id);
CREATE TABLE IF NOT EXISTS strategy_tracks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
@@ -1417,6 +1430,48 @@ class ReviewDatabase:
)
return int(cursor.rowcount)
def list_mentor_preferences(self, user_id: int) -> list[dict[str, Any]]:
with self.connect() as connection:
rows = connection.execute(
"""
SELECT mentor_id, pinned, sort_order
FROM mentor_preferences
WHERE user_id = ?
ORDER BY sort_order, mentor_id
""",
(int(user_id),),
).fetchall()
return [
{
"mentor_id": str(row["mentor_id"]),
"pinned": bool(row["pinned"]),
"sort_order": int(row["sort_order"]),
}
for row in rows
]
def save_mentor_preferences(
self, user_id: int, ordered_ids: list[str], pinned_ids: set[str]
) -> None:
now = datetime.now().astimezone().isoformat(timespec="seconds")
values = [
(int(user_id), mentor_id, int(mentor_id in pinned_ids), index, now)
for index, mentor_id in enumerate(ordered_ids)
]
with self.connect() as connection:
connection.execute(
"DELETE FROM mentor_preferences WHERE user_id = ?",
(int(user_id),),
)
connection.executemany(
"""
INSERT INTO mentor_preferences
(user_id, mentor_id, pinned, sort_order, updated_at)
VALUES (?, ?, ?, ?, ?)
""",
values,
)
def save_strategy_tracks(
self,
user_id: int,