Files

110 lines
3.8 KiB
Markdown

# AGENTS.md
Repo-specific notes for AI agents.
## Stack
- Bun-only (`mise.toml` pins `bun = 1.3.13`). Do not use `npm` / `npx` / `node` / `yarn` / `pnpm`.
- TanStack Start + React 19 SSR + Vite + Nitro `bun` preset.
- ORPC contract-first API, TanStack Query v5, Tailwind v4.
- Business data source is the customer's existing **MySQL** database. This app is read-only display software.
- There is no PostgreSQL, Drizzle schema, embedded migration flow, or local DB mutation path in this project now.
- `scripts/seed.ts` is the only local development helper allowed to create/truncate/insert sample data. The app runtime must stay read-only.
## Scripts
```bash
bun run dev
bun run build
bun run compile
bun run seed
bun run typecheck
bun run test
bun run fix
```
Before shipping: `bun run fix && bun run typecheck && bun run test && bun run build`.
## MySQL Source
Environment variable:
```bash
DATABASE_URL=mysql://user:password@host:3306/database
```
Required AI prediction service:
```bash
SOH_PREDICTION_API_BASE_URL=http://127.0.0.1:8000
SOH_PREDICTION_CACHE_TTL_SECONDS=86400
SOH_PREDICTION_TIMEOUT_MS=10000
```
Customer table: `ls_battery_info`.
| Column | Type | Meaning |
| --- | --- | --- |
| `id` | `int(11)` auto increment | primary key |
| `user_id` | `int(11)` | user ID |
| `mac` | `varchar(50)` | device MAC |
| `dev_model` | `varchar(20)` | device model |
| `dev_name` | `varchar(50)` | device name |
| `is_low_power` | `varchar(10)` | `true` / `false` |
| `power_status` | `tinyint(4)` | `0` not charging, `1` charging, `2` full |
| `power` | `tinyint(4)` | current battery `0~100` |
| `create_time` | `datetime` | created time |
| `remark` | `varchar(500)` | nullable remark |
Rules:
- Only run `SELECT` queries against this table. Do not insert, update, delete, migrate, or create tables.
- Do not add mock/fallback rows. If MySQL is unavailable, surface the error.
- `is_low_power` is stored as a string and normalized to boolean in `src/domain/battery.ts`.
- `power_status` is normalized to `0 | 1 | 2`.
- `battery.batteries` returns paginated latest records per `mac`; supported filters are `pageSize`, `cursor`, `search`, `lowPower`, `powerStatus`, and `sort`.
- `battery.history` takes `mac` and returns history ordered by `create_time DESC, id DESC`, limited to 500 rows.
- Dashboard requires the external prediction API via `SOH_PREDICTION_API_BASE_URL`; missing configuration must fail environment validation. Per-device prediction failures may surface as unavailable values, but must not be rendered as `0%`.
## Layout
```
src/
├── routes/
│ ├── index.tsx # SoH dashboard
│ ├── batteries.tsx # battery monitor page
│ └── api/ # ORPC handlers
├── server/
│ ├── api/ # contracts / routers / interceptors
│ ├── battery/mysql.ts
│ └── prediction/client.ts
├── domain/battery.ts
├── client/orpc.ts
└── styles.css
```
## ORPC
- Contracts live in `src/server/api/contracts/`.
- Routers live in `src/server/api/routers/`.
- Use `os` from `@/server/api/server`.
- Current business API:
- `battery.dashboard`
- `battery.batteries`
- `battery.history`
## CLI And Deploy
- `src/bin.ts` must keep static imports minimal. Nitro's bun preset starts the server as a side effect when `.output/server/index.mjs` is imported.
- `serve` is lazy-loaded via citty.
- `bun run compile` produces `out/server-<target>`.
- Runtime artifact is a single binary plus `DATABASE_URL` configuration.
## Code Style
- 2-space indentation, LF, single quotes, semicolons as-needed, 120-column line width.
- Route components use `function Foo()` declarations below route config.
- No `console.*` in business code; use `getLogger([...])` from `@/server/logger` if logging is needed.
- No `as any`, `@ts-ignore`, or `@ts-expect-error`.
- Do not edit `src/routeTree.gen.ts` manually.