Skip to content

Commit f84e5be

Browse files
authored
Merge branch 'main' into fix/DC-216-co-socure-config
2 parents a833745 + 8bfd872 commit f84e5be

1 file changed

Lines changed: 144 additions & 36 deletions

File tree

README.md

Lines changed: 144 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,120 @@
33
[![State CI](https://github.com/codeforamerica/sebt-self-service-portal/actions/workflows/state-ci.yaml/badge.svg)](https://github.com/codeforamerica/sebt-self-service-portal/actions/workflows/state-ci.yaml)
44

55
## Background
6+
67
The Summer EBT (SUN Bucks) Self-Service Portal is an application that allows parents/guardians
78
of children eligible for [Summer EBT](https://www.fns.usda.gov/summer/sunbucks) manage their benefit, including the following core features:
9+
810
- Verifying a child's eligibility
911
- Verifying when and how the benefit will be received (which EBT card)
1012
- Changing mailing address on file
1113
- Requesting a replacement EBT card
1214

13-
## Quick start 🧰
15+
## Technology Stack overview
16+
17+
**Backend**
18+
19+
- Language/framework: [C# with .NET 10](https://dotnet.microsoft.com/en-us/languages/csharp)
20+
- Key libraries: [ASP.NET Core](https://dotnet.microsoft.com/en-us/apps/aspnet), [Serilog](https://serilog.net/), [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/en-us/dotnet/standard/mef/), [EntityFramework (EF) Core](https://learn.microsoft.com/en-us/ef/core/)
21+
- Package manager: [NuGet](https://www.nuget.org/)
22+
23+
**Frontend**
24+
25+
- Language/framework: [NextJS 16](https://nextjs.org/) with TypeScript
26+
- Key libraries: next, react, [i18next](https://www.i18next.com/), react-i18next, tanstack/react-query, zod
27+
- Package manager: [pnpm](https://pnpm.io/)
28+
- Design system: [USWDS](https://designsystem.digital.gov/), with design tokens specified for each state
29+
30+
**Infrastructure**
31+
32+
- Infrastructure as Code using OpenTofu (Terraform) - see [tofu](./tofu/)
33+
- Docker with [docker-compose](https://docs.docker.com/compose/) for local development
34+
35+
## Local Environment Set Up 🧰
36+
1437
> **Note:** The following steps assume you are working on macOS. Steps may differ if you are working on a different operating system.
1538
16-
### Prerequisites 👷
17-
- The application backend is built with the .NET 10 SDK, which can be downloaded [here](https://dotnet.microsoft.com/en-us/download).
18-
- Frontend packages and local development scripts are managed with [pnpm](https://pnpm.io/).
19-
- [Docker](https://www.docker.com/) is required for packaging and running containers.
39+
### 1. Make sure you have downloaded and installed prequisite software 👷
40+
41+
- [.NET 10 SDK](https://dotnet.microsoft.com/en-us/download) for running the back end
42+
- The latest version of [nodeJS](https://nodejs.org/en)
43+
- [pnpm](https://pnpm.io/installation/) for managing front end packages and development scripts
44+
- [Docker](https://www.docker.com/) Desktop for running and managing containers (includes MSSQL database)
45+
46+
### 2. Clone repositories
47+
48+
Clone this repository on your local machine, alongside the [state connector repository](https://github.com/codeforamerica/sebt-self-service-portal-state-connector/) and any revelant state backend connector(s) - for example, [Colorado](https://github.com/codeforamerica/sebt-self-service-portal-co-connector) - as siblings (within the same parent folder). Note that you will need to build and set up all repos as part of your local env setup.
49+
50+
```bash
51+
git clone git@github.com:codeforamerica/sebt-self-service-portal.git
52+
53+
git clone git@github.com:codeforamerica/sebt-self-service-portal-state-connector.git
54+
55+
# Colorado:
56+
git clone git@github.com:codeforamerica/sebt-self-service-portal-co-connector.git
57+
58+
```
59+
60+
### 3. Configure local environment
61+
62+
`.env` files are used in this project to set environment variables (eg, database configs). This is a preferred pattern for [12-factor Apps](https://www.12factor.net/config). They are also set to fallback to a generic default. You'll need to create `.env` files for your local environment, based on the example file.
2063

21-
### .NET Tools 🛠️
22-
.NET tools are CLI utilities installed and managed using NuGet. Currently, we are using
23-
the `nuget-license` tool for auditing backend dependency license. To install .NET tools,
24-
run `dotnet tool restore` from the solution root. Needed tools are defined in the tools
25-
manifest in `.config/dotnet-tools.json`.
64+
To create your local .env file with configurations for the database and API, run this command in the root of the repo:
2665

27-
### Development 💻
2866
```bash
29-
pnpm install # Install dependencies
67+
cp .env.example .env
3068
```
31-
***
69+
70+
You'll want do the same from within `/src/SEBT.Portal.Web`:
71+
3272
```bash
33-
pnpm dev # Start both API and frontend
73+
cp .env.example .env.local
3474
```
3575

76+
You'll also need an API `appsettings` file for your local machine with certain values set (see [state specific configuration](#state-specific-configuration) below):
77+
3678
```bash
37-
pnpm web:dev # Start frontend only
79+
cd src/SEBT.Portal.Api
80+
cp appsettings.Development.example.json appsettings.Development.json
81+
```
82+
83+
### 4. Install dependencies
84+
85+
Front end
86+
87+
- To install all javascript package dependencies, run `pnpm install` from the root of this repository.
88+
- You can learn more about the front end in the [SEBT.Portal.Web README](./src/SEBT.Portal.Web/README.md)
89+
90+
Back end
91+
92+
- .NET tools are CLI utilities installed and managed using [NuGet](https://www.nuget.org/). Currently, we are using the
93+
[`nuget-license`](https://www.nuget.org/packages/nuget-license) tool for auditing backend dependency license. Needed tools are defined in the tools manifest in `.config/dotnet-tools.json`. To install .NET tools, run `dotnet tool restore` from each solution root (ie, each top-level directory containing a `.sln` or `.slnx` file):
94+
- /src/SEBT.Portal.Infrastructure
95+
- /src/SEBT.Portal.Api
96+
97+
- You'll also want to run `dotnet build` from within the root of each repository before starting up the app for the first time.
98+
99+
### 5. Start Services 💻
100+
101+
Make sure Docker is installed and the docker daemon is running. When the database spins up locally, all migrations will be run and db seeded automatically (see [database setup](#database-setup) section below).
102+
103+
```bash
104+
docker compose up -d # Start all docker containers, including MSSQL Database and Mailpit for testing
38105
```
39106

40-
### Docker Compose
41107
```bash
42-
# Start all services (MSSQL, Mailpit)
43-
docker compose up -d
108+
pnpm dev # Script to start both API (ie, `dotnet watch`) and frontend (ie, `next dev`)
109+
```
110+
111+
To open the app, navigate to <https://localhost:3000>
112+
113+
## Development
114+
115+
### Other helpful commands
116+
117+
```bash
118+
# Start frontend only
119+
pnpm web:dev
44120

45121
# View logs
46122
docker compose logs -f
@@ -52,16 +128,19 @@ docker compose down
52128
docker compose down -v
53129
```
54130

55-
#### Mailpit (Local Email Testing)
56-
Mailpit captures all outgoing emails in development. Access the web UI at http://localhost:8025
131+
### Mailpit (Local Email Testing)
132+
133+
[Mailpit](https://mailpit.axllent.org/) captures all outgoing emails in local development. Once the Mailpit docker container is running on your machine, you can access its UI in your browser at <http://localhost:8025>
57134

58135
### Local Build & Test (Debug mode)
136+
59137
```bash
60138
pnpm api:build # Build backend only (Debug)
61139
pnpm api:test # Test backend only
62140
```
63141

64142
### CI Build & Test (Release mode)
143+
65144
```bash
66145
pnpm ci:build # Build frontend + backend (Release)
67146
pnpm ci:test # Test frontend + backend
@@ -74,6 +153,7 @@ pnpm ci:test:backend # Test backend only
74153
```
75154

76155
### CI Testing (Local)
156+
77157
```bash
78158
# State-based CI testing
79159
pnpm ci:test:states # Test all states
@@ -88,12 +168,14 @@ pnpm ci:validate # Validate workflows (dry-run)
88168
## Branch Strategy 🌿
89169

90170
**State-Specific Development:**
171+
91172
```bash
92173
deploy/dc-* # DC-only changes (only DC builds in CI)
93174
deploy/co-* # CO-only changes (only CO builds in CI)
94175
```
95176

96177
**Shared Development:**
178+
97179
```bash
98180
feature/* # Changes for all states (all states build in CI)
99181
main # Production source for all states
@@ -121,21 +203,39 @@ STATE=dc dotnet run --project src/SEBT.Portal.Api
121203
# Docker Compose uses STATE from .env
122204
docker compose up
123205
```
206+
124207
Only include sections you want to override; other settings fall back to `appsettings.json`!
125208

126209
### OIDC support
127210

128-
States can use an external OpenID Connect (OIDC) provider for sign-in. Code exchange and id_token validation run in the Next.js server; the .NET API performs "complete-login" (validates a short-lived callback token and returns a portal JWT that includes IdP claims such as phone and name).
211+
States can use an external [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/) provider for sign-in. Code exchange and id_token validation run in the Next.js server; the .NET API performs "complete-login" (validates a short-lived callback token and returns a portal JWT that includes IdP claims such as phone and name).
212+
213+
For a deployment that uses OIDC, in `.env.local` under `SEBT.Portal.Web`, set:
214+
215+
- `OIDC_DISCOVERY_ENDPOINT`
216+
- `OIDC_CLIENT_ID`
217+
- `OIDC_CLIENT_SECRET`
218+
- `OIDC_REDIRECT_URI`
219+
- `OIDC_COMPLETE_LOGIN_SIGNING_KEY` (at least 32 characters)
220+
221+
In `appsettings` under `SEBT.Portal.Api`, set:
129222

130-
For a deployment that uses OIDC, set in **Next.js** `.env.local`: `OIDC_DISCOVERY_ENDPOINT`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_REDIRECT_URI`, `OIDC_COMPLETE_LOGIN_SIGNING_KEY` (at least 32 characters). Set the **same** value for `OIDC_COMPLETE_LOGIN_SIGNING_KEY` in the API as `Oidc:CompleteLoginSigningKey`. In the API, set `Oidc:DiscoveryEndpoint`, `Oidc:ClientId`, `Oidc:CallbackRedirectUri`, and optionally `Oidc:LanguageParam`. The API serves public config via `GET /api/auth/oidc/{stateCode}/config`.
223+
- `Oidc:CompleteLoginSigningKey` (same value as `OIDC_COMPLETE_LOGIN_SIGNING_KEY`)
224+
- `Oidc:DiscoveryEndpoint`
225+
- `Oidc:ClientId`
226+
- `Oidc:CallbackRedirectUri`
227+
- `Oidc:LanguageParam` (optional)
131228

132-
See `src/SEBT.Portal.Api/appsettings.Development.example.json` and [ADR-0008](docs/adr/0008-oidc-mycolorado-authentication-and-state-auth-context.md) for the design.
229+
The API serves public config via `GET /api/auth/oidc/{stateCode}/config`.
230+
231+
See `appsettings.Development.example.json` and [ADR-0008](docs/adr/0008-oidc-mycolorado-authentication-and-state-auth-context.md).
133232

134233
### ID Proofing Requirements
135234

136235
PII data is only shown and editable to users who meet the ID proofing requirements configured within "IdProofingRequirements" and their current IAL status (for example, `address+view`, `email+view`, `phone+view`). Configure in `appsettings.json` or override with `appsettings.{state}.json`.
137236

138237
Example (`appsettings.json`):
238+
139239
```json
140240
{
141241
"IdProofingRequirements": {
@@ -154,62 +254,60 @@ The application uses Microsoft SQL Server as its database. This is propped up v
154254

155255
#### Configuration
156256

157-
Database configuration is managed through environment variables. Copy `.env.example` to `.env` and customize as needed (this is a preferred pattern for [12-factor Apps](https://www.12factor.net/config)). They are also set to fallback to a generic default.
158-
159-
```bash
160-
cp .env.example .env
161-
```
162-
163-
Available environment variables:
257+
Configuration is managed through environment variables.
164258

259+
Available environment variables for `.env` in the respository root:
165260
**Database (for Docker Compose):**
261+
166262
- `MSSQL_SA_PASSWORD` - SQL Server SA password
167263
- `MSSQL_DATABASE` - Database name
168264
- `MSSQL_USER` - Database user
169265
- `MSSQL_SERVER` - Server hostname (for local)
170266
- `MSSQL_PORT` - Server port
171267

172268
**API**
269+
173270
- `JWTSETTINGS__SECRETKEY` - Secret key for JWT token signing. Must be at least 32 characters.
174271
- `IDENTIFIERHASHER__SECRETKEY` - Secret key for HMAC-SHA256 hashing of Household Identifiers as needed. Must be at least 32 characters.
175272

176-
**OIDC (state IdP sign-in)**
177-
Set `OIDC_DISCOVERY_ENDPOINT`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_REDIRECT_URI`, and `OIDC_COMPLETE_LOGIN_SIGNING_KEY` in Next.js `.env.local`. In the API, set `Oidc:CompleteLoginSigningKey` (same value), `Oidc:DiscoveryEndpoint`, `Oidc:ClientId`, and `Oidc:CallbackRedirectUri`. See `appsettings.Development.example.json` and [ADR-0008](docs/adr/0008-oidc-mycolorado-authentication-and-state-auth-context.md).
178-
179273
### Database Migrations
180274

181-
The application uses [Entity Framework Core migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli) to manage database schema changes.
275+
The application uses [EF, or Entity Framework Core migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli) to manage database schema changes.
182276

183277
#### Automatic Migrations
184278

185279
**Migrations run automatically on application startup.** When the API starts, it checks for pending migrations and applies them automatically. This ensures the database schema is always up-to-date.
186280

187281
#### Manual Migration Commands
188282

189-
While migrations run automatically, you can also manage them manually:
283+
While migrations run automatically, you can also manage them manually by installing `ef` on your local machine:
190284

191285
**List all migrations:**
286+
192287
```bash
193288
dotnet ef migrations list \
194289
--project src/SEBT.Portal.Infrastructure/SEBT.Portal.Infrastructure.csproj \
195290
--startup-project src/SEBT.Portal.Api/SEBT.Portal.Api.csproj
196291
```
197292

198293
**Apply pending migrations:**
294+
199295
```bash
200296
dotnet ef database update \
201297
--project src/SEBT.Portal.Infrastructure/SEBT.Portal.Infrastructure.csproj \
202298
--startup-project src/SEBT.Portal.Api/SEBT.Portal.Api.csproj
203299
```
204300

205301
**Create a new migration:**
302+
206303
```bash
207304
dotnet ef migrations add MigrationName \
208305
--project src/SEBT.Portal.Infrastructure/SEBT.Portal.Infrastructure.csproj \
209306
--startup-project src/SEBT.Portal.Api/SEBT.Portal.Api.csproj
210307
```
211308

212309
**Remove the last migration (if not applied):**
310+
213311
```bash
214312
dotnet ef migrations remove \
215313
--project src/SEBT.Portal.Infrastructure/SEBT.Portal.Infrastructure.csproj \
@@ -219,6 +317,7 @@ dotnet ef migrations remove \
219317
#### Migration Files
220318

221319
Migrations are stored in `src/SEBT.Portal.Infrastructure/Migrations/`:
320+
222321
- Each migration has a timestamp prefix (e.g., `20251212171249_AddUserOptInTable.cs`)
223322
- The `PortalDbContextModelSnapshot.cs` file tracks the current model state
224323
- Migration files should be committed to version control
@@ -228,13 +327,15 @@ Migrations are stored in `src/SEBT.Portal.Infrastructure/Migrations/`:
228327
#### Automatic Seeding
229328

230329
The database is automatically seeded with test users when running in the **Development** environment. Seeding occurs automatically during:
330+
231331
- Database migrations (`dotnet ef database update`)
232332
- Application startup (when migrations are applied)
233333
- `DbContext.EnsureCreated()` calls
234334

235-
The automatic seeding uses EF Core's `UseSeeding` mechanism under the hood. See https://learn.microsoft.com/en-us/ef/core/modeling/data-seeding
335+
The automatic seeding uses EF Core's `UseSeeding` mechanism under the hood. See <https://learn.microsoft.com/en-us/ef/core/modeling/data-seeding>
236336

237337
To help test different workflows and users in different states, the seeder will create the following users unless instructed otherwise:
338+
238339
- `co-loaded@example.com` - A co-loaded user with completed ID proofing
239340
- `non-co-loaded@example.com` - A non-co-loaded user with in-progress ID proofing
240341
- `not-started@example.com` - A user who hasn't started ID proofing
@@ -254,6 +355,7 @@ dotnet run --project scripts/ClearSeededData
254355
This will prompt for confirmation before deleting all seeded records from the database. This is irreversable; once done, you'll have to reseed.
255356

256357
**View database tables example:**
358+
257359
```bash
258360
docker exec -it sebt_mssql /opt/mssql-tools18/bin/sqlcmd \
259361
-S localhost -U sa -P YourStrong@Passw0rd -d SebtPortal -C \
@@ -263,8 +365,14 @@ docker exec -it sebt_mssql /opt/mssql-tools18/bin/sqlcmd \
263365
Alternatively, I'd highly recommend a tool like [LINQPad](https://www.linqpad.net/) to help with DB-related tasks.
264366

265367
## Documentation 📚
368+
266369
More documentation can be found in the [docs](./docs) folder.
267370

371+
See also:
372+
373+
- [README for SEBT.Portal.Web (front end)](./src/SEBT.Portal.Web/README.md)
374+
- [README for Figma design token scripts](./src/SEBT.Portal.Web/design/scripts/README.md)
375+
268376
We use [Lightweight Architecture Decision Records](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions)
269377
for tracking architectural decisions, using [adr tools](https://github.com/npryce/adr-tools) to
270378
store them in source control. These can be found in the [docs/adr](./docs/adr) folder.

0 commit comments

Comments
 (0)