> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aspfox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Local Development

> Day-to-day development workflow, hot reload, and the full Makefile reference.

## Hot reload

**Backend:** The API container runs `dotnet watch run`. Save any `.cs` file and the application rebuilds incrementally. Changes typically take 2–5 seconds to take effect. You do not need to restart Docker.

**Frontend:** Vite HMR (Hot Module Replacement) is active in the frontend container. Save any `.tsx`, `.ts`, or `.css` file and the browser updates without a full page reload. React state is preserved for components that are not directly modified.

## Makefile reference

All development commands go through `make`. Run any of these from the project root.

| Command                      | What it does                                              |
| ---------------------------- | --------------------------------------------------------- |
| `make up`                    | Start all services in the background (detached mode)      |
| `make down`                  | Stop all services and remove containers                   |
| `make restart`               | Restart the API container without rebuilding the image    |
| `make logs`                  | Follow logs from all services (Ctrl+C to stop)            |
| `make logs SERVICE=api`      | Follow logs from the API container only                   |
| `make logs SERVICE=frontend` | Follow logs from the frontend container only              |
| `make build`                 | Rebuild Docker images and restart all services            |
| `make migrate`               | Apply any pending EF Core migrations to the database      |
| `make seed`                  | Run database seeders (creates admin user and lookup data) |
| `make test`                  | Run all tests (backend + frontend)                        |
| `make test-backend`          | Run backend xUnit tests with coverage report              |
| `make test-frontend`         | Run frontend Vitest tests                                 |
| `make typecheck`             | Run TypeScript type checking on the frontend (no emit)    |
| `make lint`                  | Run ESLint on the frontend                                |
| `make shell-api`             | Open a bash shell inside the running API container        |
| `make shell-db`              | Open a psql session in the database container             |
| `make clean`                 | Remove all containers and volumes (deletes database data) |
| `make fresh`                 | Full reset: `clean` + `up` + `migrate` + `seed`           |
| `make release-check`         | Run all checks that CI runs: typecheck, lint, test        |

## Adding an EF Core migration

When you modify an entity or add a new one, you need to create a migration and apply it.

**Step 1:** Make sure the database container is running:

```bash theme={null}
make up
```

**Step 2:** Open a shell in the API container:

```bash theme={null}
make shell-api
```

**Step 3:** Create the migration from inside the container:

```bash theme={null}
dotnet ef migrations add AddProjectsTable \
  --project src/Acme.Infrastructure \
  --startup-project src/Acme.Api
```

**Step 4:** Exit the container and apply the migration:

```bash theme={null}
exit
make migrate
```

The migration file is created in `src/Acme.Infrastructure/Migrations/`. Commit it to git alongside the entity changes.

<Note>
  If you need to roll back a migration in development, run `make shell-api` and then `dotnet ef database update <PreviousMigrationName>` inside the container. Then delete the unwanted migration file.
</Note>

## Viewing database contents

Open a psql session directly:

```bash theme={null}
make shell-db
```

This drops you into an interactive psql session connected to the development database. Use standard psql commands:

```sql theme={null}
\dt                           -- list all tables
SELECT * FROM users LIMIT 10;
SELECT * FROM tenants;
SELECT * FROM refresh_tokens WHERE is_revoked = false;
\q                            -- quit
```

## Viewing API logs

```bash theme={null}
make logs SERVICE=api
```

AspFox uses Serilog with structured logging. Every request logs a correlation ID, method, path, status code, and duration. Example:

```
[INF] HTTP POST /api/v1/auth/login 200 OK in 47ms {CorrelationId: "abc123"}
[INF] Executing InviteMemberCommand {TenantId: "…", TargetEmail: "user@example.com"}
[WRN] Resend email failed for template EmailVerification {Error: "…"}
```

The correlation ID appears in every log line for a request, making it easy to trace a request through the logs.

## Running tests

```bash theme={null}
# All tests
make test

# Backend only (shows coverage)
make test-backend

# Frontend only
make test-frontend
```

Backend tests use TestContainers — they spin up a real PostgreSQL instance in Docker for integration tests. The first run downloads the container image; subsequent runs are fast.
