63d065011b
- Updated timestamps and AST hashes in manifest.json for various backend and frontend files to reflect recent changes. - Added new files related to MCC categories and optional hold reasons in the manifest. - Modified the README in the infra directory to correct the linting tool from 'mypy' to 'ty' for type checking in the backend project.
70 lines
3.1 KiB
Markdown
70 lines
3.1 KiB
Markdown
# infra/
|
|
|
|
Local development stack and provider-neutral production images. Root-owned dirs
|
|
(`backend/`, `frontend/`) are owned by their respective workstreams; this
|
|
directory owns only orchestration, images and proxy configuration.
|
|
|
|
```
|
|
infra/
|
|
├── docker-compose.yml # dev stack: api, worker, frontend proxy, pg, redis, minio, mailpit
|
|
├── .env.example # copy to infra/.env; placeholders only, no real secrets
|
|
├── docker/
|
|
│ ├── Dockerfile.backend # provider-neutral API/worker image (context: backend/)
|
|
│ └── Dockerfile.frontend # provider-neutral SPA+nginx image (context: frontend/)
|
|
└── nginx/
|
|
└── nginx.conf # same-origin /api/v1 reverse proxy + SPA static
|
|
```
|
|
|
|
## Quickstart
|
|
|
|
```sh
|
|
cp infra/.env.example infra/.env # fill placeholders (no real secrets locally)
|
|
docker compose -f infra/docker-compose.yml up -d --wait
|
|
```
|
|
|
|
| Service | URL / port | Notes |
|
|
| --- | --- | --- |
|
|
| Web app (nginx proxy) | http://127.0.0.1:8080 | serves SPA, proxies `/api/v1` → api:8000 |
|
|
| API (direct) | http://127.0.0.1:8000 | FastAPI; `GET /healthz` |
|
|
| Mailpit UI | http://127.0.0.1:8025 | test SMTP sink; SMTP on 127.0.0.1:1025 |
|
|
| MinIO console | http://127.0.0.1:9001 | S3 API on 127.0.0.1:9000 |
|
|
| PostgreSQL | 127.0.0.1:5432 | named volume `postgres_data` |
|
|
| Redis | 127.0.0.1:6379 | AOF persistence, named volume `redis_data` |
|
|
|
|
Until `backend/` and `frontend/` exist, start infra services only:
|
|
|
|
```sh
|
|
docker compose -f infra/docker-compose.yml up -d --wait postgres redis minio mailpit
|
|
```
|
|
|
|
## Contracts with backend/frontend workstreams
|
|
|
|
These entry points are referenced by the compose file and CI; coordinate changes
|
|
through both sides:
|
|
|
|
**Backend** (`backend/`, build context of `Dockerfile.backend`):
|
|
- uv-managed project with `pyproject.toml` + `uv.lock`; lint `ruff`, types `ty`, tests `pytest`.
|
|
- API: `uvicorn app.main:app`, health endpoint `GET /healthz`.
|
|
- Worker: Celery app importable as `app.worker.celery`; tasks idempotent, `acks_late`, `prefetch=1`.
|
|
- Statement parsing happens **only** in the worker; the local compose worker is attached only
|
|
to the internal backend network, and production must enforce the equivalent no-egress policy.
|
|
|
|
**Frontend** (`frontend/`, build context of `Dockerfile.frontend`):
|
|
- pnpm project with `pnpm-lock.yaml`; scripts: `lint`, `typecheck`, `test` (non-watch), `build` → `dist/`.
|
|
- Calls the same-origin `/api/v1`; **no secrets in `VITE_*`** — none are required.
|
|
|
|
## CI
|
|
|
|
`.github/workflows/ci.yml` runs backend lint/type/test/build and frontend
|
|
lint/type/test/build once the workstreams provide the plan-required lockfiles
|
|
(`backend/uv.lock`, `frontend/pnpm-lock.yaml`; auto-detected), and always
|
|
validates the compose file, boots the infra services against their healthchecks,
|
|
and `nginx -t`-checks the proxy config.
|
|
|
|
## Production
|
|
|
|
Production runs the same images on a platform in the Russian Federation that
|
|
supplies PostgreSQL, Redis, S3-compatible storage, SMTP and a secret manager.
|
|
See `docs/adr/0004-provider-neutral-encrypted-data-boundary.md` and
|
|
`docs/operations/beta-release-runbook.md`.
|