Metadata-Version: 2.4
Name: rawr-dashboard
Version: 0.1.0
Summary: RAWR Dashboard — bento module board for journal, P&L, and indicators.
Project-URL: Homepage, https://github.com/snowjang24/rawr-tools
Project-URL: Repository, https://github.com/snowjang24/rawr-tools
Project-URL: Documentation, https://github.com/snowjang24/rawr-tools/tree/main/packages/rawr-dashboard#readme
Project-URL: Issues, https://github.com/snowjang24/rawr-tools/issues
Requires-Python: >=3.12
Requires-Dist: click>=8.0
Requires-Dist: fastapi>=0.110
Requires-Dist: pydantic>=2.0
Requires-Dist: rawr-tools
Requires-Dist: uvicorn[standard]>=0.29
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# rawr-dashboard

A RAWR plugin that adds a local bento-board web UI for trade journalling, portfolio reviews, P&L tracking, and indicator tiles — plus MCP tools so an AI agent can write to the journal directly.

## Install

```bash
pip install rawr-dashboard
```

The package bundles the pre-built SPA (no Node.js needed at runtime).

## Usage

### Serve the dashboard

```bash
rawr dashboard serve            # opens http://127.0.0.1:8800/ in your browser
rawr dashboard serve --port 9000 --no-open
```

### Import KIS executions

```bash
rawr dashboard sync             # idempotent — safe to run repeatedly
```

## 한국 시장 관찰 모니터

`rawr dashboard monitor`는 한국 주식/ETF 시장을 로컬에서 관찰하고 후보와 주문 프리뷰를 저장하는 preview-only 기능입니다. 이 기능은 실주문을 제출하지 않습니다.

```bash
rawr dashboard monitor doctor
rawr dashboard monitor run-once
rawr dashboard monitor start --interval-minutes 10
rawr dashboard monitor status
rawr dashboard monitor stop
```

- 기본 주기는 10분입니다.
- 허용 주기는 5-15분입니다.
- 후보별 주문 프리뷰는 `preview_only=true`, `live_order_submitted=false`를 포함합니다.
- 웹 대시보드는 `rawr dashboard serve`로 실행합니다.
- 실거래 검토는 기존 RAWR order preview와 policy gate를 별도로 거쳐야 합니다.

## Dev flow

The SPA source lives under `apps/dashboard/` (Vite + React). To rebuild it:

```bash
pnpm --dir apps/dashboard build   # writes to src/rawr_dashboard/web/static/
```

To rebuild the Python wheel with the fresh SPA:

```bash
python -m build --wheel packages/rawr-dashboard
```

> **Always build the SPA first.** The wheel force-includes whatever is in
> `web/static/`; if you skip the `pnpm build` step the wheel ships without a UI
> and `rawr dashboard serve` returns 404 at `/`.

## Data model

| Layer | File | Purpose |
|-------|------|---------|
| Models | `models.py` | `JournalEntry`, `Annotation`, `CalendarItem` (Pydantic) |
| Core | `core/journal.py` | `JournalService` — create/close entry, upsert annotation |
| Core | `core/reviews.py` | `ReviewService` — store portfolio reviews in RAWR memory events |
| Core | `core/sync.py` | `KisSyncService` — import KIS executions (idempotent) |
| Core | `core/board.py` | `BoardService` — module/board layout CRUD |
| Web | `web/app.py` | FastAPI app factory |
| Web | `web/deps.py` | `get_db()` — shared `RawrDB` instance |
| CLI | `cli.py` | `dashboard` Click group; `get_cli_plugin()`, `get_mcp_plugin()` |

## Built-in review workflow

The default board includes:

- `portfolio_reviews` — writes recurring portfolio reviews to RAWR `memory_events`.
- `trade_entry` — records manual buy/sell journal entries to the shared `journal` table.

API endpoints:

```bash
GET  /api/reviews
POST /api/reviews
GET  /api/journal
POST /api/journal
```

## MCP tools (agent write access)

When RAWR's MCP server is running, an AI agent can call these tools:

### `dashboard_record_trade`

Record a new open trade in the journal.

| Parameter | Type | Description |
|-----------|------|-------------|
| `code` | `str` | Ticker symbol |
| `name` | `str` | Company / asset name |
| `side` | `str` | `"buy"` or `"sell"` |
| `qty` | `int` | Quantity |
| `entry_price` | `float` | Entry price |
| `reason` | `str` | Trade rationale (optional) |
| `strategy` | `str` | Strategy tag (optional) |
| `currency` | `str` | Default `"KRW"` |

Returns `{"journal_id": int, "status": "open"}`.

### `dashboard_close_trade`

Close an open journal entry with its realized outcome.

| Parameter | Type | Description |
|-----------|------|-------------|
| `journal_id` | `int` | ID returned by `dashboard_record_trade` |
| `exit_price` | `float` | Exit price |
| `outcome_pnl` | `float` | Realized P&L |
| `outcome_pct` | `float` | Return % |

Returns `{"journal_id": int, "updated": bool, "status": "closed" | "not_found"}` — `updated` is `false` (status `"not_found"`) when no entry matched the id.

### `dashboard_annotate_trade`

Attach a reflection note to a trade entry.

| Parameter | Type | Description |
|-----------|------|-------------|
| `journal_id` | `int` | Target entry |
| `tags` | `list[str]` | Freeform tags (optional) |
| `confidence` | `int` | Conviction level 1–5 (optional) |
| `emotion` | `str` | Emotional state note (optional) |
| `discipline_checklist` | `dict` | Key→bool checklist (optional) |
| `mistakes` | `str` | Post-trade mistake notes (optional) |

Returns `{"journal_id": int, "annotated": true}`.

### `dashboard_sync_kis`

Pull KIS executions into the journal (idempotent).

Returns `{"created": int, "skipped": int}`.
