2026-05-18 15:30:30 -04:00
# Proposal System
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
2026-06-11 14:02:35 -04:00





2026-05-18 15:30:30 -04:00
Internal proposal management platform for Sea Haven Industries. Dispatchers submit proposal requests, AI generates draft line items from historical data via Bedrock RAG, admins review and approve in a pricing workspace, and the system produces branded PDFs for delivery.
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
2026-05-18 15:30:30 -04:00
## Architecture Overview
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
2026-05-18 15:30:30 -04:00
Monorepo with five primary services:
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
- **.NET 8 API** -- Clean Architecture REST API hosted on Lambda behind API Gateway (JWT-authorized) with Function URL (AWS_IAM) for internal access
2026-05-18 15:30:30 -04:00
- **React 19 Web** -- MUI v7 admin/dispatcher workspace served via CloudFront + S3
- **React Native Mobile** -- iOS-first field app for dispatchers (offline-capable)
2026-05-18 18:10:35 -04:00
- **Python Lambdas** -- PDF extraction, PDF generation, library ingestion, AI suggestions, AOSS index provisioning
2026-05-18 15:30:30 -04:00
- **CDK Infrastructure** -- Three TypeScript stacks managing all AWS resources
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
## Repository Structure
```
proposal-system/
2026-05-18 15:30:30 -04:00
├── api/ .NET 8 Web API (Lambda-hosted, EF Core + PostgreSQL)
├── web/ React 19 + MUI v7 + Vite frontend
2026-05-20 11:36:51 -04:00
├── mobile/ React Native 0.85 iOS app
2026-05-18 15:30:30 -04:00
├── lambdas/ Python 3.12 processing functions (arm64)
├── infra/ CDK TypeScript (3 stacks)
├── shared/ TypeScript API contracts (shared between web + mobile)
├── scripts/ Post-deploy and utility scripts
├── .github/ CI/CD workflows
└── docker-compose.yml
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
```
2026-05-18 15:30:30 -04:00
## Tech Stack
| Component | Technologies |
|---|---|
| API | .NET 8, ASP.NET Core, EF Core + Npgsql, FluentValidation, Cognito JWT, Amazon.Lambda.AspNetCoreServer |
| Web | React 19, TypeScript, MUI v7, Vite, Redux Toolkit, TanStack Query, axios |
2026-05-20 11:36:51 -04:00
| Mobile | React Native CLI 0.85, React 19, React Native Paper, React Navigation, react-native-app-auth (PKCE), amazon-cognito-identity-js (SRP), Keychain, offline draft queue |
2026-05-18 15:30:30 -04:00
| Lambdas | Python 3.12, arm64, pdfplumber, reportlab, httpx, boto3 |
| Infrastructure | CDK TypeScript (aws-cdk-lib 2.253.1) |
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| AI/RAG | Bedrock Knowledge Base (Titan Embeddings v2), OpenSearch Serverless (VPC-only), Claude Sonnet via Bedrock cross-region inference |
2026-05-18 15:30:30 -04:00
| Auth | Cognito User Pool + Google OAuth IdP (groups: dispatchers, admins, sysadmins) |
## AWS Resources
2026-05-18 18:10:35 -04:00
All resources are in **us-east-1** (account 328440206208).
2026-05-18 15:30:30 -04:00
| CDK Stack | Key Resources |
|---|---|
| `proposal-system-foundation` | RDS PostgreSQL 15 (t4g.small), S3 buckets, SQS queue + DLQ, Cognito user pool, Secrets Manager |
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| `proposal-system-compute` | API Gateway HTTP API (JWT authorizer + access logging), .NET 8 API Lambda + Function URL (AWS_IAM), Python Lambdas (pdf-extract, pdf-generate, library-ingest, suggestions, oss-index-creator), OpenSearch Serverless collection (VPC endpoint), Bedrock KB |
2026-05-18 15:30:30 -04:00
| `proposal-system-frontend` | CloudFront distribution (S3 OAC) |
| Resource Type | Names |
|---|---|
| S3 Buckets | `proposal-system-uploads` , `proposal-system-generated` , `proposal-system-library` , `seahaven-ios-certificates` |
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| SQS | `proposal-system-jobs` (720s visibility, SQS-managed encryption, reportBatchItemFailures) + `proposal-system-jobs-dlq` (SQS-managed encryption, message body filtering by jobType) |
2026-05-18 15:30:30 -04:00
| Secrets | `proposal-system/db-credentials` , `proposal-system/internal-api-key` |
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
## Local Development
### Prerequisites
- .NET 8 SDK
2026-05-18 15:30:30 -04:00
- Node.js 24+
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
- Python 3.12
2026-05-18 15:30:30 -04:00
- PostgreSQL 16 (via docker-compose or native)
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
2026-05-18 15:30:30 -04:00
### Database
```bash
docker compose up -d # starts PostgreSQL on port 5432
# database: proposalsystem, password: localdev
```
### API
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
```bash
cd api
dotnet restore
dotnet run --project src/ProposalSystem.Api
2026-05-18 15:30:30 -04:00
# runs on http://localhost:5000
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
```
2026-05-18 15:30:30 -04:00
In development mode (`DevMode=true` in appsettings.Development.json):
- JWT auth uses a local symmetric HMAC key (no Cognito required)
- S3 service returns fake presigned URLs
- SQS publisher logs messages without sending
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
### Web Frontend
```bash
cd web
npm install
npm run dev
2026-05-18 15:30:30 -04:00
# runs on http://localhost:5173, proxies /api to localhost:5000
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
```
2026-05-18 15:30:30 -04:00
When `VITE_COGNITO_CLIENT_ID` is not set, the login screen shows role-selector buttons for local development.
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
### Infrastructure
```bash
cd infra
npm install
npx cdk synth
```
## CI/CD
2026-05-18 15:30:30 -04:00
### CI (on pull request to main)
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
Seven parallel jobs calling org reusable workflows:
2026-05-18 15:30:30 -04:00
| Job | Workflow | What it checks |
|---|---|---|
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| .NET Build & Test | `ci-dotnet.yaml` | Restore, build, test the API solution (104 xUnit tests) |
2026-05-18 15:30:30 -04:00
| Web Frontend Check | `ci-typescript-cdk.yaml` | TypeScript typecheck for web |
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| Web Tests | `ci-typescript-cdk.yaml` | vitest suite (26 tests — auth, interceptors, components) |
2026-05-18 15:30:30 -04:00
| Mobile Typecheck | `ci-typescript-cdk.yaml` | TypeScript typecheck for mobile |
| Python Lint | `ci-python-sam.yaml` | ruff check + format on lambdas/ |
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| Python Tests | `ci-python-sam.yaml` | pytest suite (19 tests — pdf-generate, suggestions handlers) |
2026-05-18 15:30:30 -04:00
| CDK Synth | `ci-typescript-cdk.yaml` | Synthesize CDK stacks (includes .NET publish) |
### Deploy (on push to main)
Calls `cd-cdk.yaml` reusable workflow:
1. Publishes .NET 8 API and Python Lambdas
2. Runs `cdk deploy --all`
3. Executes `scripts/post-deploy.sh` (builds web, syncs to S3, invalidates CloudFront)
Deploy uses OIDC role `githubdeploy-proposal-system` . Concurrency group prevents parallel deploys.
2026-05-20 11:36:51 -04:00
### Mobile Deploy
2026-05-18 15:30:30 -04:00
2026-05-20 11:36:51 -04:00
Workflow: `deploy-mobile.yaml` -- builds and uploads to TestFlight via `cd-mobile-ios.yaml` reusable workflow on `macos-26` .
2026-05-18 15:30:30 -04:00
2026-05-20 11:36:51 -04:00
Triggers:
- **Automatic**: push to `main` with changes in `mobile/**`
- **Manual**: `workflow_dispatch` for on-demand builds
2026-05-18 15:30:30 -04:00
## Mobile iOS
The iOS app uses **Fastlane** with **match** for code signing. Certificates and profiles are stored in the `seahaven-ios-certificates` S3 bucket (versioning enabled, public access blocked).
Build and upload to TestFlight is handled by the `cd-mobile-ios.yaml` reusable workflow. Required secrets:
| Secret | Purpose |
|---|---|
| `AWS_DEPLOY_ROLE_ARN` | OIDC role for match S3 access |
| `MATCH_PASSWORD` | Decryption passphrase for signing assets |
| `ASC_KEY_ID` | App Store Connect API key ID |
| `ASC_ISSUER_ID` | App Store Connect issuer |
| `ASC_KEY_CONTENT` | App Store Connect API key (base64) |
2026-05-20 18:51:31 -04:00
## Authentication & Authorization
Two-layer auth architecture with defense-in-depth:
| Path | Authorizer | Authentication |
|---|---|---|
| External clients → API Gateway `/{proxy+}` | Cognito JWT authorizer (web + mobile client IDs) | .NET JWT middleware (ValidateAudience=true) |
| `/api/health` | None (public) | None |
| `/api/auth/callback` , `/api/auth/dev-login` | None (unauthenticated) | None (pre-auth endpoints) |
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
| Internal Lambdas → Function URL | AWS_IAM (grantInvokeUrl) | Internal API key (`X-Internal-Api-Key` header, value from Secrets Manager) |
2026-05-20 18:51:31 -04:00
**Role-based access:** Cognito groups (`dispatchers` , `admins` , `sysadmins` ) map to API roles via `cognito:groups` claim. Dispatchers can only see their own proposals (ownership enforced in service layer). VendorProposals and GeneratedPdfs endpoints restricted to admins/sysadmins.
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
**Internal API key:** Python Lambdas call the .NET API via a Lambda Function URL with AWS_IAM auth (bypasses API Gateway JWT check). The `InternalApiKeyMiddleware` validates the `X-Internal-Api-Key` header and assigns the `admins` role to the synthetic identity. Lambdas cache the API key from Secrets Manager with a 5-minute TTL.
2026-05-20 18:51:31 -04:00
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
## Data Flow
1. Dispatcher submits proposal request (web or mobile)
2026-05-20 18:51:31 -04:00
2. API creates proposal record (with advisory-locked number generation), publishes SQS message
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
3. If vendor PDF attached: `pdf-extract` Lambda parses and structures data
2026-05-18 15:30:30 -04:00
4. Suggestions Lambda queries Bedrock KB for similar proposals, generates line items via Claude
5. Admin reviews/edits line items in pricing workspace
Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model
Phase 0 of proposal-system: complete project setup including:
- CDK infrastructure (3 stacks: foundation, compute, frontend)
- .NET 8 solution with Clean Architecture (Domain, Application, Infrastructure, Api)
- EF Core data model (PostgreSQL) with all entities
- Python Lambda placeholders (pdf-extract, pdf-generate, library-ingest)
- React 19 web frontend scaffold (Vite + MUI)
- React Native mobile placeholder
- Shared TypeScript API contracts
- GitHub Actions CI/CD (ci.yaml + deploy.yaml)
- OIDC deploy role (githubdeploy-proposal-system)
- Dependabot configuration
- Cognito User Pool with Google OAuth, PKCE clients, groups
2026-05-16 18:40:46 -04:00
6. On approval: `pdf-generate` Lambda creates branded PDF
2026-05-18 15:30:30 -04:00
7. On send: `library-ingest` Lambda adds approved proposal to KB for future matching
2026-05-20 18:51:31 -04:00
Failed SQS messages are reported via `batchItemFailures` and retried up to 3 times before moving to the DLQ.
docs: Phase 6 cleanup — update AUDIT-REPORT, README, remove stale docs
- AUDIT-REPORT.md: mark all Phase 6 findings fixed (API-M2/M5/M7/M9/M10/M12/M13,
WEB-M3/M4/M8/M9/M11, LAM-M2/M3/M6/M9, INF-M1/M2/M9), update test count to 149
- README.md: Function URL NONE→AWS_IAM, add Testing and Security sections,
expand CI table with test jobs, note SQS encryption/OpenSearch VPC/access logging
- Remove stale session docs (AUDIT-2026-05-20, HANDOFF, RETROSPECTIVE, CHATGPT prompt)
- Add .claude/agents/ to .gitignore
- Remove empty-state placeholder from SimilarProposalsPanel
2026-05-27 18:17:37 -04:00
## Testing
149 tests across three stacks, all run in CI on every PR:
| Suite | Framework | Count | Coverage |
|---|---|---|---|
| .NET API | xUnit | 104 | State machine transitions, authorization attributes, middleware, validators, ProposalNumberGenerator, LineItemService state guards |
| Web | vitest | 26 | ProtectedRoute, RoleGuard, API client interceptor (401 logout, token attachment) |
| Python Lambdas | pytest | 19 | pdf-generate and suggestions handler contracts |
```bash
cd api & & dotnet test # .NET tests
cd web & & npm test # vitest
cd lambdas & & python -m pytest # pytest
```
## Security
Hardening applied across all layers (see AUDIT-REPORT.md for full details):
- **Auth:** Cognito JWT validation with audience check, startup fails if auth not configured, DevMode gated to `IsDevelopment()`
- **API:** FluentValidation on all DTOs, generic error responses (no stack traces or config leaks), structured audit logging with before/after diffs
- **Function URL:** AWS_IAM auth + internal API key (two-layer defense)
- **Infrastructure:** S3 `enforceSSL` + `BLOCK_ALL` , SQS managed encryption, OpenSearch VPC-only, Cognito optional TOTP MFA, API Gateway access logging
- **Lambdas:** Prompt injection sanitization, PDF size limits, numeric validation on AI suggestions, S3 key sanitization, idempotent SQS processing
- **CI/CD:** OIDC (no long-lived credentials), SHA-pinned workflow refs, `--require-approval broadening` on local deploys
- **Web:** sessionStorage for tokens (not localStorage), error boundaries, role guards on all admin routes, 401 interceptor clears auth state