Commit graph

37 commits

Author SHA1 Message Date
dependabot[bot]
debdf45300
build(deps): bump constructs (#244)
Bumps the infra group with 1 update in the /infra directory: [constructs](https://github.com/aws/constructs).


Updates `constructs` from 10.7.0 to 10.7.1
- [Release notes](https://github.com/aws/constructs/releases)
- [Commits](https://github.com/aws/constructs/compare/v10.7.0...v10.7.1)

---
updated-dependencies:
- dependency-name: constructs
  dependency-version: 10.7.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: infra
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 16:06:55 -04:00
Adam Moussa
d011b66467
build(deps): batch Dependabot updates (#232-#240, #242) (#243)
* build(deps): bump the infra group in /infra with 3 updates

Bumps the infra group in /infra with 3 updates: [constructs](https://github.com/aws/constructs), [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) and [tsx](https://github.com/privatenumber/tsx).


Updates `constructs` from 10.6.0 to 10.7.0
- [Release notes](https://github.com/aws/constructs/releases)
- [Commits](https://github.com/aws/constructs/compare/v10.6.0...v10.7.0)

Updates `aws-cdk` from 2.1130.0 to 2.1132.0
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1132.0/packages/aws-cdk)

Updates `tsx` from 4.23.0 to 4.23.1
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.23.0...v4.23.1)

---
updated-dependencies:
- dependency-name: constructs
  dependency-version: 10.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: infra
- dependency-name: aws-cdk
  dependency-version: 2.1132.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: infra
- dependency-name: tsx
  dependency-version: 4.23.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: infra
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): update boto3 requirement in /lambdas/aurora-pgvector-init

Updates the requirements on [boto3](https://github.com/boto/boto3) to permit the latest version.
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.43.46...1.43.51)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.43.51
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): update boto3 requirement in /lambdas/suggestions

Updates the requirements on [boto3](https://github.com/boto/boto3) to permit the latest version.
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.43.46...1.43.51)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.43.51
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): update boto3 requirement in /lambdas/pdf-extract

Updates the requirements on [boto3](https://github.com/boto/boto3) to permit the latest version.
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.43.46...1.43.51)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.43.51
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): update boto3 requirement in /lambdas/pdf-generate

Updates the requirements on [boto3](https://github.com/boto/boto3) to permit the latest version.
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.43.46...1.43.51)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.43.51
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump the web group in /web with 3 updates

Bumps the web group in /web with 3 updates: [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react), [react-hook-form](https://github.com/react-hook-form/react-hook-form) and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `lucide-react` from 1.24.0 to 1.25.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.25.0/packages/lucide-react)

Updates `react-hook-form` from 7.81.0 to 7.82.0
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.81.0...v7.82.0)

Updates `vite` from 8.1.4 to 8.1.5
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.1.5/packages/vite)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: web
- dependency-name: react-hook-form
  dependency-version: 7.82.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: web
- dependency-name: vite
  dependency-version: 8.1.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: web
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): bump the mobile-npm group in /mobile with 4 updates

Bumps the mobile-npm group in /mobile with 4 updates: [@react-navigation/bottom-tabs](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/bottom-tabs), [@react-navigation/native](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/native), [@react-navigation/native-stack](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/native-stack) and [react-native-screens](https://github.com/software-mansion/react-native-screens).


Updates `@react-navigation/bottom-tabs` from 7.18.8 to 7.18.11
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/bottom-tabs@7.18.11/packages/bottom-tabs/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/bottom-tabs@7.18.11/packages/bottom-tabs)

Updates `@react-navigation/native` from 7.3.8 to 7.3.11
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/native@7.3.11/packages/native/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/native@7.3.11/packages/native)

Updates `@react-navigation/native-stack` from 7.17.10 to 7.18.3
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/native-stack@7.18.3/packages/native-stack/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/native-stack@7.18.3/packages/native-stack)

Updates `react-native-screens` from 4.26.0 to 4.26.2
- [Release notes](https://github.com/software-mansion/react-native-screens/releases)
- [Commits](https://github.com/software-mansion/react-native-screens/compare/4.26.0...4.26.2)

---
updated-dependencies:
- dependency-name: "@react-navigation/bottom-tabs"
  dependency-version: 7.18.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mobile-npm
- dependency-name: "@react-navigation/native"
  dependency-version: 7.3.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mobile-npm
- dependency-name: "@react-navigation/native-stack"
  dependency-version: 7.18.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: mobile-npm
- dependency-name: react-native-screens
  dependency-version: 4.26.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mobile-npm
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps): update boto3 requirement in /lambdas/library-ingest

Updates the requirements on [boto3](https://github.com/boto/boto3) to permit the latest version.
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.43.46...1.43.51)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.43.51
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump the api group with 7 updates

Bumps Microsoft.AspNetCore.Authentication.JwtBearer from 8.0.28 to 8.0.29
Bumps Microsoft.EntityFrameworkCore from 8.0.28 to 8.0.29
Bumps Microsoft.EntityFrameworkCore.Design from 8.0.28 to 8.0.29
Bumps Microsoft.EntityFrameworkCore.InMemory from 8.0.28 to 8.0.29
Bumps Microsoft.EntityFrameworkCore.Sqlite from 8.0.28 to 8.0.29
Bumps Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore from 8.0.28 to 8.0.29
Bumps Microsoft.NET.Test.Sdk from 18.7.0 to 18.8.1

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Authentication.JwtBearer
  dependency-version: 8.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: api
- dependency-name: Microsoft.EntityFrameworkCore
  dependency-version: 8.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: api
- dependency-name: Microsoft.EntityFrameworkCore.Design
  dependency-version: 8.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: api
- dependency-name: Microsoft.EntityFrameworkCore.InMemory
  dependency-version: 8.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: api
- dependency-name: Microsoft.EntityFrameworkCore.Sqlite
  dependency-version: 8.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: api
- dependency-name: Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
  dependency-version: 8.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: api
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.8.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: api
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump NSubstitute from 5.3.0 to 6.0.0

---
updated-dependencies:
- dependency-name: NSubstitute
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 15:51:33 -04:00
Adam Moussa
c19c7fda72
fix(infra): send proposals from seahaven.com domain identity (primary SES domain) (#230)
Switch the API Lambda's SES sender from the email identity proposals@seahavenind.com
to proposals@seahaven.com under the seahaven.com DOMAIN identity — the org's primary
sending domain for all workload stacks. The domain identity is account-shared and
managed out-of-band in seahaven-prod (Easy-DKIM verified in the seahaven.com Route53
zone; production-access request submitted), so this stack references its ARN instead
of creating an EmailIdentity (avoids per-stack duplication + cross-account DNS at
deploy). Send scoped to identity/seahaven.com with a required ses:FromAddress condition.
GPT-4.1 cross-review APPROVE. Drops the unused aws-ses import.

Follow-up: codify the seahaven.com identity in the seahaven-prod account baseline.
2026-07-15 22:54:10 +00:00
Adam Moussa
590f0c075c
fix(infra): grant KB role rds:DescribeDBClusters (prod deploy blocker) (#229)
The seahaven-prod deploy failed at CreateKnowledgeBase: the Bedrock KB execution
role (proposal-system-kb-role) was denied rds:DescribeDBClusters, which Bedrock
calls to validate the Aurora pgvector store config. Add it. rds:DescribeDBClusters
does NOT support resource-level scoping (account/region list action) so it must be
Resource:*; the role's sensitive actions (rds-data:*, s3, InvokeModel, secret) stay
tightly scoped. GPT-4.1 cross-review APPROVE (caught the Resource:* requirement).
2026-07-15 15:54:14 -04:00
Adam Moussa
0c5b294ffc
fix(infra): Aurora engine 15.4 -> 15.17 (15.4 retired by RDS, deploy failed) (#228)
First prod deploy failed: RDS returned 'Cannot find version 15.4 for aurora-postgresql'
(minor version retired). Bump to latest available 15.x (15.17); stays on major 15 for
pgvector / ADR 0001. Clean create — the failed stack rolled back, no cluster persisted.
2026-07-15 15:01:50 -04:00
Adam Moussa
0f9d27fbf0
chore(infra): prep proposal-system for seahaven-prod deployment (#227)
* chore(infra): retarget prod to seahaven-prod account + OIDC deploy-role artifacts

Retarget the CDK prod env from mgmt (328440206208, now frozen for workloads) to the
dedicated seahaven-prod workload account (011934824531). proposal-system is the org's
first prod tenant. Hard-block env=staging (still targets frozen mgmt) in resolveConfig
until it is retargeted to seahaven-dev (710827005802). Add a WARN-only out-of-pipeline
deploy guard in bin/app.ts.

Add infra/deploy-role/: OIDC trust policy (sub scoped to
Sea-Haven-Industries/proposal-system:ref:refs/heads/main), least-privilege permissions
policy (AssumeRole on the verified cdk-hnb659fds bootstrap roles, deterministic site
bucket, account-scoped CloudFront invalidation), and an idempotent creation script.
Verified against live prod: bootstrap qualifier hnb659fds v32, OIDC provider present.
Passed GPT-4.1 cross-review (APPROVE) and workflow red-team (CLEAN). Role NOT yet created
— gated on /sh-security-review + the deploy go-ahead.

Docs: README + CLAUDE.md reflect the prod account and pipeline-only deploy.

* chore(infra): region-bound deploy-role DescribeStacks to us-east-1 (sh-security-review IAM-L2)

* feat(infra): Aurora prod backup retention 14d + window; prod-only CDK context

Bump Aurora automated-backup (PITR) retention 7->14d and set a preferred backup
window for the prod tenant. Dedicated AWS Backup vault + cross-account restore
test is a tracked follow-up (no org central-backup design exists yet). Prune the
stale mgmt-account AZ context; prod (011934824531) is the only deploy target.
2026-07-15 14:44:35 -04:00
dependabot[bot]
6a43d571cb
build(deps-dev): bump aws-cdk in /infra in the infra group
Bumps the infra group in /infra with 1 update: [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk).


Updates `aws-cdk` from 2.1129.0 to 2.1130.0
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1130.0/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1130.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: infra
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-11 04:32:54 +00:00
6692f856bc
fix(infra): run CDK app via tsx to support TypeScript 7
TypeScript 7.0.2 (the native-port build) no longer exposes the internal
compiler API (ts.sys) that ts-node@10.9.2 depends on, so
`npx ts-node bin/app.ts` fails during `cdk synth` with
"Cannot read properties of undefined (reading 'fileExists')".

Switch the CDK app runner to tsx (esbuild-based, version-agnostic — it
does not consume the typescript package's programmatic API), and pin tsx
as an infra devDependency. Verified `cdk synth` succeeds locally with
typescript 7.0.2 installed.
2026-07-08 16:51:54 -04:00
dd058f7170
build(deps): combine open Dependabot updates into one PR
Consolidates the 15 open Dependabot PRs (#195–#209) into a single branch.

Python (lambdas):
- boto3 -> >=1.43.43,<2.0 in suggestions, library-ingest, pdf-generate,
  pdf-extract, aurora-pgvector-init (#203, #205, #206, #208, #204)
- tests: pytest >=9.1.1 (#198, major), pytest-mock >=3.15.1 (#197),
  moto >=5.2.2 (#200), httpx >=0.28.1 (#195)

npm:
- infra: @types/node ^25.9.5 (#196), typescript ~7.0.2 (#199, major)
- web: vitest ^4.1.10 (#202), typescript ~7.0.2 (#207, major)
- shared/api-contracts: typescript ~7.0.2 (#201, major)

Ruby (mobile):
- bundler group: cocoapods 1.17.0, fastlane 2.237.0 + transitive (#209)

Note: TypeScript 5.7 -> 7.0.2 and pytest 8 -> 9.1.1 are major bumps;
relying on CI to validate.
2026-07-08 16:46:43 -04:00
dependabot[bot]
59a4c1d2fa
build(deps): bump the infra group in /infra with 3 updates (#186) 2026-07-04 14:11:31 -04:00
dependabot[bot]
c558520a79
build(deps-dev): bump aws-cdk in /infra in the infra group (#169)
Bumps the infra group in /infra with 1 update: [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk).


Updates `aws-cdk` from 2.1128.0 to 2.1128.1
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1128.1/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1128.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: infra
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 20:07:17 +00:00
dependabot[bot]
c83570c07c
build(deps-dev): bump @types/node from 22.19.19 to 25.9.3 in /infra (#141)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.19 to 25.9.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.9.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:43:46 -04:00
dependabot[bot]
43c46d1a6c
build(deps): bump the infra group across 1 directory with 2 updates (#140)
Bumps the infra group with 2 updates in the /infra directory: [aws-cdk-lib](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk-lib) and [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk).


Updates `aws-cdk-lib` from 2.257.0 to 2.260.0
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.alpha.md)
- [Commits](https://github.com/aws/aws-cdk/commits/v2.260.0/packages/aws-cdk-lib)

Updates `aws-cdk` from 2.1126.0 to 2.1128.0
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1128.0/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1128.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: infra
- dependency-name: aws-cdk-lib
  dependency-version: 2.260.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: infra
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 14:27:21 -04:00
Adam Moussa
405f4bbfab
fix(infra): distinct Aurora construct ID; group + unpause Dependabot (#129)
* fix(infra): give the Aurora cluster a distinct construct ID

The RDS->Aurora swap (PR3 #125) kept construct ID 'Database', so CloudFormation
saw the same logical ID change from AWS::RDS::DBInstance to AWS::RDS::DBCluster and
rejected the changeset ('Update of resource type is not permitted'). Renaming the
construct to 'AuroraCluster' gives the cluster a new logical ID, so CFN does a clean
replace (remove old DBInstance, add new DBCluster) instead of an in-place type change.

* chore(deps): group Dependabot minor/patch updates per ecosystem

Add a group to each update entry so weekly minor/patch bumps land as a
single PR per ecosystem/directory instead of one PR per package. Major
bumps remain individual PRs so breaking changes get isolated review.

Grouping takes effect when open-pull-requests-limit is raised above 0
(version updates are still paused during development, #109).

* chore(deps): unpause Dependabot version updates

Raise open-pull-requests-limit from 0 to 10 across all ecosystems,
re-enabling weekly version updates (paused during development, #109).
With grouping now in place, minor/patch bumps land as one grouped PR
per ecosystem; the limit caps outstanding major-bump PRs.
2026-06-18 13:57:15 -04:00
Adam Moussa
1fca0fa978
feat: proposal delivery — email customers the PDF on Mark as Sent (#126)
* feat: proposal delivery — email customers the PDF on "Mark as Sent"

Makes the system's namesake feature real: marking a proposal Sent now emails the
customer an expiring link to the branded PDF, and customers are managed (with
contact emails) instead of hardcoded. v1 PR4.

API:
- Customer.ContactEmail + migration; Customer list/update endpoints. Search stays
  additive at GET /api/customers?query= (frozen-mobile + web compat); new paginated
  list at GET /api/customers/list (admin).
- IEmailService (SesEmailService v2 / DevEmailService, dev-gated). MarkSentAsync
  resolves the customer's email, presigns the latest PDF (7d), and sends via SES.
  Email/presign failures are caught + audited and NEVER roll back the Sent transition.
- Startup EF migration guarded by a Postgres advisory lock (concurrency-safe).

Infra:
- SES email identity (proposals@seahavenind.com); least-privilege ses:SendEmail/
  SendRawEmail scoped to the identity ARN + ses:FromAddress condition; SES_FROM_ADDRESS
  env. SES starts in sandbox — production access needed for unverified recipients.

Web:
- Customer management page (/admin/customers): list / create / edit incl. contact email.
- New-proposal form searches real customers (free-solo) instead of a hardcoded value.
- Mark-as-Sent dialog notes the PDF will be emailed to the customer.

GPT-4.1 cross-review (SES IAM): no BLOCK (ses:FromAddress condition applied).
Verified: api build + 121 tests; web tsc + 26 tests; infra tsc; ruff clean.

* Potential fix for pull request finding 'CodeQL / Exposure of private information'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for pull request finding 'CodeQL / Exposure of private information'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for pull request finding 'CodeQL / Exposure of private information'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-06-18 12:40:55 -04:00
Adam Moussa
aff38a11ae
feat(infra): migrate Bedrock KB vector store to Aurora pgvector (#125)
Some checks failed
Deploy / Deploy to AWS (push) Has been cancelled
Replaces OpenSearch Serverless with Aurora PostgreSQL Serverless v2 + pgvector as
the Bedrock Knowledge Base vector store (v1 PR3). Bedrock KB requires Aurora SSv2
(RDS Data API), not a plain RDS instance — so the DB engine moves to Aurora.

- foundation: rds.DatabaseInstance (PG15) -> rds.DatabaseCluster Aurora SSv2
  (0.5-4 ACU, enableDataApi). RDS alarms: free-storage -> freeable-memory.
- compute: delete all AOSS (collection, policies, VPC endpoint, index-creator);
  add bedrock_user secret + KB role (scoped rds-data + secret read); repoint
  CfnKnowledgeBase to RDS storage (bedrock_integration.bedrock_kb, vector(1024)).
- lambdas: oss-index-creator -> aurora-pgvector-init (bootstrap schema/table/
  indexes/role via RDS Data API; transient-error retry; password guard).
- ADR 0001 documents the decision.

Eliminates the ~$175-350/mo AOSS OCU floor. NAT kept (egress still needed).
GPT-4.1 cross-review: no BLOCK (FIX applied). tsc clean; foundation synth shows
Aurora cluster with Data API enabled; 23 pytest pass.
2026-06-12 18:44:42 -04:00
Adam Moussa
bbd185b280
feat(infra): parameterize stacks for multi-env (prod/staging) (#123)
Adds an env config layer resolved from CDK context (`-c env=staging`, default prod)
and threads it through all three stacks so a fully isolated staging environment can
be deployed in the same AWS account.

prod is byte-identical: the prod config reproduces the deployed values exactly and
stackSuffix='' keeps every construct ID, stack name, and physical resource name
unchanged. Verified via synth — prod foundation keeps proposal-system-db /
-uploads / db-credentials / -auth / seahaven; staging suffixes all of them.

- config.ts: EnvConfig (prod + staging, same account) + resolveConfig
- app.ts: env-aware stack naming + config passthrough
- foundation/compute/frontend: ~40 physical names suffixed with config.stackSuffix;
  CORS, Cognito domain/callbacks, alarms email from config; RETAIN / deletionProtection
  gated on config.retainData so staging can be torn down
- cdk.json: register `env` context (default prod)
- post-deploy.sh: STACK_SUFFIX for dynamic stack-name lookup (default prod)

Note: automated staging CI deploy needs a one-line `cdk-context` input added to the
org reusable cd-cdk.yaml (companion change). prod deploy is unaffected (default prod).
2026-06-12 18:04:53 -04:00
Adam Moussa
3d050bcf8e
fix(lambdas): SigV4-sign internal API calls and bundle Lambda dependencies (#122)
Some checks are pending
Deploy / Deploy to AWS (push) Waiting to run
The .NET API Lambda Function URL uses authType=AWS_IAM, but the four workload
Lambdas (suggestions, pdf-extract, pdf-generate, library-ingest) sent unsigned
requests with only X-Internal-Api-Key -> every internal call 403s. They also
used bare fromAsset() with no pip bundling -> ImportError at cold start. Both
made the SQS->Lambda->API pipeline non-functional when deployed (v1 pre-flight).

- Add _sign_request_headers (botocore SigV4Auth, service "lambda"); serialize the
  JSON body once and send via httpx content= so the signed payload hash matches
  the bytes sent; preserve X-Internal-Api-Key for the app-layer check. Sign per
  retry attempt to avoid SigV4 timestamp expiry on slow retries.
- Add CDK pip bundling (--platform manylinux2014_aarch64 --only-binary=:all:) to
  all four Lambdas so ARM64 wheels (reportlab, Pillow, pdfplumber) ship.
- Converge _retry_request across all four (fixes possibly-undefined return in
  pdf-extract/pdf-generate).
- Add SigV4 signing regression tests.

Verified: ruff clean, infra tsc clean, aarch64 wheels resolve for all four,
23 pytest pass. GPT-4.1 cross-family review: no BLOCK (FIX + NIT applied).
2026-06-12 17:13:08 -04:00
Adam Moussa
a342465036
fix(deps): pin aws-cdk-lib to ==2.257.0 (#90)
Some checks are pending
Deploy / Deploy to AWS (push) Waiting to run
* fix(deps): re-pin aws-cdk-lib to ==2.253.1

* fix(deps): pin aws-cdk-lib to 2.257.0 (exact)
2026-06-05 13:20:09 -04:00
dependabot[bot]
8691c8a205
build(deps-dev): bump aws-cdk from 2.1124.1 to 2.1125.0 in /infra (#71)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1124.1 to 2.1125.0.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1125.0/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1125.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 04:33:26 +00:00
Adam Moussa
ae3ad9d823 fix: CORS, JWT auth, useBlocker crash, and auto-migration for production deploy
Some checks failed
Deploy / Deploy to AWS (push) Has been cancelled
- Add CloudFront origin to API Gateway CORS preflight and .NET CORS policy
- Replace HttpMethod.ANY with explicit methods so OPTIONS preflight doesn't
  hit the JWT authorizer (was causing 403 on all API calls)
- Return Cognito ID token instead of access token from auth callback
  (access tokens lack the aud claim required by API Gateway JWT authorizer)
- Add CloudFront callback URI to allowed redirect list
- Remove identity_provider=Google from login URL to show Cognito hosted UI
- Replace useBlocker (requires data router) with state-based navigation guard
  to fix crash on AdminWorkspace with BrowserRouter
- Add auto-migration on Lambda cold start
- Enable Swagger in production
2026-05-27 19:20:29 -04:00
Adam Moussa
8da87e9301 fix(infra): scope Bedrock model ARN, AOSS permissions, require deploy approval (INF-M1, M2, M9)
INF-M1: Replace wildcard anthropic.claude-* foundation-model ARN with the
specific cross-region inference profile ARN and its backing foundation model.
Both suggestions and pdf-extract Lambdas use us.anthropic.claude-sonnet-4-5-20250929-v1:0.

INF-M2: Replace aoss:* data access policy permissions with scoped actions.
KB role gets DescribeCollectionItems/CreateCollectionItems/UpdateCollectionItems
on collection and DescribeIndex/ReadDocument/WriteDocument on indexes.
Index creator gets CreateIndex/DescribeIndex/WriteDocument plus collection describe/create.

INF-M9: Change --require-approval never to --require-approval broadening in
infra/package.json deploy script so IAM/security changes require manual
confirmation during local development.
2026-05-27 18:18:44 -04:00
Adam Moussa
fcdc46c136 fix: infra medium findings (INF-M5, INF-M8)
INF-M5: Add enforceSSL: true to all S3 buckets (uploads, generated,
library, web site) to require HTTPS-only access via bucket policy.

INF-M8: Pin all reusable GitHub Actions workflow references from @main
to commit SHA c040bfaa for supply chain security.
2026-05-27 18:18:44 -04:00
Adam Moussa
a74ac4945f fix: LAM-C1/INF-H1 require IAM auth on Function URL, INF-H3 restrict OpenSearch to VPC
LAM-C1/INF-H1: Change Function URL authType from NONE to AWS_IAM and
grant invokeUrl permission to all four caller Lambdas (suggestions,
pdf-extract, pdf-generate, library-ingest). Lambda HTTP clients will
need SigV4 signing as a follow-up.

INF-H3: Create OpenSearch Serverless VPC endpoint in private subnets
and update network policy from AllowFromPublic to SourceVPCEs, removing
public internet access to the vector search collection.
2026-05-27 18:18:44 -04:00
Adam Moussa
4f1271eb50 audit: fix all Critical and High security/reliability issues across monorepo
6-domain audit (API, web, mobile, lambdas, infra, QA) with fixes:

API security: scope internal API key middleware to allowed paths only,
return 401 on invalid key instead of falling through, remove unvalidated
JWT code path, sanitize error messages, add UpdateProposal validator,
remove status field from UpdateProposalRequest to prevent over-posting,
log swallowed exceptions in ProposalService.

Infrastructure: enforce SSL on all S3 buckets, encrypt SQS queues,
enable optional MFA on Cognito, add API Gateway access logging.

Lambdas: fix _retry_request undefined variable across all 4 Lambdas,
re-raise exceptions in pdf-extract/pdf-generate instead of swallowing,
add idempotency guard to suggestions Lambda.

Web: add ErrorBoundary, add auth loading state to ProtectedRoute,
add mutation error toasts in AdminWorkspace, fix dead Cognito link.

Mobile: add mutex to offline queue processing, distinguish permanent
vs retryable failures, register all screens for both roles, log sync
errors.

Swagger/OpenAPI: add Swashbuckle with JWT bearer security definition,
add ProducesResponseType attributes to key endpoints.

Includes AUDIT-REPORT.md with complete findings and CLAUDE.md project
instructions.
2026-05-27 18:18:44 -04:00
dependabot[bot]
7b4481b194
Bump aws-cdk-lib from 2.253.1 to 2.257.0 in /infra (#58)
Bumps [aws-cdk-lib](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk-lib) from 2.253.1 to 2.257.0.
- [Release notes](https://github.com/aws/aws-cdk/releases)
- [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.alpha.md)
- [Commits](https://github.com/aws/aws-cdk/commits/v2.257.0/packages/aws-cdk-lib)

---
updated-dependencies:
- dependency-name: aws-cdk-lib
  dependency-version: 2.257.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 04:34:11 +00:00
dependabot[bot]
91b9386293
Bump aws-cdk from 2.1122.0 to 2.1124.1 in /infra (#63)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1122.0 to 2.1124.1.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1124.1/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1124.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 04:34:07 +00:00
Adam Moussa
9d856a9619
Phase 3 audit fixes: FIX-01–47, accessibility NITs, code quality NITs [skip deploy]
Some checks failed
Deploy / Deploy to AWS (push) Has been cancelled
## Summary
Implements Phase 3 of the AUDIT-2026-05-20 findings:
- 29 FIX-severity items across API, web, infra, and lambdas
- 7 accessibility NITs (aria-labels, document titles)
- 4 code quality NITs (deduplication, constants extraction)

Key changes:
- API: N+1 fix, pagination clamping, idempotent transitions, upload confirm endpoint, revision TotalBidAmount carry-forward
- Web: confirmation dialogs, currency formatting, error states, date range filters, document titles
- Infra: S3 CORS lockdown, API Gateway throttling, AOSS network policy fix, CI concurrency
- Lambdas: skip empty suggestions, remove status side-effect
- Scripts: post-deploy health check

## Test plan
- [x] tsc --noEmit (web + infra)
- [x] dotnet build (api)
- [x] ruff check + format (lambdas)
- [x] Cross-review via orchestrator (no blockers)

[skip deploy]
2026-05-20 19:38:36 -04:00
Adam Moussa
99e0c16505 Merge main into feature/fix-phase-2, resolve infra conflicts
Keep both Phase 1 (JWT authorizer, webClientId/mobileClientId props) and
Phase 2 (alarmTopic, CloudWatch alarms) changes in CDK stacks.
2026-05-20 19:09:35 -04:00
Adam Moussa
184bc1da7e Fix Phase 2 audit findings: reliability, UX, and operational monitoring
BLOCK-10: Add CloudWatch alarms (DLQ, Lambda errors, RDS, API 5xx) with SNS email
BLOCK-11: Remove sync-over-async deadlock in CurrentUserService
BLOCK-12: Add AppDelegate OAuth URL callback handler for mobile
BLOCK-13: Wire mobile 401 interceptor to dispatch Redux logout
BLOCK-14: Fix JWT base64 padding crash and SysAdmin role detection
BLOCK-15: Reset pagination to page 1 on filter change
BLOCK-16: Add unsaved-changes guard (beforeunload + useBlocker) to AdminWorkspace
FIX-08: Add BulkUpdateLineItems FluentValidation validator
FIX-13: Display auth errors on LoginPage
FIX-25: Add token refresh with retry queue to mobile API client
FIX-44: Add httpx retry logic to all Lambda handlers
FIX-42/43: Align docker-compose PG version (15) and DB name (proposals) with RDS
2026-05-20 19:07:49 -04:00
Adam Moussa
091c5fcb44
Fix Phase 1 security and data integrity audit findings (#49)
BLOCK-01: Add API Gateway JWT authorizer with Cognito, route internal
Lambda calls through Function URL to bypass gateway auth
BLOCK-02/03: Prevent proposal number race condition with pg_advisory_xact_lock
and filter revision numbers from max-number query
BLOCK-04: Restrict VendorProposals and GeneratedPdfs to admins/sysadmins
BLOCK-05: Sum all vendor costs instead of overwriting with single vendor
BLOCK-06: Enable ValidateAudience on JWT, add Auth env vars to API Lambda
BLOCK-07: Validate ID token signature in AuthController via OIDC discovery
BLOCK-08: Use batchItemFailures in all Lambda SQS handlers
BLOCK-09: Increase SQS visibility timeout from 180s to 720s
FIX-10: Scope dispatcher queries to own proposals (IDOR fix)
2026-05-20 18:51:31 -04:00
Adam Moussa
da00d27049 Add email/password login, fix Cognito config, enable mobile auto-deploy
Apple review requires a test account login path that doesn't depend on
Google OAuth. Add amazon-cognito-identity-js for direct SRP auth with a
native email/password form on the login screen. Fill in the empty Cognito
client ID and pool ID, fix the Cognito domain prefix, and align CDK
callback URLs with the app's actual URL scheme. Enable push-triggered
mobile deploys, add CDK outputs for client IDs, fix stale README
references, and add mobile/README.md.
2026-05-20 11:36:51 -04:00
Adam Moussa
28475d8529 Revert suggestions log group from foundation stack
The log group already exists — created by the compute stack's
logRetention setting on the suggestions Lambda. Adding it to the
foundation stack caused a duplicate resource error on deploy.
2026-05-18 18:32:04 -04:00
Adam Moussa
fdaaf5ed4a Fix compliance violations: Lambda defaults, CI node-version, dead code
oss-index-creator Lambda was missing functionName, arm64 architecture,
and explicit log retention — all required by the engineering handbook.
CI workflow was not passing node-version to reusable workflows, risking
drift. Removed unused _api_request helper from all four main Lambdas.
Added missing suggestions log group to foundation stack.
2026-05-18 18:28:31 -04:00
Adam Moussa
7df81b4427 Fix AOSS dependency ordering: pre-create vector index via Custom Resource
Some checks are pending
Deploy / Deploy to AWS (push) Waiting to run
The Bedrock Knowledge Base creation was failing with 403/404 because
the OpenSearch Serverless data access policy hadn't propagated before
the KB tried to connect. Adds a CDK Custom Resource (using opensearch-py)
that creates the vector index with retry logic, ensuring the full
dependency chain: Collection → DataAccessPolicy → Index → KnowledgeBase.
2026-05-18 17:55:03 -04:00
Adam Moussa
ceefae2850
Implement Phases 2-5: Frontend, AI/RAG, PDF Generation (#22)
* Fix NuGet versions and add InitialCreate EF Core migration

- Update AWSSDK.SQS and AWSSDK.SecretsManager to 3.7.500.0 (actual available versions)
- Update AWSSDK.Extensions.NETCore.Setup to 3.7.400
- Generate InitialCreate migration for PostgreSQL (all 8 entities)
- Build verified: 0 errors, 0 warnings

* Implement Dispatcher Frontend (Phase 2)

React 19 + MUI v7 + TypeScript + Vite SPA matching SHOC patterns:
Redux Toolkit (auth/ui slices), TanStack React Query, axios interceptors,
react-toastify, Cognito OAuth PKCE login flow, paginated proposal list,
new proposal form with customer autocomplete and vendor PDF upload,
read-only proposal detail with status stepper timeline.

* Add AuthController for Cognito code exchange and .env.example

Backend endpoint POST /api/auth/callback exchanges the OAuth
authorization code with Cognito's token endpoint, auto-provisions
the user in the DB, and returns the access token to the frontend.

* Implement Admin Frontend Experience (Phase 3)

Three-panel admin workspace: left reference panel (submission details,
vendor data), center editor (refined scope, inline line item table with
reorder/add/remove/pricing), right similar proposals panel (KB results
with pull-to-editor). Admin dashboard with stats cards and proposal
queue table. Approval flow with confirmation dialog, mark-as-sent,
and create-revision actions. Role-based sidebar navigation.

* Implement backend dev mode, internal API auth, and service layer enhancements

- Add dev-login endpoint with local JWT signing for local development
- Add InternalApiKeyMiddleware with timing-safe comparison for Lambda-to-API auth
- Add DevS3Service and NoOpJobPublisher for running without AWS services
- Implement CurrentUserService cascading user resolution (ID → sub → email → create)
- Add async ResolveAsync() to avoid synchronous DB calls in request pipeline
- Add /proposals/stats endpoint for efficient server-side status counts
- Guard status transitions: only allow Draft → InReview via update endpoint
- Add vendor proposals, generated PDFs, and similar proposals controllers
- Add ISimilarProposalService and SimilarProposalService
- Add [Authorize] to AddSimilarReference endpoint

* Implement Lambda functions for PDF processing, suggestions, and library ingest

- pdf-extract: Parse vendor PDFs with pdfplumber, fallback to Claude multimodal
- pdf-generate: Generate branded proposal PDFs with reportlab Platypus
- library-ingest: Format approved proposals as markdown and sync to Bedrock KB
- suggestions: Query KB for similar proposals, generate line items via Claude
- All Lambdas use internal API key auth and cold-start secret caching
- Fix pdf_path unbound variable in pdf-extract error handling

* Add Bedrock Knowledge Base, OpenSearch Serverless, and SQS message filtering

- Provision OpenSearch Serverless collection for vector search
- Create Bedrock Knowledge Base with Titan embedding model
- Configure S3 data source with fixed-size chunking (512 tokens, 20% overlap)
- Add suggestions Lambda with SQS event source filtering
- Scope bedrock:InvokeModel IAM to specific model ARN patterns
- Add internal API key secret in Secrets Manager
- Add log retention (2 months) to all Lambda functions
- Add docker-compose.yml for local PostgreSQL

* Apply SHOC design system styling across frontend

- Rewrite theme with SHOC palette (#0c4f6f primary, Nunito font, 4px radius)
- Add global CSS with Google Fonts import for Nunito
- Redesign Topbar with avatar initials, role subtitle, gradient header
- Redesign Sidebar with 220px width, section headers, active state border
- Restyle LoginPage with SHOC branded card and dev-mode role selector
- Update AdminDashboard KPI cards to centered SHOC style
- Add devLogin API method for local development auth flow

* Fix frontend navigation bugs, differentiate Dashboard from Proposals list

- Fix double nav selection by adding isNavActive() with ALL_NAV_PATHS set
- Fix /admin/users routing to placeholder instead of redirect to /
- Fix ProposalDetailPage Back button navigating to / instead of /proposals
- Differentiate Dashboard (KPI cards + recent 5) from ProposalListPage (full paginated table)
- Dashboard now uses dedicated /proposals/stats endpoint for accurate counts
- Fix adminApi.getPdf dead code (axios rejects before status check)
- Wire up PDF generation button in AdminWorkspace
- Adjust layout: 220px drawer, 10px content padding, 64px toolbar height

* Add appsettings.Development.json to gitignore

Prevent dev-only signing keys and connection strings from being committed.

* Fix CI failures: unused Python imports and CDK synth asset path

CDK synth job needs the .NET API published first so the Lambda asset
path exists. Python lint had 3 unused imports in pdf-generate.

* Apply ruff formatting to all Lambda Python files
2026-05-17 13:06:23 -04:00
0b055b3ad9 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