arcanesync-server/AGENTS.md

3.1 KiB

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.