Updated CLAUDE.md and deployment script
This commit is contained in:
@@ -30,7 +30,7 @@ npm run lint # eslint
|
||||
|
||||
### Docker
|
||||
```powershell
|
||||
.\build-budget-image.ps1 # builds multi-stage image and pushes to docker.stwaddle.com/budget:latest
|
||||
.\deploy.ps1 # builds image, pushes to docker.stwaddle.com/budget:latest, and deploys to prod via SSH
|
||||
```
|
||||
|
||||
## Architecture
|
||||
@@ -71,11 +71,18 @@ src/
|
||||
- **Inline table editing**: rows show read-only data; clicking a cell enters edit mode in-place using a `useState(editing)` toggle. New rows use a separate input row appended to `<tbody>` (not a modal).
|
||||
- **Sorting**: `SortableHeader` component and `SortState` type in `src/components/SortableHeader.tsx`. Sorting is client-side only and derives a view from the drag-ordered `displayItems` array — clearing sort restores drag order. Drag handles are disabled while a sort is active.
|
||||
- **Frequency calculations** for real-time previews are in `src/utils/frequency.ts`, mirroring the C# `FrequencyCalculator` exactly.
|
||||
- **Drag-and-drop ordering**: `@dnd-kit` is used on income/outgo rows. Row order is persisted to the server. Sort handles are hidden while a column sort is active.
|
||||
- **Auth**: `react-oidc-context` wraps the whole app; `AuthGuard` protects all budget routes; `TokenSync` wires the OIDC access token into the API client on every auth state change. After OIDC callback, navigation uses `window.location.replace('/')` (not `history.replaceState`) so React Router picks up the URL change.
|
||||
|
||||
### Local development environment
|
||||
Required env vars when running the API locally (set in `appsettings.Development.json` or shell):
|
||||
- `ConnectionStrings__DefaultConnection` — Postgres connection string
|
||||
- `Oidc__Audience` — `budget_api`
|
||||
- `OTEL_EXPORTER_OTLP_ENDPOINT` — optional; omit or set to skip telemetry export
|
||||
|
||||
### Auth / OIDC
|
||||
- Authority: `https://auth.stwaddle.com/` (OpenIddict-based, at `src.Auth.Server` in a sibling repo)
|
||||
- API audience claim: `budget-api` (must match `AUTH__AUDIENCE` env var)
|
||||
- API audience claim: `budget_api` (underscore — must match `Oidc__Audience` env var)
|
||||
- Scope: `budget_api` (underscore, not hyphen)
|
||||
- Roles `admin` and `user` are granted per-user on the client registration in the auth server admin panel. A user with no role gets `access_denied` at the authorize endpoint.
|
||||
- Frontend OIDC config is baked into the build via `VITE_*` env vars; override locally in `src/Budget.Client/.env.local`
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
$image = "docker.stwaddle.com/budget:latest"
|
||||
docker build -t $image .
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
docker push $image
|
||||
+6
-2
@@ -1,2 +1,6 @@
|
||||
.\build-image.ps1
|
||||
.\update-container.ps1
|
||||
$image = "docker.stwaddle.com/budget:latest"
|
||||
docker build -t $image .
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
docker push $image
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
ssh stwaddle_com "cd stwaddlecom; docker compose pull budget; docker compose down budget; docker compose up -d budget"
|
||||
@@ -1,46 +0,0 @@
|
||||
services:
|
||||
budget:
|
||||
image: ${IMAGE_REGISTRY:-}budget:latest
|
||||
environment:
|
||||
- VIRTUAL_HOST=${BUDGET_VIRTUAL_HOST:-budget.stwaddle.com}
|
||||
- LETSENCRYPT_HOST=${BUDGET_LETSENCRYPT_HOST:-budget.stwaddle.com}
|
||||
- VIRTUAL_PORT=8080
|
||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Production}
|
||||
- ConnectionStrings__DefaultConnection=Host=apps-db;Port=5432;Database=${POSTGRES_DB:-budget};Username=${POSTGRES_USER:-budget};Password=${POSTGRES_PASSWORD}
|
||||
- OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT}
|
||||
- OTEL_EXPORTER_OTLP_PROTOCOL=${OTEL_EXPORTER_OTLP_PROTOCOL}
|
||||
- OTEL_SERVICE_NAME=budget
|
||||
depends_on:
|
||||
- apps-db
|
||||
- auth
|
||||
networks:
|
||||
- web
|
||||
- apps-internal
|
||||
- auth-public
|
||||
- telemetry
|
||||
restart: unless-stopped
|
||||
|
||||
apps-db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_DB=${POSTGRES_DB:-budget}
|
||||
- POSTGRES_USER=${POSTGRES_USER:-budget}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
volumes:
|
||||
- apps-db-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- apps-internal
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
apps-internal:
|
||||
external: true
|
||||
auth-public:
|
||||
external: true
|
||||
telemetry:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
apps-db-data:
|
||||
@@ -1 +0,0 @@
|
||||
ssh stwaddle_com "cd stwaddlecom; docker compose pull budget; docker compose down budget; docker compose up -d budget"
|
||||
Reference in New Issue
Block a user