Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# PROJECT KNOWLEDGE BASE

**Generated:** 2026-03-29 21:13:36 CST
**Commit:** 941a44da
**Branch:** feat/agents-md

## OVERVIEW
Sub2API is an AI API gateway platform: Go backend for routing, billing, auth, and persistence; Vue frontend for admin/user UI; Docker/systemd deploy assets for self-hosting.
Core stack: Go 1.26.1 + Gin + Ent + Wire + PostgreSQL/Redis, plus Vue 3 + Vite + Pinia + Vitest + TailwindCSS.

## STRUCTURE
```text
curious-cactus/
├── backend/ # Go runtime, persistence, generated Ent, SQL migrations
├── frontend/ # Vue app; build output embeds into backend/internal/web/dist
├── deploy/ # Docker/systemd install assets and config templates
├── .github/ # CI, security scan, release workflow
├── docs/ # Product/developer docs
└── tools/ # Repo utilities such as secret/audit helpers
```

## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Server bootstrap | `backend/cmd/server/main.go` | Setup mode, auto-setup, graceful shutdown |
| HTTP routing | `backend/internal/server/router.go` | Registers auth, user, admin, gateway routes |
| Business logic | `backend/internal/service/` | Covered by `backend/AGENTS.md` |
| Persistence | `backend/internal/repository/` | Ent + raw SQL + Redis caches |
| Schema edits | `backend/ent/schema/` | Covered by `backend/ent/schema/AGENTS.md` |
| Migration edits | `backend/migrations/` | Covered by `backend/migrations/AGENTS.md` |
| Frontend bootstrap | `frontend/src/main.ts` | Injected config before mount; router/i18n setup |
| Frontend routing | `frontend/src/router/index.ts` | Lazy routes, auth/admin/backend-mode guards |
| Admin API/UI | `frontend/src/api/admin/`, `frontend/src/views/admin/` | Covered by `frontend/AGENTS.md` |
| Deployment / self-hosting | `deploy/` | See `deploy/AGENTS.md` for compose variants, install scripts, and socket/path gotchas |
| Repo tooling | `tools/` | Small helper scripts such as audit/exception checks |
| Product/API docs | `docs/` | Start here for integration-facing docs before editing code |

## CODE MAP
| Symbol | Type | Location | Role |
|--------|------|----------|------|
| `main` | function | `backend/cmd/server/main.go` | Entry point for setup mode and normal server mode |
| `runMainServer` | function | `backend/cmd/server/main.go` | Loads config, initializes app, starts server |
| `SetupRouter` | function | `backend/internal/server/router.go` | Applies middleware and mounts route groups |
| `ProviderSet` | variable | `backend/internal/service/wire.go` | Service-layer dependency graph root |
| `bootstrap` | function | `frontend/src/main.ts` | Frontend startup sequence |
| `router` | constant | `frontend/src/router/index.ts` | Route table + navigation guards + prefetch |

## CONVENTIONS
- Use `pnpm`, not `npm`; CI installs frontend deps with `pnpm install --frozen-lockfile`.
- Frontend build output goes to `backend/internal/web/dist`; the backend can embed and serve it.
- Backend architecture is layered: `handler` and `service` must not import `repository` directly; lint enforces this.
- Ent output is generated; hand-written ORM work belongs in `backend/ent/schema/` and related mixins.
- SQL migrations auto-run on startup and are checksum-validated for immutability.
- Go version is pinned in CI and local tooling to `1.26.1`.

## ANTI-PATTERNS (THIS PROJECT)
- Editing generated Ent files under `backend/ent/`.
- Modifying an already-applied migration instead of creating a new migration.
- Switching frontend package management to `npm` or changing `package.json` without updating `pnpm-lock.yaml`.
- Using API keys in query parameters; use the `Authorization` header.
- Relying on Sora-related features in production.

## UNIQUE STYLES
- Frontend tests live in sibling `__tests__/` directories; backend tests are colocated as `*_test.go` with build tags such as `unit` and `integration`.
- Route metadata uses `titleKey`/`descriptionKey` for translated titles and page descriptions.
- Some frontend folders already carry rich README-style docs (`views/auth`, `router`, `stores`, `components/common`, `components/layout`); do not duplicate them blindly.
- Docker deployment favors `docker-compose.local.yml` because data stays in local directories and can be migrated by archiving the deploy folder.

## COMMANDS
```bash
make build
make test

cd backend && make generate
cd backend && make test-unit
cd backend && make test-integration

cd frontend && pnpm install
cd frontend && pnpm run build
cd frontend && pnpm run lint:check
cd frontend && pnpm run typecheck
cd frontend && pnpm run test:run
```

## NOTES
- First-run setup can happen through the setup wizard or Docker auto-setup; do not assume a ready config exists.
- For self-hosted stability, keep `JWT_SECRET` and `TOTP_ENCRYPTION_KEY` fixed instead of letting them change every restart.
- When fronting Sub2API with Nginx for Codex CLI traffic, enable `underscores_in_headers on;`.
- Child instruction files exist at `backend/`, `backend/migrations/`, `backend/ent/schema/`, `frontend/`, and `deploy/`; prefer the nearest one.
75 changes: 75 additions & 0 deletions backend/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# BACKEND KNOWLEDGE BASE

## OVERVIEW
`backend/` is the Go application: server bootstrap, config loading, DI, handlers, services, repositories, shared protocol/client helpers, generated Ent ORM, and SQL migrations.
This is the authoritative layer for runtime rules, persistence architecture, and codegen boundaries.

## STRUCTURE
```text
backend/
├── cmd/jwtgen/ # JWT secret helper binary
├── cmd/server/ # Main binary, setup mode, Wire bootstrap
├── internal/
│ ├── config/ # Config loading and validation
│ ├── domain/ # Shared domain constants and models
│ ├── handler/ # HTTP handlers
│ ├── integration/ # End-to-end backend test flows
│ ├── middleware/ # Shared middleware such as rate limiting
│ ├── model/ # Shared model structs
│ ├── pkg/ # Shared protocol/client/helper packages
│ ├── repository/ # Ent/raw SQL/Redis persistence
│ ├── service/ # Account, auth, gateway, billing, ops, subscriptions
│ ├── server/ # Router and HTTP server wiring
│ ├── setup/ # Setup wizard and auto-setup
│ ├── testutil/ # Backend test fixtures and helpers
│ ├── util/ # Focused utility packages
│ └── web/ # Embedded frontend serving
├── ent/ # Mostly generated code; handwritten work lives in schema/
└── migrations/ # SQL migrations, checksum-protected
```

## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Bootstrap / flags | `cmd/server/main.go` | `--setup`, `--version`, auto-setup, shutdown |
| DI graph | `cmd/server/wire.go`, `internal/*/wire.go` | Wire provider sets |
| Routing / middleware | `internal/server/`, `internal/server/routes/`, `internal/middleware/` | Router setup, route registration, shared middleware |
| Service layer | `internal/service/` | Flat package spanning auth, account, admin, gateway, billing, ops, subscriptions, Sora |
| Persistence | `internal/repository/` | Ent client, Redis caches, raw SQL helpers |
| Config | `internal/config/config.go` | Large config surface; exact behavior lives here |
| Shared helpers / clients | `internal/pkg/`, `internal/util/`, `internal/domain/` | Protocol adapters, logging, validation, shared constants |
| Backend e2e tests | `internal/integration/`, `internal/testutil/` | Integration harnesses, fixtures, HTTP helpers |
| Generated ORM | `ent/` | Do not edit generated output |
| Schema work | `ent/schema/` | See `ent/schema/AGENTS.md` |
| Migration work | `migrations/` | See `migrations/AGENTS.md` |

## CONVENTIONS
- Go version is pinned to `1.26.1`; CI verifies it exactly.
- Keep layer boundaries intact: `handler` and `service` must not import `repository` directly.
- Ent is the ORM, Wire is the DI tool; schema/codegen changes are normal here.
- Frontend embedding is part of backend runtime: frontend build artifacts land in `internal/web/dist`.
- Test scopes use build tags such as `unit`, `integration`, and `e2e`.

## ANTI-PATTERNS
- Editing generated Ent files under `ent/` instead of editing `ent/schema/`.
- Bypassing backend layering by importing persistence directly into `service` or `handler`.
- Changing Ent schema without regenerating code.
- Changing migration history in place.
- Treating setup/auto-setup as optional plumbing; startup behavior depends on it.

## COMMANDS
```bash
cd backend && make build
cd backend && make generate
cd backend && make test
cd backend && make test-unit
cd backend && make test-integration
cd backend && go run ./cmd/server
```

## NOTES
- `internal/service/wire.go` is a high-signal navigation file even when you are not editing DI; it reveals the major backend subsystems.
- `internal/service/` is intentionally broad and flat; use filename prefixes plus `wire.go` to navigate instead of expecting child docs under that subtree.
- `internal/repository/migrations_runner.go` is the source of truth for how SQL files execute at runtime.
- Parent-level backend guidance should cover most subtrees; only migrations and handwritten Ent schema have separate child docs because their local failure modes are special.
- If a change touches auth, gateway routing, or admin behavior, expect to cross `handler`, `service`, and `repository` boundaries even if only one package is edited.
46 changes: 46 additions & 0 deletions backend/ent/schema/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# ENT SCHEMA KNOWLEDGE BASE

## OVERVIEW
`backend/ent/schema/` is the handwritten Ent enclave: entity definitions, mixins, edges, indexes, and annotations.
Edit schema here; generated files elsewhere under `backend/ent/` are outputs, not authoring surfaces.

## STRUCTURE
```text
backend/ent/schema/
├── *.go # Entity schemas
└── mixins/
├── soft_delete.go
└── time.go
```

## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Add/change entity fields | `*.go` in this directory | Entity-specific fields, edges, indexes, annotations |
| Shared timestamps | `mixins/time.go` | Common created/updated fields |
| Soft delete behavior | `mixins/soft_delete.go` | Custom interceptor/hook-based implementation |
| Code generation entry | `../generate.go` | `go:generate` feature list |
| Matching SQL migration | `../../migrations/` | Schema change should usually ship with migration |

## CONVENTIONS
- Author schema changes here, not in generated Ent output.
- Reuse the local mixins where appropriate; this repo has a custom `SoftDeleteMixin` and a shared `TimeMixin`.
- Use annotations/indexes deliberately; table naming and SQL behavior are part of the handwritten schema contract.
- Treat schema edits and migration edits as one workflow, not separate chores.

## ANTI-PATTERNS
- Editing `backend/ent/*.go` generated files instead of changing schema and regenerating.
- Introducing a schema change without the corresponding SQL migration when runtime data shape changes.
- Replacing the repo’s custom soft-delete pattern with Ent’s default soft-delete approach.
- Forgetting regeneration after schema edits.

## COMMANDS
```bash
cd backend && go generate ./ent
cd backend && go generate ./cmd/server
```

## NOTES
- The parent `backend/` file owns the broad “generated Ent code is off-limits” rule; this child focuses on the handwritten authoring surface.
- `SoftDeleteMixin` is a repo-specific behavior boundary; read it before changing delete semantics.
- If a schema edit changes query semantics or constraints, check `internal/repository/` callers and add/update a migration.
45 changes: 45 additions & 0 deletions backend/migrations/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# MIGRATIONS KNOWLEDGE BASE

## OVERVIEW
`backend/migrations/` contains forward-only SQL migrations executed by the backend’s custom runner.
This directory is high-risk because correctness depends on filename order, checksum immutability, and special handling for `_notx.sql` files.

## STRUCTURE
```text
backend/migrations/
├── NNN_description.sql # Transactional migrations
├── NNN_description_notx.sql # Non-transactional concurrent index migrations
└── README.md # Full migration workflow and rules
```

## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Migration rules | `README.md` | Naming, immutability, `_notx.sql`, troubleshooting |
| Runtime behavior | `../internal/repository/migrations_runner.go` | Checksums, advisory lock, execution mode |
| Applied migration state | `schema_migrations` table | Stores filename + checksum |

## CONVENTIONS
- Name files as `NNN_description.sql` with zero-padded numeric prefixes.
- Keep migrations forward-only; if you need to revert behavior, add a new migration.
- `_notx.sql` is only for statements that must run outside a transaction, especially `CREATE/DROP INDEX CONCURRENTLY`.
- `_notx.sql` content must be idempotent: use `IF NOT EXISTS` / `IF EXISTS`.
- Files execute in lexicographic order, not by timestamp or folder.

## ANTI-PATTERNS
- Editing a migration that may already have run in any environment.
- Renaming, deleting, or reordering existing migration files.
- Mixing regular DDL/DML or transaction control statements into `_notx.sql` files.
- Assuming goose-style Up/Down parsing exists; the runner executes the file content as-is.

## COMMANDS
```bash
psql -d sub2api -c "SELECT * FROM schema_migrations ORDER BY applied_at DESC;"
git log --oneline -- backend/migrations/NNN_description.sql
```

## NOTES
- The application auto-runs migrations on startup; there is no separate migration binary here.
- Recovery from checksum mismatch is a Git/history problem first, not a SQL-edit-in-place problem.
- If a schema change starts in `backend/ent/schema/`, add the migration here in the same change set.
- Read `README.md` before touching `_notx.sql`; it contains repo-specific execution semantics.
59 changes: 59 additions & 0 deletions deploy/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# DEPLOYMENT KNOWLEDGE BASE

## OVERVIEW
`deploy/` is the operator-facing subtree for Docker Compose, systemd installs, env templates, and deployment scripts.

## STRUCTURE
```text
deploy/
├── docker-compose.local.yml # Preferred local-directory deployment
├── docker-compose.yml # Named-volume deployment
├── docker-compose.dev.yml # Build-from-source local development
├── docker-compose.standalone.yml # App-only deployment with external Postgres/Redis
├── docker-deploy.sh # One-click Docker preparation
├── install.sh # Binary install / upgrade / uninstall
├── docker-entrypoint.sh # Container permission fix + exec wrapper
├── .env.example # Docker env template
├── config.example.yaml # Binary/systemd config template
└── sub2api.service # Systemd unit
```

## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Choose Docker variant | `docker-compose.local.yml`, `docker-compose.yml`, `docker-compose.standalone.yml` | Local directories are preferred; standalone expects external services |
| One-click Docker setup | `docker-deploy.sh` | Downloads local compose/env templates and generates secrets |
| Binary install / upgrade | `install.sh`, `sub2api.service` | Systemd path is `/opt/sub2api`; setup wizard remains relevant here |
| Container startup behavior | `docker-entrypoint.sh` | Fixes `/app/data` ownership, then re-execs as `sub2api` |
| Environment variables | `.env.example`, `config.example.yaml` | Docker favors env vars; binary install can use config YAML |
| Data management daemon | `DATAMANAGEMENTD_CN.md`, `install-datamanagementd.sh` | Socket path is fixed at `/tmp/sub2api-datamanagement.sock` |

## CONVENTIONS
- Prefer `docker-compose.local.yml` for self-hosted deployments because data lives in local directories and migrates cleanly by archiving the deploy folder.
- Docker deployments rely on `AUTO_SETUP=true`; binary/systemd deployments still expect the normal setup wizard flow.
- Keep `JWT_SECRET` and `TOTP_ENCRYPTION_KEY` fixed across restarts; empty values trigger random regeneration and break sessions or 2FA.
- `docker-compose.standalone.yml` is only for environments with externally managed PostgreSQL and Redis.
- Container and service units run as `sub2api`; permission fixes happen in entrypoint/service setup, not in app code.

## ANTI-PATTERNS
- Using named-volume compose when you actually need easy backup/migration behavior.
- Removing or changing `PGDATA=/var/lib/postgresql/data` in `docker-compose.yml`; Postgres 18 otherwise falls back to the image default path and can appear to lose data after recreate.
- Assuming PostgreSQL or Redis are exposed on the host by default; the compose files keep them on the internal network unless you add debug ports yourself.
- Treating `JWT_SECRET` or `TOTP_ENCRYPTION_KEY` as optional in long-lived deployments.
- Moving the datamanagementd socket to a different path without updating the host/container mount strategy.

## COMMANDS
```bash
cd deploy && cp .env.example .env
cd deploy && docker compose -f docker-compose.local.yml up -d
cd deploy && docker compose -f docker-compose.local.yml logs -f sub2api
cd deploy && docker compose -f docker-compose.local.yml down
cd deploy && sudo ./install.sh
cd deploy && sudo ./install.sh upgrade
```

## NOTES
- `docker-deploy.sh` downloads `docker-compose.local.yml` but saves it as `docker-compose.yml`; read the script before assuming the filename tells you which variant is in use.
- `install.sh` is bilingual and defaults to Chinese in non-interactive `curl | bash` flows.
- `sub2api.service` uses hardening flags such as `NoNewPrivileges=true` and `ProtectSystem=strict`; preserve those unless deployment requirements truly change.
- Keep root deployment guidance pointer-oriented; deploy-specific gotchas should live here.
Loading
Loading