Files
AdPlatform-Server/Registration/README.md
Grae Jones fae2226581
All checks were successful
Registration / build-deploy (push) Successful in 9m8s
Revised Registration
2026-03-22 09:37:28 -07:00

127 lines
4.7 KiB
Markdown

# Registration Service
ASP.NET Core (.NET 8) service for managing prospect registration in AdPlatform.
Self-hosted via docker-compose as `registration:8080` behind nginx / Gateway.
## Architecture
```
Client SPA (client.positivespend.com)
└─► Gateway (portal.positivespend.com)
└─► Registration API (regapi.positivespend.com → registration:8080)
├─► dbRegistration (10.10.99.212 — Registrations table, spRegistration)
└─► CIAM (PositiveSpendClients.ciamlogin.com — token validation)
Management API (mgmt.positivespend.com)
└─► Registration API (admin endpoints, x-functions-key auth)
└─► dbRegistration
```
The Registration service never touches `dbAdPlatform`. Management never touches `dbRegistration`.
Approval provisioning into `dbAdPlatform` is the Management API's responsibility, called after
the `complete` action marks a registration as Approved.
## Endpoints
| Method | Route | Auth | Description |
|--------|-------|------|-------------|
| `POST` | `/api/registration/register` | Bearer (CIAM JWT) | New prospect signup |
| `GET` | `/api/registration/pending` | x-functions-key | List pending applicants |
| `GET` | `/api/registration/item/{id}` | x-functions-key | Get single applicant |
| `POST` | `/api/registration/action/{id}/reject` | x-functions-key | Reject applicant |
| `POST` | `/api/registration/action/{id}/complete` | x-functions-key | Mark approved |
| `GET` | `/api/health` | Anonymous | Health check |
`entraSubjectId` is **never** read from the request body on `/register` — it is extracted
from the validated CIAM Bearer token (OID claim). The client cannot spoof it.
## Authentication
**Client-facing endpoint** (`/register`): Bearer token issued by
`PositiveSpendClients.ciamlogin.com` (tenant `cbf8b7d7`). Validated by
`Microsoft.Identity.Web` against the CIAM tenant. The Client SPA acquires this
token via MSAL after the user signs in with Google, Apple, or Microsoft.
**Admin endpoints** (`pending` / `item` / `reject` / `complete`): `x-functions-key` header
validated by `ApiKeyAuthFilter`. Key must match `Registration__FunctionKey` env var.
These endpoints are called by the Management API, not the browser.
## CIAM Tenant Reference
| Field | Value |
|-------|-------|
| Tenant | Positive Spend Clients |
| Tenant ID | `cbf8b7d7-1e13-486d-b5b0-287ba79fdf0b` |
| Client SPA App ID | `c426967f-bfcc-46af-b4e5-d69dc01cbf75` |
| Authority | `https://PositiveSpendClients.ciamlogin.com/cbf8b7d7.../` |
This is the **client-facing CIAM tenant** — separate from the internal `positivespend.com`
org tenant (`f56a3c51`) used by Management and the Tech/Admin consoles.
## Mock Mode
Switch in `Program.cs` to run without a database (seeds 4 test applicants in memory):
```csharp
services.AddSingleton<IRegistrationDataService, MockDataService>();
```
State resets on container restart — by design.
## Database Setup
Run `dbo.spRegistration.sql` against `dbRegistration` on `10.10.99.212` once.
It is idempotent (`CREATE OR ALTER PROCEDURE`, `IF OBJECT_ID ... IS NULL` guard on the table).
## docker-compose Environment Variables
```bash
# SQL Server
ConnectionStrings__Sql=Server=10.10.99.212;Database=dbRegistration;User Id=appAdPlatformReg;Password=...;TrustServerCertificate=True;
# CIAM — already correct in .env
AzureAd__Instance=https://PositiveSpendClients.ciamlogin.com/
AzureAd__TenantId=cbf8b7d7-1e13-486d-b5b0-287ba79fdf0b
AzureAd__ClientId=c426967f-bfcc-46af-b4e5-d69dc01cbf75
# CORS — already in .env
CORS__AllowedOrigins=https://client.positivespend.com,https://portal.positivespend.com,...
# Admin key — already in .env
Registration__FunctionKey=mra0B2boC5m36E7CUn-Urhwp7k3t3QvPZKjJvtNVEdVgAzFuuaAyRA==
```
## Health Check
```bash
curl https://regapi.positivespend.com/api/health
# {"ok":true,"service":"registration","mode":"database","timestamp":"..."}
```
## SSL
```bash
sudo certbot --nginx -d regapi.positivespend.com
```
---
## Host Swap — Restore Azure Functions
Three files change. Everything else (Data layer, Mock layer, models, SQL) is identical.
| File | Change |
|------|--------|
| `Registration.csproj` | Comment ASP.NET Core `ItemGroup`, uncomment Functions `ItemGroup`, restore `<AzureFunctionsVersion>v4</AzureFunctionsVersion>`, change `Sdk` to `Microsoft.NET.Sdk` |
| `Program.cs` | Comment ASP.NET Core block, uncomment Functions `HostBuilder` block |
| `Functions/RegistrationFunctions.cs` | Swap class declaration, swap each method signature (all marked `◄ INACTIVE`) |
Client changes when restoring Functions:
- `authConfig.js`: set `API_BASE_URL` to the Azure Function App URL, set `API_FUNCTION_KEY` from Azure Portal → App Keys → default
Run locally in Functions mode:
```bash
func start
curl http://localhost:7071/api/health
```