Skip to content

Conversation

@hao10282025-sudo
Copy link
Collaborator

Summary

onboarding document update

Changes proposed

Add Hao Wang to CODEOWNERS and MAINTAINERS.md

Context for reviewers

Onboarding process

Validation steps

Verify the name is added as expected

* @mdragon # project lead

/documentation/ @andycochran @btabaska @chouinar @doug-s-nava @joshtonava @mdragon @myduong-navapbc @widal001 @prasnava @jakobpederson @ErinPattisonNava # everyone
/documentation/ @andycochran @btabaska @chouinar @doug-s-nava @joshtonava @mdragon @myduong-navapbc @widal001 @prasnava @jakobpederson @ErinPattisonNava @haowang # everyone
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the codeowners file, the @ should be your github username, looks like yours is @hao10282025-sudo.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the codeowners file, the @ should be your github username, looks like yours is @hao10282025-sudo.

Ah ok right, updated with the accurate GitHub username, thanks

babebe and others added 20 commits November 6, 2025 10:03
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes / Work for #6115  

## Changes proposed

Remove `is_organization_owner` flag from `OrganizationUser` table
Create migration file
Update tests
## Summary

The current ci-openapi.yml workflow introduces merge conflicts when the
branch is stale. Updated the workflow to rebase and resolve merge
conflicts.

## Validation steps

The ci-openapi.yml workflow should continue to run without introduced
merge conflicts.

Successfully tested the workflow:
[here](https://github.com/HHS/simpler-grants-gov/actions/runs/19142747767)

Merge conflicts are now resolved in the latest pull request:
[here](#6910)
…6973)

## Summary
Fixes #6317 

## Changes proposed
* Adds an endpoint for fetching audit events for an application
* Adds a lot to the application audit factory to setup events in
reasonable states

## Context for reviewers
Another ticket will handle adding audit events in our application
endpoints, but this one is for fetching those from the already created
table.

In the future, we may want to add filters and/or more sorting options,
but keeping it very basic for now.

## Validation steps
Tests verify that each of the event type scenarios should flow through
uneventfully with expected fields populated.
…the Zip (#6954)

## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes #6834

## Changes proposed

<!-- What was added, updated, or removed in this PR. -->
Add `enable_xml_generation` to `ApplicationSubmissionConfig`.
Add `SubmissionXMLAssembler` to handle assembling application submission
forms, header and footer into a `GrantApplication.xml` file, included in
the zip file.
When FF is enabled, `SubmissionXMLAssembler` will generate XML and
include in the ZIP file.
Add relevant tests to the task and assembler.
Update the submission manifest to reflect `GrantApplication.xml` is
added to the zip.

## Context for reviewers

<!-- Technical or background context, more in-depth details of the
implementation, and anything else you'd like reviewers to know about
that will help them understand the changes in the PR. -->
We moved up creating the `ApplicationSubmission` record earlier in the
`create_application_submission_task` because we need the
`legacy_tracking_number` in the XML footer, so we update the record
after creating it and the zip file.
The process is designed to *not* block the task if there was an error
generating the XML, so any forms that are not supported or fail are
skipped.


## Validation steps

<!-- Manual testing instructions, as well as any helpful references
(screenshots, GIF demos, code examples or output). -->
See unit tests for task and assembler.
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes / Work for #6808 

## Changes proposed

<!-- What was added, updated, or removed in this PR. -->
Add "tcertificates" to TABLES_TO_LOAD to enable automated loading for
table.

## Context for reviewers

<!-- Technical or background context, more in-depth details of the
implementation, and anything else you'd like reviewers to know about
that will help them understand the changes in the PR. -->
This will allow tcertificates table to remain up to date with the Oracle
db. Waiting on #6807

## Validation steps

<!-- Manual testing instructions, as well as any helpful references
(screenshots, GIF demos, code examples or output). -->
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes #6892 
Anyone running the API locally will need to run the following steps in
the `api/` directory:
- `docker compose down` or `make stop`
- `make remake-backend` 
- `docker compose up` or `make run-logs`

## Changes proposed

Bumps the container version to match the PostgresSQL version we're
running in AWS

## Context for reviewers

<!-- Technical or background context, more in-depth details of the
implementation, and anything else you'd like reviewers to know about
that will help them understand the changes in the PR. -->

## Validation steps

1. Check out this branch
2. Run the steps above in the `api/` folder
3. Validate that FE/API still work locally
…cs (#6910)

Automated update of ERD diagrams and OpenAPI specs.

---------

Co-authored-by: nava-platform-bot <[email protected]>
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes / Work for #6813

Ran the migration locally and checked the db
```
app=# SELECT user_id, user_type_id FROM api.user;
               user_id                | user_type_id
--------------------------------------+--------------
 a3f77afe-c293-414b-a2c0-53c1be5f2936 |            1
 f15c7491-7ebc-4f4f-8de6-3ac0594d9c63 |            1
 0f4ae584-c310-472d-9d6c-57201b5f84cc |            1
 b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e |            1
 f5a6b7c8-d9e0-4f1a-2b3c-4d5e6f7a8b9c |            1
 5b4807c5-57d4-4867-b722-1658b47c59ba |            1
 12345678-1234-5678-9abc-123456789abc |            1
 7edb5704-9d3b-4099-9e10-fbb9f2729aff |            1
 6234b6c2-334e-42c4-8e8b-0c7faba549dd |            2  # dev
 21b7ac4c-3acb-4975-bd4d-6c76592d8507 |            2  # staging
 30bbfd53-f34a-401c-b3b7-a2712e32e072 |            2  # training
 aa59a18f-86e9-47b2-a80e-8c2a4ddc9287 |            2  # prod
 ```
Querying the database session it looks like the enums are being set correctly by id:
```
│   User(
│   │   user_id=UUID('7edb5704-9d3b-4099-9e10-fbb9f2729aff'),
│   │   user_type=<UserType.STANDARD: 'standard'>,
│ │ created_at=datetime.datetime(2025, 11, 4, 21, 14, 43, 907167,
tzinfo=datetime.timezone.utc),
│ │ updated_at=datetime.datetime(2025, 11, 4, 21, 14, 43, 907167,
tzinfo=datetime.timezone.utc)
│   ),
│   User(
│   │   user_id=UUID('6234b6c2-334e-42c4-8e8b-0c7faba549dd'),
│   │   user_type=<UserType.INTERNAL_FRONTEND: 'internal_frontend'>,
│ │ created_at=datetime.datetime(2025, 11, 4, 22, 11, 14, 542228,
tzinfo=datetime.timezone.utc),
│ │ updated_at=datetime.datetime(2025, 11, 4, 22, 11, 14, 542228,
tzinfo=datetime.timezone.utc)
│   )
```

Can query against the UserType:
```
>>>
list(dbs.query(User).where(User.user_type==UserType.INTERNAL_FRONTEND))
[
│   User(
│   │   user_id=UUID('6234b6c2-334e-42c4-8e8b-0c7faba549dd'),
│   │   user_type=<UserType.INTERNAL_FRONTEND: 'internal_frontend'>,
│ │ created_at=datetime.datetime(2025, 11, 4, 22, 11, 14, 542228,
tzinfo=datetime.timezone.utc),
│ │ updated_at=datetime.datetime(2025, 11, 4, 22, 11, 14, 542228,
tzinfo=datetime.timezone.utc)
│   )
]
```

## Changes proposed

<!-- What was added, updated, or removed in this PR. -->

- Add user_type Lookup model
- Add user_type_id to User model
- Update UserFactory
- Manually adjust user_type_id on Users (use list of uuids to set to internal frontend users)

## Context for reviewers

<!-- Technical or background context, more in-depth details of the implementation, and anything else you'd like reviewers to know about that will help them understand the changes in the PR. -->

## Validation steps

<!-- Manual testing instructions, as well as any helpful references (screenshots, GIF demos, code examples or output). -->
### Summary
Improves how validation handling and logging works for CommonGrants
services in order to address a bug that allowed URLs with problematic
characters to slip through `validate_url()` only to fail Pydantic validation

Fixes #6982 

### Changes
- Fixes bug with `validate_url()` in CommonGrants routes
  Previous implementation used `urlparse`, which allowed some URLs to pass
  through that ultimately failed `HttpUrl` validation in Pydantic with strict mode 
  enabled. This now uses the same Pydantic field configuration to validate URLs.

- Improves logging for CommonGrants routes
  Adds `extras` argument to logging with input data and
  `CommonGrantsEvents` enum when validation fails. Also downgrades
  validation logging from `exception` to `warning` so we aren't tripping
  the New Relic alerts on every validation issue.

- Tests validation handling and logging
  Confirms how CommonGrants services handle validation errors and logging
…#7002)

## Summary

## Changes proposed
* Make the application list page sort by created_at instead of
updated_at
* Fix a SQLAlchemy warning in a recent change from the create submission
work

## Context for reviewers
After a recent chat with frontend/product, we agreed that sorting by
`created_at` makes more sense. `updated_at` is a bit clunky as it only
changes when a user updates the application name (form updates would not
change this). Created at is consistent as it gets set once.

The other fix is unrelated entirely, but fixes a SQLAlchemy warning that
was happening from an unrelated change.
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…cs (#7010)

Automated update of ERD diagrams and OpenAPI specs.

Co-authored-by: nava-platform-bot <[email protected]>
## Summary

Disabled the auto dev deploys when a commit is merged into main. Created
a new workflow to trigger dev deploys as a cron everyday at 5am. This
will reduce the amount of churn in the dev environment.

## Validation steps

The current deploy workflows should continue.
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[hadolint/hadolint-action](https://redirect.github.com/hadolint/hadolint-action)
| action | minor | `v3.1.0` -> `v3.3.0` |
| [python](https://redirect.github.com/actions/python-versions) |
uses-with | minor | `3.13` -> `3.14` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>hadolint/hadolint-action (hadolint/hadolint-action)</summary>

###
[`v3.3.0`](https://redirect.github.com/hadolint/hadolint-action/releases/tag/v3.3.0)

[Compare
Source](https://redirect.github.com/hadolint/hadolint-action/compare/v3.2.0...v3.3.0)

##### Features

- trigger release workflow
([2332a7b](https://redirect.github.com/hadolint/hadolint-action/commit/2332a7b74a6de0dda2e2221d575162eba76ba5e5))

###
[`v3.2.0`](https://redirect.github.com/hadolint/hadolint-action/releases/tag/v3.2.0)

[Compare
Source](https://redirect.github.com/hadolint/hadolint-action/compare/v3.1.0...v3.2.0)

##### Features

- new minor release
([3fc49fb](https://redirect.github.com/hadolint/hadolint-action/commit/3fc49fb50d59c6ab7917a2e4195dba633e515b29))

</details>

<details>
<summary>actions/python-versions (python)</summary>

###
[`v3.14.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.0-18313368925):
3.14.0

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.9-18515951191...3.14.0-18313368925)

Python 3.14.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "on the 2nd and 4th day instance on
sunday after 9pm" in timezone America/New_York, Automerge - At any time
(no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/HHS/simpler-grants-gov).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNTkuNCIsInVwZGF0ZWRJblZlciI6IjQxLjE3My4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Billy Daly <[email protected]>
## Summary

Work for #6597 

## Changes proposed

A table was added to the Applications page including ability to fetch
the /{user_id}/applications endpoint. Figma designs are found
[here](https://www.figma.com/design/zPlDWcYM396szw2yL3UXvk/Simpler-Grants-2025?node-id=6147-97509).

Testing coverage for touched components:

<img width="983" height="264" alt="Screenshot 2025-11-05 at 1 46 10 PM"
src="https://github.com/user-attachments/assets/dc2f26e1-fa1d-43f3-bce4-b7b33bae65a3"
/>

## Context for reviewers

This pr builds on #6907 to flesh out the Applications page with data.
The feature has already completed design review.

One note is that when you go to an Opportunity where you've already
created an Application, it does not remember you have already begun and
application. So you'll see the "start an application" button and you can
have multiple applications opened as an individual against a single
opportunity. Looks like that will be fixed in #6600

## Validation steps

- [ ] A logged out user should get an error message that they need to
sign in
- [ ] A logged in user who has started no applications should see the
appropriate content
- [ ] Easiest to test seeing applications in localhost with the
`many_app_user` user
  - [ ] Close date should be formatted
  - [ ] Status for applications in draft should say "Draft"
  - [ ] Status for applications in submitted should say "Submitted"
  - [ ] Status for applications in approved should say "Submitted"
- [ ] Application name should be a link to the already-started
application
- [ ] Type should read as Individual for applications started as an
individual
- [ ] Type should read as the organization name for applications started
as an organization
- [ ] Opportunity name should be listed with a link, and Agency should
be listed as well
- [ ] If an application is opened in a separate browser and this page is
refreshed, it should appear (no caching issues)
- [ ] Error can be tested in localhost only, I put `
raise_flask_error(500, f"EJP error!!”)`
[here](https://github.com/HHS/simpler-grants-gov/blob/2ccb772aa0930263173046f17708e1e7571e8f6f/api/src/services/users/get_user_applications.py#L66)
to force a 500
…7018)

## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes / Work for #6899 

## Changes proposed

<!-- What was added, updated, or removed in this PR. -->

In our XML generation logic, add support for static fields and
attributes on nested objects.

## Context for reviewers

<!-- Technical or background context, more in-depth details of the
implementation, and anything else you'd like reviewers to know about
that will help them understand the changes in the PR. -->
Fields can now be populated with constant values that don't come from
application data, e.g.:
```
"form_version": {
    "xml_transform": {
        "target": "FormVersion",
        "static_value": "4.0"
    }
}
```

Generates XML: `<FormVersion>4.0</FormVersion>`


For attributes on nested objects:
```
"material_change_supplement": {
    "xml_transform": {
        "target": "MaterialChangeSupplement",
        "type": "nested_object",
        "attributes": {
            "SFLLL_2_0:ReportType": "MaterialChange"
        },
        "nested_fields": {
            "year": {"xml_transform": {"target": "MaterialChangeYear"}},
            "quarter": {"xml_transform": {"target": "MaterialChangeQuarter"}},
            "last_report_date": {"xml_transform": {"target": "LastReportDate"}}
        }
    }
}
```

Provided with `application_data`
```
     {
            "material_change_supplement": {
                "year": "2025",
                "quarter": "1",
                "last_report_date": "2025-01-01",
            }
        }
```

generates:

```
<SFLLL_2_0:MaterialChangeSupplement SFLLL_2_0:ReportType="MaterialChange">
  <SFLLL_2_0:MaterialChangeYear>2025</SFLLL_2_0:MaterialChangeYear>
  <SFLLL_2_0:MaterialChangeQuarter>1</SFLLL_2_0:MaterialChangeQuarter>
  <SFLLL_2_0:LastReportDate>2025-01-01</SFLLL_2_0:LastReportDate>
</SFLLL_2_0:MaterialChangeSupplement>
```

Our `base_transformer` was augmented to store passed in attributes which
are interpreted later. The new format is
```
result[f"__{target_field}__attributes"] = transform_rule["attributes"]
```

This stores static attribute data required for the transform step later.

## Validation steps

<!-- Manual testing instructions, as well as any helpful references
(screenshots, GIF demos, code examples or output). -->
See new unit tests.
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes issue where XSDs were being pulled at runtime, which is used by
our XML generation logic to enforce element ordering (required in some
cases). Instead of XSD ordering, rely on ordering from our configs.

Additionally, remove some SF424 hard-coding.

## Changes proposed

<!-- What was added, updated, or removed in this PR. -->

Update order of `applicant_type_code_mapping` to fix XSD validation.
Remove `_get_xsd_element_order` and `_get_complex_type_element_order`
which previously used network requests at runtime to fetch XSDs.
Add helper method to inspect config and extract element order.
Add a test for the scenario.

## Validation steps

<!-- Manual testing instructions, as well as any helpful references
(screenshots, GIF demos, code examples or output). -->
See new test and run `make fetch-xsds` and `make test-xml-validation` to
see CLI tests passing.
## Summary

Fix API Anchore Vulnerabilities below: 

libcap    2.73-1.amzn2023.0.3 ->  2.73-1.amzn2023.0.4   
python    3.13.9         ->       3.15.0                
lz4-libs  1.9.4-1.amzn2023.0.2 -> 1.9.4-1.amzn2023.0.3  

We will be skipping the python version upgrade as that version is not
released yet.

## Validation steps

API should continue to work as is.
…7034)

## Summary
Fixes #6316 

## Changes proposed
* Adds activity history events for application endpoints

## Context for reviewers
Went through all of our non-get endpoints for apply and added audit
events. The ticket lays out most of these events, although the following
odd cases were also added:
* If a user starts an app as an individual, they get added as a user,
that gets noted down
* If a user adds an organization later, that is a new event I added +
all the users that get removed get noted down.

The logic for handling a failed submission requires a separate DB
session so unfortunately needs to be at the API route level.

## Validation steps
Locally, I started an app against the opportunity/competition with all
forms.Added an attachment, adjusted a few forms, failed to submit, fixed
issue, and then submitted just one form.

I then called the audit history endpoint and got the following events.
(If you want a JWT for the user, the new `GET /local/local-users`
endpoint can get you that easily).

<details>
<summary>Open me to see the full set of audit events</summary>

```json
{
  "data": [
    {
      "application_audit_event": "submission_created",
      "application_audit_id": "aca7ee2e-3528-4a8a-b0e2-b5d090e77b1b",
      "created_at": "2025-11-12T15:24:14.494628+00:00",
      "target_application_form": null,
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "application_submitted",
      "application_audit_id": "7349263c-fe6a-4672-8b0b-179d2bd0e610",
      "created_at": "2025-11-12T15:23:48.630890+00:00",
      "target_application_form": null,
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "d7149201-81df-4556-aca6-4cbeb04c154d",
      "created_at": "2025-11-12T15:23:41.912324+00:00",
      "target_application_form": {
        "application_form_id": "95fa6b3d-c043-41f3-9d04-67f9339da507",
        "competition_form_id": "40f68f9d-fe01-406d-9ad5-93f45bee86fd",
        "form_id": "bf683068-23a4-43fa-ac7a-0f046b83cb14",
        "form_name": "Project Abstract Summary"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "application_submit_rejected",
      "application_audit_id": "5ef653ee-3ad4-46c8-bc75-82fd6f9c038e",
      "created_at": "2025-11-12T15:23:32.344679+00:00",
      "target_application_form": null,
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "e4484c73-fd83-4930-8367-124587a8f7f3",
      "created_at": "2025-11-12T15:23:28.270079+00:00",
      "target_application_form": {
        "application_form_id": "95fa6b3d-c043-41f3-9d04-67f9339da507",
        "competition_form_id": "40f68f9d-fe01-406d-9ad5-93f45bee86fd",
        "form_id": "bf683068-23a4-43fa-ac7a-0f046b83cb14",
        "form_name": "Project Abstract Summary"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "4ceaf68f-b311-4240-9287-3adb75b6a7fa",
      "created_at": "2025-11-12T15:23:23.359912+00:00",
      "target_application_form": {
        "application_form_id": "1b8da552-4ca5-4da1-8e29-4f90f0ffbe0a",
        "competition_form_id": "6ffaf589-d985-49a0-bc1a-cbec75883213",
        "form_id": "32165da2-354d-42c0-a986-cf4f2f350039",
        "form_name": "Project Narrative Attachment Form"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "3774ffe4-9b4d-416b-ba3b-60b62e5624c4",
      "created_at": "2025-11-12T15:23:21.950359+00:00",
      "target_application_form": {
        "application_form_id": "95fa6b3d-c043-41f3-9d04-67f9339da507",
        "competition_form_id": "40f68f9d-fe01-406d-9ad5-93f45bee86fd",
        "form_id": "bf683068-23a4-43fa-ac7a-0f046b83cb14",
        "form_name": "Project Abstract Summary"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "623996db-01ed-406e-880e-25c12824c32c",
      "created_at": "2025-11-12T15:23:20.908241+00:00",
      "target_application_form": {
        "application_form_id": "cb6dc736-9c40-48f4-9943-fdca18fafbc1",
        "competition_form_id": "fe296f2c-62b3-4d0a-957e-86bb66176112",
        "form_id": "778a1485-082a-463e-a61b-6615ccebe027",
        "form_name": "Disclosure of Lobbying Activities (SF-LLL)"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "d18d1efb-0f63-4984-b73d-8c063a6031d7",
      "created_at": "2025-11-12T15:23:19.101114+00:00",
      "target_application_form": {
        "application_form_id": "507ebc03-fb85-4493-a625-223aef1029ac",
        "competition_form_id": "70e513f7-d0e9-46e4-aa7b-ea6b3646c88b",
        "form_id": "7057eaee-f043-4029-b7f2-c932f11ce900",
        "form_name": "CD511"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "f4fb77de-0778-482c-8b84-8e37961000f2",
      "created_at": "2025-11-12T15:23:18.395613+00:00",
      "target_application_form": {
        "application_form_id": "4e074823-25ad-40d7-8aeb-c64e1ba82f87",
        "competition_form_id": "ebaaaf91-8022-4d6e-b09b-b6e487827adf",
        "form_id": "66092260-d3c2-4427-8fd2-bb14e1590aff",
        "form_name": "Budget Narrative Attachment Form"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "6b8530c1-51eb-424c-82c7-b138c24ba29e",
      "created_at": "2025-11-12T15:23:17.598543+00:00",
      "target_application_form": {
        "application_form_id": "edf6c262-36d0-41c8-92dd-de5dd56e4d06",
        "competition_form_id": "a7d437d3-b929-4438-84ee-c720c69220a6",
        "form_id": "08e6603f-d197-4a60-98cd-d49acb1fc1fd",
        "form_name": "Budget Information for Non-Construction Programs (SF-424A)"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "d27b7575-c683-423a-85c5-67e69f799f78",
      "created_at": "2025-11-12T15:23:15.248089+00:00",
      "target_application_form": {
        "application_form_id": "3b20adee-7655-4e45-b023-450860c78d35",
        "competition_form_id": "ed653a24-dba8-4140-b693-7b8f9db19e95",
        "form_id": "1d0681f8-26f9-4ff1-a75e-e33477668f73",
        "form_name": "Assurances for Non-Construction Programs (SF-424B)"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "18653314-2e2c-4d9e-b893-220580c757b0",
      "created_at": "2025-11-12T15:23:15.184622+00:00",
      "target_application_form": {
        "application_form_id": "d5498d5b-5970-4df6-b15a-b6466b7a9167",
        "competition_form_id": "b5d632b1-b534-4e94-882c-db10fed3fc5a",
        "form_id": "1623b310-85be-496a-b84b-34bdee22a68a",
        "form_name": "Application for Federal Assistance (SF-424)"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "attachment_added",
      "application_audit_id": "70dacc65-aa2e-4581-8cd7-bff2e514c454",
      "created_at": "2025-11-12T15:23:05.560928+00:00",
      "target_application_form": null,
      "target_attachment": {
        "application_attachment_id": "e80210e9-1d9d-45fa-bf3d-c391902fad77",
        "file_name": "GG_LobbyingForm-V1.1.pdf",
        "is_deleted": false
      },
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "form_updated",
      "application_audit_id": "607c9d0c-0fab-41fe-b82f-14e091a38928",
      "created_at": "2025-11-12T15:22:32.893444+00:00",
      "target_application_form": {
        "application_form_id": "d5498d5b-5970-4df6-b15a-b6466b7a9167",
        "competition_form_id": "b5d632b1-b534-4e94-882c-db10fed3fc5a",
        "form_id": "1623b310-85be-496a-b84b-34bdee22a68a",
        "form_name": "Application for Federal Assistance (SF-424)"
      },
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "user_added",
      "application_audit_id": "87b6f158-7bad-474f-8de3-a5904cada553",
      "created_at": "2025-11-12T15:22:19.900640+00:00",
      "target_application_form": null,
      "target_attachment": null,
      "target_user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      },
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    },
    {
      "application_audit_event": "application_created",
      "application_audit_id": "202bbb0a-b82c-43b8-b73c-cf173a6fd4d2",
      "created_at": "2025-11-12T15:22:19.900619+00:00",
      "target_application_form": null,
      "target_attachment": null,
      "target_user": null,
      "user": {
        "email": "[email protected]",
        "first_name": null,
        "last_name": null,
        "user_id": "5b4807c5-57d4-4867-b722-1658b47c59ba"
      }
    }
  ],
  "message": "Success",
  "pagination_info": {
    "page_offset": 1,
    "page_size": 25,
    "sort_order": [
      {
        "order_by": "created_at",
        "sort_direction": "descending"
      }
    ],
    "total_pages": 1,
    "total_records": 17
  },
  "status_code": 200
}
```

</details>
chouinar and others added 14 commits November 19, 2025 14:12
## Summary
Work for #6905 

## Changes proposed
* Adds the EPA Form 4700-4

## Context for reviewers
https://www.grants.gov/forms/form-items-description/fid/773

This form has a lot of fields, and handles addresses/names a bit
different than other forms, so did a little restructuring of the shared
schemas to leverage what does overlap.

Note that the exact way we want to format this probably needs a bit of
cleanup, I got all the fields down and ordered, but didn't try to make
it look nice.

## Validation steps
If you want to see the form locally:

Run `make db-migrate db-seed-local` to get form setup locally.

Login as the `many_app_user` and go to
http://localhost:3000/applications - find the application associated
with the EPA form. It should look something like (not all of it, it's
pretty long):
<img width="803" height="758" alt="Screenshot 2025-11-18 at 2 24 46 PM"
src="https://github.com/user-attachments/assets/7ce088dc-57d0-4dc6-b2e9-d70cac71cfa2"
/>
<img width="489" height="737" alt="Screenshot 2025-11-18 at 2 24 52 PM"
src="https://github.com/user-attachments/assets/36f5d807-831e-42f3-87d4-a9d14cc399f1"
/>
<img width="482" height="722" alt="Screenshot 2025-11-18 at 2 24 56 PM"
src="https://github.com/user-attachments/assets/165ac530-78ee-4461-afb7-7127a792b9eb"
/>
<img width="707" height="775" alt="Screenshot 2025-11-18 at 2 25 03 PM"
src="https://github.com/user-attachments/assets/5aee544d-9293-4885-9b61-a0da1721c3aa"
/>
## Summary

Added documentation to make it easier for windows users to get started
with the API.
## Summary

Updated GitHub workflows to reduce slack notifications. 

## Validation steps

All workflows should continue to work as is except slack notifications
should only be triggered when merged into main or when a release is
created.
…6862)

## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Work for #6861  

## Changes proposed

Change from the old, depreciated non-namespaced package, to the new
namespaced one.

## Context for reviewers

This is reacting to a warning during the build process about the package
we had been referencing being depreciated

## Validation steps

Check out the branch, ensure that form functionality works with the more
current version of the package.
…cs (#7180)

Automated update of ERD diagrams and OpenAPI specs.

Co-authored-by: nava-platform-bot <[email protected]>
## Summary

Clean up unused ecr images. Scheduled as a daily cron at 5am. 

## Validation steps

The new workflow job: ECR Cleanup should run and print out what ecr
tags/images where deleted.
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Work for #6955 

## Changes proposed

Prettifying the layout for the Form CD511.

## Context for reviewers

Most of this work was previously done by @chouinar, this is just making
the large text section at the top more readable.

## Validation steps

A local opportunity linked to this form can be found by running `make
db-seed-local` and searching the output for "CD511".

- [ ] Successfully start an application against this form
- [ ] Ensure the form looks correct
- [ ] Ensure the form can be saved
- [ ] Ensure the application can be submitted
- [ ] Check the print setup to make sure that the PDF looks correct
## Summary

Work for #6925 

## Changes proposed

This PR displays the users who have received an invitation
Unit test will come in after the page is put together

## Validation steps

- to run locally, you would need to `run npm run build && npm start
- `make remake-backend && docker compose up`
- navigate to feature flags (http://localhost:3000/dev/feature-flags)
- make sure that `manageUsersOff` is set to `disabled`
- sign into the app as "two_org_user"
- navigate to Workspace > Activity Dashboard
- scroll to the bottom and "View Organization Details"
- click "Manage Users"
- invite a user and VERIFY that is shows up in the table
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes for #6949  

## Changes proposed

Add `tuser_profile` and `vuser_account` tables to the load job for
hourly sync.

## Context for reviewers
Foreign and legacy tables have been successfully added in the staging
environment.
The load job was tested locally against the staging environment, and
data was confirmed to sync successfully.
## Summary
- Added comprehensive AWS Security Hub Terraform configuration
- Configured finding aggregation across all AWS regions for centralized
monitoring
- Added product subscriptions for AWS security services (GuardDuty,
Inspector, Access Analyzer, Firewall Manager, Systems Manager, Health,
Macie)
- Created custom security insights for critical/high severity findings,
failed CIS controls, and public/exposed resources

## Test plan
- [ ] Run `terraform init` and `terraform plan` in the `infra/accounts/`
directory
- [ ] Review the planned changes to ensure Security Hub resources will
be created correctly
- [ ] Apply with `terraform apply` to provision Security Hub
configuration
- [ ] Verify in AWS Console that Security Hub is enabled with all four
standards
- [ ] Verify finding aggregation is configured for all regions
- [ ] Verify product subscriptions are active (note: some services like
GuardDuty, Inspector, Macie need to be enabled separately if not already
active)
- [ ] Check that custom insights appear in the Security Hub console

## Notes
Some product integrations require the underlying services to be enabled
first. If GuardDuty, Inspector, or Macie are not enabled in your
account, those specific product subscription resources may fail and can
be removed or commented out.

---------

Co-authored-by: Sean Thomas <[email protected]>
## Summary

<!-- Use "Fixes" to automatically close issue upon PR merge. Use "Work
for" when UAT is required. -->
Fixes #7145

## Changes proposed

<!-- What was added, updated, or removed in this PR. -->
Make slight tweaks to existing SF424A XML transforms, necessary once we
started generating complete XML to validate e.g. remove `version`,
rename `glob:FormVersionIdentifier` to `FormVersionIdentifier`
Fixes issue where root element name was incorrectly used as namespace
prefix
Add transforms for all 6 major XML sections
Add e2e/unit tests for XSD compliance.
Add examples in key complex areas.
Added SF424A support to `generate-xml` command
Updated `validate-xml-generation` to include SF-424A tests
Remove an invalid test for missing namespace versions (for SF-424A it
should not be required)


## Context for reviewers

<!-- Technical or background context, more in-depth details of the
implementation, and anything else you'd like reviewers to know about
that will help them understand the changes in the PR. -->
We may not want to call this complete yet until we see some real XML and
validate. For now we are generating XSD-compliant XML, which is good.
There are a few XML generation architectural changes here. All of them
needed to satisfy the PR, so it made sense to include them despite being
a larger PR. Subsequent forms should not need this level of changes.

## Validation steps

<!-- Manual testing instructions, as well as any helpful references
(screenshots, GIF demos, code examples or output). -->

To run CLI validation, run:
``` 
docker compose run --rm grants-api poetry run python -m flask --app src.app task validate-xml-generation --form SF424A
```

To see CLI output, save a JSON file named `sf424a.json` e.g.:
```
{
  "program_type": "Non-Construction",
  "form_version_identifier": "1.0",
  "activity_line_items": [
    {
      "activity_title": "Research Activity",
      "budget_summary": {
        "assistance_listing_number": "93.001",
        "federal_estimated_unobligated_amount": "1000.00",
        "non_federal_estimated_unobligated_amount": "500.00",
        "federal_new_or_revised_amount": "50000.00",
        "non_federal_new_or_revised_amount": "10000.00",
        "total_new_or_revised_amount": "61500.00"
      },
      "budget_categories": {
        "personnel_amount": "30000.00",
        "fringe_benefits_amount": "8000.00"
      },
      "non_federal_resources": {
        "applicant_amount": "5000.00",
        "total_amount": "5000.00"
      },
      "federal_fund_estimates": {
        "first_year_amount": "50000.00"
      }
    }
  ],
  "total_budget_summary": {
    "federal_estimated_unobligated_amount": "1000.00",
    "non_federal_estimated_unobligated_amount": "500.00",
    "federal_new_or_revised_amount": "50000.00",
    "non_federal_new_or_revised_amount": "10000.00",
    "total_new_or_revised_amount": "61500.00"
  },
  "total_budget_categories": {
    "personnel_amount": "30000.00",
    "fringe_benefits_amount": "8000.00"
  },
  "total_non_federal_resources": {
    "applicant_amount": "5000.00",
    "total_amount": "5000.00"
  },
  "total_federal_fund_estimates": {
    "first_year_amount": "50000.00"
  }
}
```

Then run

```
docker compose run --rm grants-api poetry run python -m flask --app src.app task generate-xml --file sf424a.json --form SF424A
```

See XML output like:
```
<?xml version='1.0' encoding='utf-8'?>
<SF424A:BudgetInformation xmlns:SF424A="http://apply.grants.gov/forms/SF424A-V1.0" xmlns:glob="http://apply.grants.gov/system/Global-V1.0" SF424A:programType="Non-Construction" glob:coreSchemaVersion="1.0">
  <glob:FormVersionIdentifier>1.0</glob:FormVersionIdentifier>
  <SF424A:BudgetSummary>
    <SF424A:SummaryLineItem SF424A:activityTitle="Research Activity">
      <SF424A:CFDANumber>93.001</SF424A:CFDANumber>
      <SF424A:BudgetFederalEstimatedUnobligatedAmount>1000.00</SF424A:BudgetFederalEstimatedUnobligatedAmount>
      <SF424A:BudgetNonFederalEstimatedUnobligatedAmount>500.00</SF424A:BudgetNonFederalEstimatedUnobligatedAmount>
      <SF424A:BudgetFederalNewOrRevisedAmount>50000.00</SF424A:BudgetFederalNewOrRevisedAmount>
      <SF424A:BudgetNonFederalNewOrRevisedAmount>10000.00</SF424A:BudgetNonFederalNewOrRevisedAmount>
      <SF424A:BudgetTotalNewOrRevisedAmount>61500.00</SF424A:BudgetTotalNewOrRevisedAmount>
    </SF424A:SummaryLineItem>
    <SF424A:SummaryTotals>
      <SF424A:BudgetFederalEstimatedUnobligatedAmount>1000.00</SF424A:BudgetFederalEstimatedUnobligatedAmount>
      <SF424A:BudgetNonFederalEstimatedUnobligatedAmount>500.00</SF424A:BudgetNonFederalEstimatedUnobligatedAmount>
      <SF424A:BudgetFederalNewOrRevisedAmount>50000.00</SF424A:BudgetFederalNewOrRevisedAmount>
      <SF424A:BudgetNonFederalNewOrRevisedAmount>10000.00</SF424A:BudgetNonFederalNewOrRevisedAmount>
      <SF424A:BudgetTotalNewOrRevisedAmount>61500.00</SF424A:BudgetTotalNewOrRevisedAmount>
    </SF424A:SummaryTotals>
  </SF424A:BudgetSummary>
  <SF424A:BudgetCategories>
    <SF424A:CategorySet SF424A:activityTitle="Research Activity">
      <SF424A:BudgetPersonnelRequestedAmount>30000.00</SF424A:BudgetPersonnelRequestedAmount>
      <SF424A:BudgetFringeBenefitsRequestedAmount>8000.00</SF424A:BudgetFringeBenefitsRequestedAmount>
    </SF424A:CategorySet>
    <SF424A:CategoryTotals>
      <SF424A:BudgetPersonnelRequestedAmount>30000.00</SF424A:BudgetPersonnelRequestedAmount>
      <SF424A:BudgetFringeBenefitsRequestedAmount>8000.00</SF424A:BudgetFringeBenefitsRequestedAmount>
    </SF424A:CategoryTotals>
  </SF424A:BudgetCategories>
  <SF424A:NonFederalResources>
    <SF424A:ResourceLineItem SF424A:activityTitle="Research Activity">
      <SF424A:BudgetApplicantContributionAmount>5000.00</SF424A:BudgetApplicantContributionAmount>
      <SF424A:BudgetTotalContributionAmount>5000.00</SF424A:BudgetTotalContributionAmount>
    </SF424A:ResourceLineItem>
    <SF424A:ResourceTotals>
      <SF424A:BudgetApplicantContributionAmount>5000.00</SF424A:BudgetApplicantContributionAmount>
      <SF424A:BudgetTotalContributionAmount>5000.00</SF424A:BudgetTotalContributionAmount>
    </SF424A:ResourceTotals>
  </SF424A:NonFederalResources>
  <SF424A:FederalFundsNeeded>
    <SF424A:FundsLineItem SF424A:activityTitle="Research Activity">
      <SF424A:BudgetFirstYearAmount>50000.00</SF424A:BudgetFirstYearAmount>
    </SF424A:FundsLineItem>
    <SF424A:FundsTotals>
      <SF424A:BudgetFirstYearAmount>50000.00</SF424A:BudgetFirstYearAmount>
    </SF424A:FundsTotals>
  </SF424A:FederalFundsNeeded>
</SF424A:BudgetInformation>
```
Copy link
Collaborator

@doug-s-nava doug-s-nava left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what happened with the commit history here but I'd only expect one commit with a couple of files changed. Can you try and clean that up?

@hao10282025-sudo
Copy link
Collaborator Author

not sure what happened with the commit history here but I'd only expect one commit with a couple of files changed. Can you try and clean that up?

Hi Doug, thanks for your review. The extra commits you see is because I did a rebase from main branch, and these extra commits are the ones between my "outdated" commits and the latest fix, from other developers. To me it is not a problem, as Microsoft TFS has same behavior if one forgot to do "git pull" (when there is other's commits) before "git push", the actual commit log will have others commits too.
extra commits for git rebase
I do understand the concern on these extras looks not feeling good. I actually can PR these document changes together with my next DB change and discard this one. If sounds okay to you @doug-s-nava, @mdragon

@hao10282025-sudo
Copy link
Collaborator Author

PR is discarded, the changes will be move to a new one

@hao10282025-sudo hao10282025-sudo deleted the haowang/onboarding branch November 24, 2025 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.