# AI Agent Instructions This file is first-stop context for AI coding agents working in `Arkie-Library-Backend`. ## Repository identity - Project: Arkie Library Backend / ARK database API. - Go module: `github.com/arkie/ark-database`. - Stack: Go, chi router, PostgreSQL/pgx, JWT, bcrypt, optional AWS S3 uploads, Ethereum wallet signature verification. - Frontend repo expects backend API at `/api` and uploaded assets under `/uploads`. ## Branch and safety rules - Current branch observed during initialization: `terry-staging`. - Do not commit or push unless Terry explicitly asks. - Before branch-changing, pulling, rebasing, or destructive operations, run: ```bash git status --short --branch ``` - Do not commit secrets. `.env.example` is safe; real `.env` files should stay local/deployment-only. ## Required checks Before proposing deploy/push, run: ```bash gofmt -w . go test ./... ``` Optional extra check: ```bash go vet ./... ``` ## Architecture quick map - `cmd/server/main.go`: starts everything. Loads config, connects DB, ensures upload dir, optionally seeds admin, sets up S3, registers routes. - `internal/config/config.go`: all environment variables and defaults. - `internal/db/db.go`: creates and pings a `pgxpool.Pool`. - `internal/auth/`: JWT helpers. Admin tokens use issuer `ark-admin`; wallet user tokens use issuer `ark-user`. - `internal/handlers/public.go`: public category/resource/search/metric endpoints. - `internal/handlers/admin.go`: admin login, dashboard, resource CRUD, tags. - `internal/handlers/wallet_auth.go`: wallet nonce, signature verification, wallet profile. - `internal/handlers/upload.go`: admin multipart upload to local disk or S3. - `migrations/`: SQL schema files; there is no Go migration runner yet. ## Important implementation patterns - HTTP handlers are plain `net/http` functions using chi route params. - DB access comes from request context via `handlers.WithPool` and `poolFrom(r)`. - JSON responses use `writeJSON` in `internal/handlers/util.go`. - JSON request bodies use `jsonDecode`, limited to 1 MiB. - Resource IDs are UUIDs (`github.com/google/uuid`). - Tags are stored in `tags` + `resource_tags`; new tag slugs are deterministic hashes from `tagSlug`. - Public resource listing only returns `resources.status = 'published'` and `is_public = TRUE`. - Admin routes require `Authorization: Bearer ` from `/api/admin/login`. - Wallet routes produce normal user JWTs, not admin JWTs. ## Database/migration notes - `migrations/001_init.sql` is designed for a fresh database and is not fully idempotent. - `migrations/002_wallet_auth.sql` is idempotent. - `RUN_WALLET_AUTH_SCHEMA` defaults to true and lets startup create the wallet nonce table. In production with read-only/public DB users, apply migration separately and set it to false. ## Deployment/runtime notes - Dockerfile builds a static Go binary in a `golang:1.24-alpine` builder and runs it on Alpine. - `UPLOAD_DIR` defaults to `./uploads`; Docker sets it to `/app/uploads`. - When `S3_BUCKET` is set and AWS config loads, uploads go to S3. Otherwise uploads stay local. - `JWT_SECRET` default is insecure and must be changed outside development. ## Agent behavior preferences - Answer Terry concisely in Chinese unless code/docs require English. - Prefer small direct changes over broad rewrites. - Keep this README/AGENTS/docs updated when discovering non-obvious backend behavior. - Search project memory before making decisions about workflow, deployment, or conventions.