88 lines
3.1 KiB
Markdown
88 lines
3.1 KiB
Markdown
# Agents
|
|
|
|
## Project Overview
|
|
|
|
`arcanesync` — cloud sync backend for the arcanegram telegram client fork. Authenticates every request via Telegram Mini App `initData` (HMAC-SHA256) and persists per-user sync state in postgres.
|
|
|
|
## Stack
|
|
|
|
- **Runtime**: Node 24+, tsx (no build step)
|
|
- **Package manager**: pnpm
|
|
- **HTTP**: Hono on `@hono/node-server`
|
|
- **DB**: PostgreSQL via `pg` + drizzle-orm; migrations via drizzle-kit
|
|
- **Linting**: @antfu/eslint-config v8 (eslint.config.mjs)
|
|
- **Env**: env-var + native `loadEnvFile`
|
|
- **Container**: Docker, node:24-alpine; docker-compose for postgres
|
|
|
|
## Structure
|
|
|
|
```
|
|
src/
|
|
├── index.ts # entrypoint — wires hono app, starts server
|
|
├── db/
|
|
│ ├── db.ts # pg pool + drizzle instance
|
|
│ ├── schema.ts # drizzle schema
|
|
│ ├── migrate.ts # migration runner (pnpm db:migrate)
|
|
│ └── migrations/ # generated sql
|
|
├── lib/
|
|
│ ├── initdata.ts # telegram initData hmac validator
|
|
│ └── initdata.test.ts
|
|
├── middleware/
|
|
│ └── auth.ts # `Authorization: tma <initData>` guard
|
|
├── routes/
|
|
│ ├── health.ts # GET /health
|
|
│ ├── miniapp.ts # GET /miniapp (botfather stub)
|
|
│ └── sync.ts # GET/PUT /sync
|
|
└── shared/
|
|
└── config.ts # env config
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
- `GET /health` — liveness
|
|
- `GET /miniapp` — mini app stub registered with botfather
|
|
- `GET /sync` — auth required. returns `{version, data}`
|
|
- `PUT /sync` — auth required. body `{baseVersion, patch}`. 200 on accept, 409 on version conflict (returns current `{version, data}`)
|
|
|
|
Auth header: `Authorization: tma <initData>`. Validation enforces hmac correctness and `auth_date` freshness.
|
|
|
|
## Conventions
|
|
|
|
- ESM only (`"type": "module"`)
|
|
- Path alias `@/*` → `src/*` — imports must end with `.js` (nodenext resolution)
|
|
- No build step — tsx runs TS directly in dev and prod
|
|
- `cross-env` for cross-platform env vars in npm scripts
|
|
- No useless comments
|
|
- Split code into multiple files rather than monoliths
|
|
- Lowercase strings (errors, keys, log messages) where reasonable
|
|
|
|
## Commands
|
|
|
|
- `pnpm dev` — watch mode
|
|
- `pnpm start` — production run
|
|
- `pnpm lint` / `pnpm lint:fix`
|
|
- `pnpm test` — node:test runner via tsx
|
|
- `pnpm db:generate` — drizzle-kit generate
|
|
- `pnpm db:migrate` — apply migrations
|
|
- `pnpm db:studio` — drizzle studio
|
|
|
|
## Env
|
|
|
|
| var | default | meaning |
|
|
|---|---|---|
|
|
| `PORT` | `3000` | http port |
|
|
| `DATABASE_URL` | required | postgres dsn |
|
|
| `BOT_TOKEN` | required | telegram bot token (mini-app-enabled) |
|
|
| `AUTH_DATE_MAX_AGE_SECONDS` | `86400` | initData freshness window |
|
|
| `MAX_PAYLOAD_BYTES` | `65536` | per-PUT payload cap |
|
|
|
|
## Lint Rules
|
|
|
|
- `no-console: off`
|
|
- `antfu/no-top-level-await: off`
|
|
- Stylistic: 2-space indent, single quotes
|
|
- JSON key ordering enforced (auto-fixed)
|
|
|
|
## Docker
|
|
|
|
Single-stage `node:24-alpine`, no build. Copies source, installs prod deps, runs `pnpm db:migrate` then `pnpm start`. `docker-compose.yml` provides postgres for local dev.
|