mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-04-17 19:22:09 +00:00
chore: add plan and phase reports for D1 + cron rollout
This commit is contained in:
84
plans/260415-1010-d1-cron-infra/phase-03-trading-history.md
Normal file
84
plans/260415-1010-d1-cron-infra/phase-03-trading-history.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Phase 03 — Trading Trade History
|
||||
|
||||
**Priority:** P1
|
||||
**Status:** Complete
|
||||
**Depends on:** Phase 01
|
||||
|
||||
## Overview
|
||||
|
||||
Persist every buy/sell in `trading_trades` table. Add `/history [n]` command to show last N trades for the caller (default 10, max 50).
|
||||
|
||||
## Requirements
|
||||
|
||||
**Functional**
|
||||
- Every successful buy/sell inserts a row: `(id, user_id, symbol, side, qty, price_vnd, ts)`.
|
||||
- `/history` → last 10 trades (newest first).
|
||||
- `/history 25` → last 25 (clamp 1..50).
|
||||
- Rendered as compact table (HTML-escaped).
|
||||
- **No inline cap enforcement** — cleanup cron (Phase 04) handles it.
|
||||
|
||||
**Non-functional**
|
||||
- Insert is fire-and-forget from the user's perspective but must complete before `ctx.reply` (use `await`).
|
||||
- Failure to persist does NOT fail the trade — log + swallow (portfolio KV is source of truth for positions).
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/modules/trading/
|
||||
├── index.js # export crons[] + commands[] (unchanged shape, new cron + new command)
|
||||
├── handlers.js # buy/sell call recordTrade() after portfolio update
|
||||
├── history.js # NEW — recordTrade(), listTrades(), /history handler, format
|
||||
├── migrations/
|
||||
│ └── 0001_trades.sql # NEW
|
||||
```
|
||||
|
||||
### Schema (`trading_trades`)
|
||||
|
||||
```sql
|
||||
CREATE TABLE trading_trades (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
symbol TEXT NOT NULL,
|
||||
side TEXT NOT NULL CHECK (side IN ('buy','sell')),
|
||||
qty INTEGER NOT NULL,
|
||||
price_vnd INTEGER NOT NULL,
|
||||
ts INTEGER NOT NULL -- unix ms
|
||||
);
|
||||
CREATE INDEX idx_trading_trades_user_ts ON trading_trades(user_id, ts DESC);
|
||||
CREATE INDEX idx_trading_trades_ts ON trading_trades(ts); -- for global FIFO trim
|
||||
```
|
||||
|
||||
## Related Code Files
|
||||
|
||||
**Create**
|
||||
- `src/modules/trading/history.js`
|
||||
- `src/modules/trading/migrations/0001_trades.sql`
|
||||
- `tests/modules/trading/history.test.js`
|
||||
|
||||
**Modify**
|
||||
- `src/modules/trading/index.js` — register `/history` command, accept `sql` in init
|
||||
- `src/modules/trading/handlers.js` — call `recordTrade()` on buy/sell
|
||||
|
||||
## Todo List
|
||||
|
||||
- [x] Migration SQL
|
||||
- [x] `recordTrade(sql, { userId, symbol, side, qty, priceVnd })`
|
||||
- [x] `listTrades(sql, userId, n)`
|
||||
- [x] `/history` command handler + HTML formatter
|
||||
- [x] Wire into buy/sell handlers
|
||||
- [x] Tests (Miniflare D1): record + list + max-cap clamp
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- Buy + sell produce rows in `trading_trades`.
|
||||
- `/history` returns last 10 newest-first.
|
||||
- `/history 50` returns 50. `/history 999` clamps to 50. `/history 0` falls back to default.
|
||||
- Persistence failure is logged but does not break the trade reply.
|
||||
|
||||
## Risks
|
||||
|
||||
- D1 write latency inside a user-facing handler — measured in tests; if >300ms, consider `ctx.waitUntil(insert)` non-blocking.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Phase 04 adds the retention cron consuming this table.
|
||||
Reference in New Issue
Block a user