Commit graph

10 commits

Author SHA1 Message Date
Adam Moussa
4629f7a21a
ci(web): Phase 5 — Prettier check + Playwright smoke, org frontend workflow (#225)
* feat(web): adopt SHOC design system and shell layout (ADR 0003)

Port shoc-frontend-new dev's design system with its CSS-variable
single-token-source mechanism:

- src/styles/theme.css: SHOC token file ported verbatim (Montserrat/
  DM Sans/JetBrains Mono, primary #1c75bc, navy #262262, full radius/
  shadow/sidebar/header token layers); fonts self-hosted via @fontsource
- src/lib/theme/{css-vars,mui-theme}.ts: getCssVar -> createTheme
  adapter mirroring SHOC's mui-theme.ts (palette, typography, shadows
  tuple, component overrides; MUI v9 slot renames expressed as class
  selectors); theme.ts is now a re-export
- Shell: SHOC composition (sidebar column + sticky gradient topbar +
  scrolling main); sidebar 244px/76px collapse with brand header row,
  grouped nav, SHOC active treatment (white card + 3px accent bar);
  topbar 100-degree gradient, surface hamburger, gradient avatar pill
- Brand: SeahavenMark + BrandLockup ported (Tailwind re-expressed as
  sx; wordmark subtitle localized to PROPOSAL SYSTEM)
- Login: SHOC auth-card treatment (centered 384px card on #f9fafb)
- Old "Sea Haven Ops" Inter/#2563EB theme and Nunito remnants removed;
  remaining hardcoded hexes replaced with tokens; lucide-react for
  shell/nav icons per SHOC convention

Verify: tsc clean, 26/26 vitest, vite build OK; Playwright screenshots
pixel-sampled against the extracted SHOC spec (all hard values exact,
no blocking deviations).

* feat(contracts): adopt shared api-contracts in web, add zod schemas and ProblemDetails codes

Closes WEB-M5 (web hand-duplicated wire types, standing drift risk):

- shared/api-contracts: rewritten as the authoritative superset of the
  .NET DTOs (ProposalListItem/ProposalDetail with poNumber and
  submittedByName, line item requests, customers, pricing library,
  dashboard, audit, sites, auth, presigned upload, ApiProblem); stale
  Proposal/UpdateLineItemsRequest shapes removed
- shared/api-contracts/src/schemas.ts: zod runtime schemas coupled to
  every wire type via `satisfies z.ZodType<T>` (schema/type drift is now
  a compile error); separate entrypoint so type-only consumers (mobile)
  never pull zod
- web: imports @proposal-system/api-contracts (file: dep + tsconfig
  paths + vite preserveSymlinks); all 7 lib/api modules re-export shared
  types so page imports stay stable; enum unions tightened
  (PricingLibraryPage form state now ServiceCategory-typed)
- fix(web): customer create/update sent a singular `address` field the
  API silently dropped (contract is addresses: string[], CustomerDtos.cs)
  - addresses now round-trip, extra addresses preserved on edit
- api: ProblemDetails responses carry a machine-readable top-level
  `code` (SHOC error-code vocabulary): ValidationFailed,
  InvalidStateTransition, NotFound, Unauthorized, InternalError; new
  BusinessRuleException(code, message) maps to 422 with its code;
  GlobalExceptionHandlerTests cover the full mapping (wire contract)

Cross-checked .NET DTOs vs TS types vs zod schemas with the
orchestrator scanner (Gemini): core domains consistent; internal-only
DTOs (FileDtos vendor/lambda surface, SimilarProposalDtos, UserDtos
admin surface) intentionally uncovered.

Verify: dotnet 166/166, web tsc + vitest 26/26 + build, mobile tsc,
shared tsc all green.

* feat(web): domain-layer conventions doc + react-hook-form deps (Phase 4 prep)

* feat(web): scaffold domain module layer (proposals, lineItems, customers, pricingLibrary, admin, sites)

Additive-only: pages still use lib/api/* and constants/queryKeys.ts until
the page-migration agents run. Each domain ships api.ts (HTTP moved from
lib/api), types.ts (contract re-exports + view types), schemas.ts (contract
schema re-exports + form schemas with toRequest mappers), and use-cases.ts
(TanStack Query v5 hooks + hierarchical query keys, mirroring current page
invalidations and toast-on-error behavior).

Adds an explicit vite/vitest alias for the
@proposal-system/api-contracts/schemas subpath (package has no exports map)
plus a schema/mapper smoke test suite.

* refactor(web): proposal pages on domain layer, proposal form on react-hook-form

* refactor(web): admin workspace on domain layer

* refactor(web): customer management on domain layer + react-hook-form

* refactor(web): pricing library on domain layer + react-hook-form

* refactor(web): dashboards on domain layer

* test(web): domain use-case hook coverage

* refactor(web): finish domain-layer integration — migrate straggler components, delete legacy api modules

- SimilarProposalsPanel -> useSimilarProposals (domain/admin); inline
  SimilarProposal type replaced by domain/admin/types (identical shape);
  query key joins the admin hierarchical key space
- LineItemEditor type imports -> domain/lineItems/types
- Delete now-orphaned lib/api/{proposals,lineItems,customers,
  pricingLibrary,admin,sites}.ts, constants/queryKeys.ts,
  hooks/usePaginatedList.ts (lib/api/client.ts + auth.ts stay per
  domain README rule 5)

Verify: tsc clean, vitest 52/52, build OK, Playwright smoke of the
authed shell renders on domain hooks.

* fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup)

Correctness:
- State-transition mutations now invalidate every cached view via
  invalidateProposalViews (detail + line items + lists + stats + admin
  dashboard) — approving no longer leaves a stale queue for the
  5-minute staleTime
- Presigned S3 PUT moved to proposals/api.ts with res.ok check — a
  rejected upload is no longer confirmed as uploaded
- toCustomerRequest always sends contactEmail ('' clears); API create
  path normalizes empty->null to match the update path — customer
  emails can now be cleared from the UI
- Shared Number-based numeric form fields (domain/shared/formFields):
  '12abc' no longer silently coerces to 12 in the pricing library
- Customer create/update invalidate customersKeys.all so cached search
  autocompletes see new customers
- AdminWorkspace clears dirty right after a successful implicit save,
  before approve — no false unsaved-changes prompt when approve fails
- ProposalFormPage submit gate and missing-fields caption derive from
  ONE checks list (missing customer is now listed)
- Empty states gated on !err in ProposalListPage/AdminDashboard — no
  contradictory error + 'no proposals' UI
- VendorDataPanel migrated to useVendorProposals (kills the divergent
  ['vendorProposals', id] cache key and the inline apiClient query)
- useCustomerList/usePricingLibraryList get keepPreviousData — no
  TablePagination out-of-range flash on page change

Cleanup:
- Dead speculative hooks removed (useCreate/BulkUpdate/DeleteLineItem,
  useUpdateProposal, useProposalHistory/Audit, lineItemRowFormSchema,
  toUpdateLineItemEntry); tests moved to the live save path
  (useSaveProposalWorkspace)
- Shared useDebouncedValue hook replaces 4 drifted inline debounce
  copies (one leaked its timer on unmount, two hardcoded 300ms);
  DEBOUNCE_AUTOCOMPLETE=300 named
- Fix: WEB-H5 / WEB-H6 finding-ID markers restored at the relocated
  onError handlers (CLAUDE.md traceability)
- shared/api-contracts gains an exports map; /schemas resolver alias
  deduplicated from 3 copies to the tsconfig paths mapping

Verify: tsc clean, vitest 51/51 (tests updated to pin the new
invalidation/mapper behavior + new '12abc' rejection test),
vite build OK, dotnet 166/166.

* refactor(web): fold Redux auth/ui slices into SHOC-shape auth context + storage module

Phase 4 tail of the SHOC-alignment plan. Matches SHOC's auth shape
(lib/auth storage module + providers/ context split) while keeping the
deliberate divergences:

- sessionStorage, not localStorage (WEB-C1 stands; SHOC's localStorage
  is on the SHOULD-NOT-ALIGN list)
- token acquisition stays in the auth pages (Cognito code exchange /
  dev-login) — the provider only owns session state
- 401 interceptor clears storage directly (WEB-M2 behavior preserved;
  full-page redirect resets provider state)

Sidebar open state moves to plain layout state in App passed down as
props (SHOC (protected)/_layout.tsx pattern), keeping localStorage
persistence. Drops @reduxjs/toolkit and react-redux.

Tests: authSlice tests replaced by authStorage + AuthProvider suites
(QA-C5 coverage preserved); client interceptor tests updated for the
storage-based 401 path. 59 vitest green, tsc clean, vite build OK.
Verified end-to-end headless: login redirect, seeded-session shell,
sidebar toggle persistence, logout, expired/malformed token handling,
RoleGuard bounce; recipe persisted as web/.claude/skills/verify.

* fix(web): harden auth session teardown per /sh-security-review findings

- AUTH-L1 (confirmed medium): logout() now clears the react-query cache —
  the singleton cache survived SPA logout, serving the previous
  principal's cached GETs to the next login in the same tab for up to
  staleTime with no server round-trip.
- AUTH-L3 (confirmed low): isTokenValid decodes base64url before atob —
  valid Cognito JWTs containing '-'/'_' in the payload segment were
  misclassified as expired (login lockout/loop; inherited from the old
  authSlice).
- AUTH-L2 (unverified, hardened anyway): 401 interceptor broadcasts
  AUTH_SESSION_CLEARED_EVENT so AuthProvider drops in-memory state
  synchronously, restoring the old Redux atomic-clear semantics.
- INJ-1 (unverified, hardened anyway): Authorization header only set
  when the stored token is a string.

Each fix pinned by a test; 63 vitest green, tsc clean.

* docs: web stack row reflects auth-context refactor (Redux removed, MUI v9)

* ci(web): Phase 5 — prettier check + Playwright smoke via org frontend workflow

Converts the web CI job from ci-typescript-cdk.yaml (typecheck only) to
ci-typescript-frontend.yaml: format:check, build (tsc -b included),
vitest, and a Playwright chromium smoke. Folds the standalone Web Tests
job into it (aggregator needs updated). Pure CI — no AWS secrets.

The smoke (e2e/smoke.spec.ts) drives dev-login → dashboard shell →
proposal list, plus the unauthenticated bounce, against a fully mocked
API (pathname-anchored route interception — a '**/api/**' glob would
swallow vite's /src/lib/api/* module URLs). Config mirrors SHOC's
playwright.config.ts (port 4173, chromium, dev-server webServer).

Prettier: singleQuote + printWidth 100 to match the existing codebase
style; lint intentionally not added (no ESLint config yet — run-lint
false, out of Phase 5 scope). rollback = revert this workflow file.

* style(web): prettier format pass (mechanical)

npx prettier --write . with the new .prettierrc (singleQuote,
printWidth 100). No functional changes — enforced by format:check in
CI from this PR on.
2026-07-14 01:02:20 +00:00
Adam Moussa
d40a794695
refactor(web): auth context + storage module replace Redux (SHOC shape) (#224)
* feat(web): adopt SHOC design system and shell layout (ADR 0003)

Port shoc-frontend-new dev's design system with its CSS-variable
single-token-source mechanism:

- src/styles/theme.css: SHOC token file ported verbatim (Montserrat/
  DM Sans/JetBrains Mono, primary #1c75bc, navy #262262, full radius/
  shadow/sidebar/header token layers); fonts self-hosted via @fontsource
- src/lib/theme/{css-vars,mui-theme}.ts: getCssVar -> createTheme
  adapter mirroring SHOC's mui-theme.ts (palette, typography, shadows
  tuple, component overrides; MUI v9 slot renames expressed as class
  selectors); theme.ts is now a re-export
- Shell: SHOC composition (sidebar column + sticky gradient topbar +
  scrolling main); sidebar 244px/76px collapse with brand header row,
  grouped nav, SHOC active treatment (white card + 3px accent bar);
  topbar 100-degree gradient, surface hamburger, gradient avatar pill
- Brand: SeahavenMark + BrandLockup ported (Tailwind re-expressed as
  sx; wordmark subtitle localized to PROPOSAL SYSTEM)
- Login: SHOC auth-card treatment (centered 384px card on #f9fafb)
- Old "Sea Haven Ops" Inter/#2563EB theme and Nunito remnants removed;
  remaining hardcoded hexes replaced with tokens; lucide-react for
  shell/nav icons per SHOC convention

Verify: tsc clean, 26/26 vitest, vite build OK; Playwright screenshots
pixel-sampled against the extracted SHOC spec (all hard values exact,
no blocking deviations).

* feat(contracts): adopt shared api-contracts in web, add zod schemas and ProblemDetails codes

Closes WEB-M5 (web hand-duplicated wire types, standing drift risk):

- shared/api-contracts: rewritten as the authoritative superset of the
  .NET DTOs (ProposalListItem/ProposalDetail with poNumber and
  submittedByName, line item requests, customers, pricing library,
  dashboard, audit, sites, auth, presigned upload, ApiProblem); stale
  Proposal/UpdateLineItemsRequest shapes removed
- shared/api-contracts/src/schemas.ts: zod runtime schemas coupled to
  every wire type via `satisfies z.ZodType<T>` (schema/type drift is now
  a compile error); separate entrypoint so type-only consumers (mobile)
  never pull zod
- web: imports @proposal-system/api-contracts (file: dep + tsconfig
  paths + vite preserveSymlinks); all 7 lib/api modules re-export shared
  types so page imports stay stable; enum unions tightened
  (PricingLibraryPage form state now ServiceCategory-typed)
- fix(web): customer create/update sent a singular `address` field the
  API silently dropped (contract is addresses: string[], CustomerDtos.cs)
  - addresses now round-trip, extra addresses preserved on edit
- api: ProblemDetails responses carry a machine-readable top-level
  `code` (SHOC error-code vocabulary): ValidationFailed,
  InvalidStateTransition, NotFound, Unauthorized, InternalError; new
  BusinessRuleException(code, message) maps to 422 with its code;
  GlobalExceptionHandlerTests cover the full mapping (wire contract)

Cross-checked .NET DTOs vs TS types vs zod schemas with the
orchestrator scanner (Gemini): core domains consistent; internal-only
DTOs (FileDtos vendor/lambda surface, SimilarProposalDtos, UserDtos
admin surface) intentionally uncovered.

Verify: dotnet 166/166, web tsc + vitest 26/26 + build, mobile tsc,
shared tsc all green.

* feat(web): domain-layer conventions doc + react-hook-form deps (Phase 4 prep)

* feat(web): scaffold domain module layer (proposals, lineItems, customers, pricingLibrary, admin, sites)

Additive-only: pages still use lib/api/* and constants/queryKeys.ts until
the page-migration agents run. Each domain ships api.ts (HTTP moved from
lib/api), types.ts (contract re-exports + view types), schemas.ts (contract
schema re-exports + form schemas with toRequest mappers), and use-cases.ts
(TanStack Query v5 hooks + hierarchical query keys, mirroring current page
invalidations and toast-on-error behavior).

Adds an explicit vite/vitest alias for the
@proposal-system/api-contracts/schemas subpath (package has no exports map)
plus a schema/mapper smoke test suite.

* refactor(web): proposal pages on domain layer, proposal form on react-hook-form

* refactor(web): admin workspace on domain layer

* refactor(web): customer management on domain layer + react-hook-form

* refactor(web): pricing library on domain layer + react-hook-form

* refactor(web): dashboards on domain layer

* test(web): domain use-case hook coverage

* refactor(web): finish domain-layer integration — migrate straggler components, delete legacy api modules

- SimilarProposalsPanel -> useSimilarProposals (domain/admin); inline
  SimilarProposal type replaced by domain/admin/types (identical shape);
  query key joins the admin hierarchical key space
- LineItemEditor type imports -> domain/lineItems/types
- Delete now-orphaned lib/api/{proposals,lineItems,customers,
  pricingLibrary,admin,sites}.ts, constants/queryKeys.ts,
  hooks/usePaginatedList.ts (lib/api/client.ts + auth.ts stay per
  domain README rule 5)

Verify: tsc clean, vitest 52/52, build OK, Playwright smoke of the
authed shell renders on domain hooks.

* fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup)

Correctness:
- State-transition mutations now invalidate every cached view via
  invalidateProposalViews (detail + line items + lists + stats + admin
  dashboard) — approving no longer leaves a stale queue for the
  5-minute staleTime
- Presigned S3 PUT moved to proposals/api.ts with res.ok check — a
  rejected upload is no longer confirmed as uploaded
- toCustomerRequest always sends contactEmail ('' clears); API create
  path normalizes empty->null to match the update path — customer
  emails can now be cleared from the UI
- Shared Number-based numeric form fields (domain/shared/formFields):
  '12abc' no longer silently coerces to 12 in the pricing library
- Customer create/update invalidate customersKeys.all so cached search
  autocompletes see new customers
- AdminWorkspace clears dirty right after a successful implicit save,
  before approve — no false unsaved-changes prompt when approve fails
- ProposalFormPage submit gate and missing-fields caption derive from
  ONE checks list (missing customer is now listed)
- Empty states gated on !err in ProposalListPage/AdminDashboard — no
  contradictory error + 'no proposals' UI
- VendorDataPanel migrated to useVendorProposals (kills the divergent
  ['vendorProposals', id] cache key and the inline apiClient query)
- useCustomerList/usePricingLibraryList get keepPreviousData — no
  TablePagination out-of-range flash on page change

Cleanup:
- Dead speculative hooks removed (useCreate/BulkUpdate/DeleteLineItem,
  useUpdateProposal, useProposalHistory/Audit, lineItemRowFormSchema,
  toUpdateLineItemEntry); tests moved to the live save path
  (useSaveProposalWorkspace)
- Shared useDebouncedValue hook replaces 4 drifted inline debounce
  copies (one leaked its timer on unmount, two hardcoded 300ms);
  DEBOUNCE_AUTOCOMPLETE=300 named
- Fix: WEB-H5 / WEB-H6 finding-ID markers restored at the relocated
  onError handlers (CLAUDE.md traceability)
- shared/api-contracts gains an exports map; /schemas resolver alias
  deduplicated from 3 copies to the tsconfig paths mapping

Verify: tsc clean, vitest 51/51 (tests updated to pin the new
invalidation/mapper behavior + new '12abc' rejection test),
vite build OK, dotnet 166/166.

* refactor(web): fold Redux auth/ui slices into SHOC-shape auth context + storage module

Phase 4 tail of the SHOC-alignment plan. Matches SHOC's auth shape
(lib/auth storage module + providers/ context split) while keeping the
deliberate divergences:

- sessionStorage, not localStorage (WEB-C1 stands; SHOC's localStorage
  is on the SHOULD-NOT-ALIGN list)
- token acquisition stays in the auth pages (Cognito code exchange /
  dev-login) — the provider only owns session state
- 401 interceptor clears storage directly (WEB-M2 behavior preserved;
  full-page redirect resets provider state)

Sidebar open state moves to plain layout state in App passed down as
props (SHOC (protected)/_layout.tsx pattern), keeping localStorage
persistence. Drops @reduxjs/toolkit and react-redux.

Tests: authSlice tests replaced by authStorage + AuthProvider suites
(QA-C5 coverage preserved); client interceptor tests updated for the
storage-based 401 path. 59 vitest green, tsc clean, vite build OK.
Verified end-to-end headless: login redirect, seeded-session shell,
sidebar toggle persistence, logout, expired/malformed token handling,
RoleGuard bounce; recipe persisted as web/.claude/skills/verify.

* fix(web): harden auth session teardown per /sh-security-review findings

- AUTH-L1 (confirmed medium): logout() now clears the react-query cache —
  the singleton cache survived SPA logout, serving the previous
  principal's cached GETs to the next login in the same tab for up to
  staleTime with no server round-trip.
- AUTH-L3 (confirmed low): isTokenValid decodes base64url before atob —
  valid Cognito JWTs containing '-'/'_' in the payload segment were
  misclassified as expired (login lockout/loop; inherited from the old
  authSlice).
- AUTH-L2 (unverified, hardened anyway): 401 interceptor broadcasts
  AUTH_SESSION_CLEARED_EVENT so AuthProvider drops in-memory state
  synchronously, restoring the old Redux atomic-clear semantics.
- INJ-1 (unverified, hardened anyway): Authorization header only set
  when the stored token is a string.

Each fix pinned by a test; 63 vitest green, tsc clean.

* docs: web stack row reflects auth-context refactor (Redux removed, MUI v9)
2026-07-13 20:37:18 -04:00
Adam Moussa
a4b09eb0ad
docs: SHOC-alignment Phase 1 — ADRs, governance files, doc corrections (#220)
- Add ADR 0002 (SHOC merge boundary: separate backend services, shared
  conventions) and ADR 0003 (adopt SHOC design system + UI/UX layout)
- Add CODEOWNERS (internal-dev) and PR template (Summary/Test plan/Jira/
  docs-current checklist + contract-table convention)
- Fix stale facts in README/CLAUDE.md: MUI v7→v9, RN 0.85→0.86,
  OpenSearch Serverless/oss-index-creator → Aurora pgvector/
  aurora-pgvector-init (ADR 0001), test counts 149→186 (123 xUnit /
  26 vitest / 37 pytest), deploy triggers are workflow_dispatch-only,
  reusable workflow refs float on @main, aws-cdk-lib version claim
  replaced with Dependabot-maintained note
2026-07-13 17:00:45 -04:00
2549ce3afc Repo hygiene: PR labeler + README badges (INFRA-56/57) 2026-06-11 14:02:35 -04:00
Adam Moussa
f9081fabf4 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:18:44 -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
ef8a3b5f48 Clean up oss-index-creator: remove debug logging, update docs
- Remove verbose print statements from Lambda handler
- Add dependabot pip entry for oss-index-creator
- Update README with new Lambda and deployed stack state
2026-05-18 18:10:35 -04:00
Adam Moussa
7426d9a538
Add iOS CD pipeline and refactor workflows to org reusable callers (#24)
* Add iOS native project for React Native mobile app

Xcode project with bundle ID com.seahavenind.proposals,
CocoaPods configuration, and app scaffolding.

* Add Fastlane configuration for iOS builds and TestFlight distribution

Configures match with S3 storage (seahaven-ios-certificates bucket)
for code signing and a beta lane for automated TestFlight uploads.

* Add mobile CI job and iOS CD workflow (disabled)

CI: adds mobile typecheck job on PRs.
CD: deploy-mobile.yaml builds and uploads to TestFlight via
Fastlane on a macOS runner with OIDC auth for match S3 access.
Currently workflow_dispatch only — activate for V1 release.

* Refactor workflows to thin wrappers calling org reusable workflows

CI jobs now call ci-dotnet, ci-typescript-cdk, and ci-python-sam
from the org repo. Deploy calls cd-cdk with post-deploy script
for web build/S3/CloudFront. Mobile deploy calls cd-mobile-ios.
Adds deploy concurrency groups to both deploy workflows.

* Add mobile Dependabot entries and remove assignees

Add npm and bundler ecosystems for mobile/. Remove assignees
from all entries — convention no longer in use.

* Add comprehensive README for the proposal-system monorepo

* Fix mobile TypeScript errors and add package-lock.json

Fix tsconfig.json (remove rootDir/outDir, add noEmit), fix useRef
type error, fix navigation type cast, add @types/react-native-vector-icons,
and generate package-lock.json for CI.

* Add .npmrc for mobile to resolve peer dependency conflicts

react-native-screens@4.x requires react-native >= 0.82 but the
project uses 0.79. legacy-peer-deps allows installation until
the next React Native upgrade.
2026-05-18 15:30:30 -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