* ci(workflows): use autofix formatter presets (PLAT-222)
Point autofix at the presets commit so ruff and Terraform fmt use the
org presets, and write the template Prettier and ESLint fixes CI checks.
* style: add an unused import for autofix
Deliberate F401 in week_keys so the ruff preset can remove it.
* ci(workflows): pin autofix to v1.0.15 (PLAT-222)
The previous pin was the pre-squash commit, which became unreachable
when that branch was deleted, so CI failed before autofix started.
* style: apply formatter
---------
Co-authored-by: sea-haven-auto-fix[bot] <5037331+sea-haven-auto-fix[bot]@users.noreply.github.com>
* fix(iam): drop githubdeploy workflow_ref OIDC condition
AWS STS does not evaluate GitHub workflow_ref, so that trust condition fail-closes AssumeRoleWithWebIdentity.
* chore(security): retarget githubdeploy Checkov suppression
Dropping the workflow_ref trust condition shifted CKV_AWS_111 from line 49 to 42. Permissions are unchanged.
* style: apply formatter
---------
Co-authored-by: sea-haven-auto-fix[bot] <5037331+sea-haven-auto-fix[bot]@users.noreply.github.com>
* ci: convert onto org HCP reusables
Switch Fargate CD and CI to the v1.0.13 org workflows, emit ci-complete, and retarget githubdeploy OIDC to the reusable plus the thin caller.
* chore(security): retarget githubdeploy Checkov suppression
The OIDC dual-claim edit shifted CKV_AWS_111 from line 40 to 49. Permissions are unchanged.
* style: apply formatter
* ci: pin org reusables to v1.0.14
Drop collect-only and requirements from the python lint caller now that ci-python-app is lint-only.
* test(ci): probe autofix with a ruff format violation
* style: apply formatter
---------
Co-authored-by: sea-haven-auto-fix[bot] <5037331+sea-haven-auto-fix[bot]@users.noreply.github.com>
* feat(infra): export attached VPC ids and lock prod to afterhours (DEV-289)
Prod must keep existing_vpc_id pointed at the afterhours VPC. Outputs
expose the resolved vpc_id and public subnet IDs.
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
* feat(api): add OpenAPI 3.1 and Redocly lint in CI (DEV-289)
Same extends: recommended ruleset and @redocly/cli 2.52.1 as
internal-portal. Documents current { error: string } JSON errors.
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
* fix(api): document 4xx and reject invalid form-status weeks (DEV-289)
Health, form-status, and roster document 400. form-status now maps
current and returns 400 for a week that is not current or YYYY-WNN.
Redocly treats 302 as a success response, matching the portal.
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
* style(test): format VPC contract assertions for ruff (DEV-289)
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
* fix(api): fail Redocly on missing 4xx and 2xx/3xx (DEV-289)
Promote operation-4xx-response and the 2xx-or-3xx success rule to error.
Replace unused health and roster 400s with 403, matching portal health.
Form-status keeps its real 400 for invalid week.
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
* fix(api): split week params and allow live menu nulls (DEV-289)
Menu and form-status take current or YYYY-WNN. Orders take YYYY-WNN or a
calendar date and reject current. Menu payloads may emit null menu_url,
calories, protein, and image_url.
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
* fix(infra): fail prod apply without the afterhours VPC (DEV-289)
Prod never creates the 10.60 fallback VPC. A terraform_data precondition
fails plan and apply when existing_vpc_id is empty, instead of a check
block that only warns.
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
Initialize the SDK on gunicorn and the SQS worker with afterhours-style scrubbing. Store the DSN in SSM and inject only the parameter name onto the live task.
* fix(infra): share the afterhours VPC when existing_vpc_id is set
Prod is at the account VPC quota, so the v1.0.0 apply destroyed Lambda/API Gateway then failed on CreateVpc. Skip creating a sixth VPC when the workspace supplies afterhours subnets.
* style(test): format the VPC terraform assertion for ruff
* feat(api): serve meals on ECS Fargate instead of Lambda
Keep the Flask app always-on with in-process jobs so CloudFront no longer fronts a cold-start API Gateway.
* fix(jobs): run delayed close and reminder deliveries
Wall-clock skip windows dropped the only weekly SQS attempt when Scheduler already fired in Eastern time. Dev schedules stay disabled.
* fix(api): return JSON objects and stop logging job payloads
Flask now jsonify-s handler dicts so API responses are not HTML, and the worker logs only event and status.
* fix(ci): restore the reusable workflow so the required check is named ci / ci
Inlining the job reported `ci` instead of the org ruleset's `ci / ci`.
* fix(secrets): drop unused os import so ruff check passes
* style: apply ruff format so ci-python-app lint passes
* fix(infra): give meals its own VPC because prod has none
* chore(security): re-key ALB SG checkov suppression after vpc.tf
* fix(iam): ignore default tags on hcptf roles (PLAT-210)
The apply role cannot iam:TagRole on itself. Provider default_tags from
the env split 403'd the prod apply on hcptf-meal-order-manager and -plan.
* fix(iam): ignore tags_all on hcptf roles (PLAT-210)
ignore_changes on tags does not cover provider default_tags. The prod
speculative plan still wanted Environment on tags_all and would TagRole.
* feat(infra): add lightweight meal-order-manager-dev (PLAT-210)
Parameterize the HCP root for seahaven-dev with schedules, PITR, alarms, and Paychex gated off so a second env does not clone production cost or side effects.
* fix(infra): drop prod-only authorizer import so dev can create it (PLAT-210)
The PLAT-102 import is already in meal-order-manager-prod state. A shared import block fails in seahaven-dev because the permission does not exist there.
* fix(iam): allow creating the weekly-menu githubdeploy role in seahaven-dev (PLAT-210)
Prod imported that role. A new account needs CreateRole on tf-managed/githubdeploy-meal-order-manager-weekly-menu.
* fix(auth): accept federated portal Cognito tokens for meals admin
Google Workspace federation stores email_verified=false, which 403'd the
portal Admin probe while the public menu still loaded.
* fix(iam): grant plan role CloudFront DescribeFunction
* feat(edge): proxy portal meals API paths on orders.seahaven.com (DEV-282)
Keep the static form on / while CloudFront forwards submit, form-status, admin, and caller-only order lookup so the portal can use the public meals host without a form redirect.
* fix(style): apply ruff format
* chore(meals): remove email_report payroll SES path (PLAT-135)
Stop Monday SES deduction emails now that Flex checkcomponents owns payroll posting.
* chore(meals): delete email_report handler and SAM resources
Remove the leftover SES Lambda source so it cannot be redeployed from template.yaml.
* feat(meals): send weekly deductions to paychex checkcomponents (PLAT-154)
* fix(meals): round checkcomponents amounts half-up
Keep SQS deduction amounts on the same rounding path as submit_order so extra-precision totals cannot diverge by a cent.
* feat(iam): import hcptf roles into app Terraform (PLAT-146)
Move the existing hcptf pair into this repo so app Terraform owns prod IAM after the substrate handoff.
* fix(iam): add apply-role IAM list permissions (PLAT-146)
IamReadOnly omitted ListRoleTags and ListInstanceProfilesForRole needed after detaching the substrate guardrail.