Skip to content

Update GC Forms extension integration#34

Merged
omarmir merged 1 commit into
mainfrom
gcform-ext-changes
May 18, 2026
Merged

Update GC Forms extension integration#34
omarmir merged 1 commit into
mainfrom
gcform-ext-changes

Conversation

@omarmir

@omarmir omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds the host extension configuration page route and wiring for extensions that own page-based stream configuration UI.
  • Updates seed/config data for the GC Forms claim integration and agency identity provider settings.
  • Adds host claim submission UUID storage and advances submodule pointers for the SDK and GC Forms extension work.

Depends on

Validation

  • bun run lint
  • bun run typecheck
  • bun run test:unit
  • bun run test:coverage
  • bun run test:e2e:light:spec tests/e2e/automated-payment-lifecycle.spec.ts
  • Manual Playwright check of /extension/gcs-gcforms-integration/config for stream 31 mapping table default expansion

Ready for review.

Summary by CodeRabbit

  • New Features

    • Added stream-based extension configuration enabling per-stream setup of extensions with dedicated configuration pages and navigation flow.
  • Database

    • Added tracking support for GC Forms submission identifiers in funding case agreements.
  • Updates

    • Updated extension configuration structure to support new admin metadata for stream-based configuration pages.
    • Revised GCForms extension configuration format.
  • Localization

    • Added English and French translation strings for stream-based extension configuration interface.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@omarmir has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 38 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aaae895e-26b7-42a1-8811-761ed39529aa

📥 Commits

Reviewing files that changed from the base of the PR and between a9ae5e2 and 1a222a0.

📒 Files selected for processing (13)
  • app/components/Extension/StreamExtensionsTab.vue
  • app/pages/extension/[id]/config.vue
  • app/utils/route-locations.ts
  • extensions/gcs-gcforms-integration
  • i18n/locales/en.json
  • i18n/locales/fr.json
  • modules/gcs-extensions.ts
  • packages/gcs-ssc-extensions
  • server/database/migrations/0009_funding_case_agreement.ts
  • server/database/migrations/9999_seed.ts
  • shared/types/database.d.ts
  • tests/unit/extensions-core.test.ts
  • tests/unit/seed-advance-assessment.test.ts
📝 Walkthrough

Walkthrough

This pull request introduces stream-based extension configuration, enabling operators to configure extensions on specific streams through a new dynamically-routed page. It restructures GCForms extension metadata and seed configuration, adds database persistence for form submission tracking, and updates extension metadata resolution to support the new streamConfigPage component field.

Changes

Stream-Based Extension Configuration

Layer / File(s) Summary
Route definition and navigation
app/utils/route-locations.ts, app/components/Extension/StreamExtensionsTab.vue
extensionStreamConfig route helper accepts streamId plus optional transferPaymentId and agencyId query parameters. StreamExtensionsTab checks for admin.streamConfigPage.componentName and navigates conditionally; otherwise falls back to openConfigure.
Extension stream configuration page and localization
app/pages/extension/[id]/config.vue, i18n/locales/en.json, i18n/locales/fr.json
New page loads extension registry, profile, and stream data; resolves and renders dynamic config component from extension metadata with v-model binding; includes loading/error states and i18n-aware messaging for missing stream ID or unavailable configuration.
Extension metadata resolution and component registration
modules/gcs-extensions.ts
resolveExtensionAdmin resolves streamConfigPage via resolveComponent; serializeExtension includes streamConfigPage in generated metadata; getExtensionComponentDefinitions discovers streamConfigPage; buildExtensionComponentRegistry conditionally registers it as ExtensionStreamConfigPage.
Database schema for GCForms submission tracking
server/database/migrations/0009_funding_case_agreement.ts, shared/types/database.d.ts
Adds nullable egcs_fc_gcformssubmissionuuid column and partial unique index on non-deleted claim rows to enforce submission UUID uniqueness.
GCForms extension configuration restructuring
server/database/migrations/9999_seed.ts
Removes __gcforms_final_for_year mapping; adds claim line-item field mappings (cost category, subsection, line item, amount); nests claim configuration under claim object with formId; extends agency enablement with identityProviderUrl and confirmSubmissions: false.
Test suite updates
tests/unit/extensions-core.test.ts, tests/unit/seed-advance-assessment.test.ts
Extension core tests verify streamConfigPage metadata preservation and ExtensionStreamConfigPage naming; seed test asserts new configuration structure and confirms removal of final-for-year mapping.
Dependency updates
extensions/gcs-gcforms-integration, packages/gcs-ssc-extensions
Git submodule pointers updated to newer commits.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A new path for streams to configure,
Dynamic components now sure,
Metadata flows where forms belong,
With databases strong and tests all sung!
Nested claims make the GCForms sing! 🎵

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: updating the GC Forms extension integration with new route-based configuration, seed data updates, and submodule pointers.
Description check ✅ Passed The PR description provides a clear summary of changes, lists dependencies, and documents comprehensive validation steps, but the quality checklist template items are not checked off.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gcform-ext-changes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@omarmir omarmir force-pushed the gcform-ext-changes branch from 6d5a84b to 911680e Compare May 18, 2026 07:21

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request implements a dedicated configuration page for extensions by introducing the streamConfigPage property in the extension metadata. It includes the new page component, routing logic, and internationalization strings. Additionally, the database schema is updated to include a GC Forms submission UUID, and seed data is refined for better claim mapping. The review feedback suggests enhancing the robustness of the data fetching process on the new configuration page by ensuring that failures in retrieving non-essential breadcrumb data do not block the primary configuration functionality.

Comment on lines +90 to +118
try {
isLoading.value = true
loadError.value = null
const [extensionResponse, profileResponse, streamResponse] = await Promise.all([
fetch(getClientRequestUrl(`/api/extensions/streams/${streamId.value}`)),
transferPaymentId.value ? fetch(getClientRequestUrl(`/api/transfer-payments/${transferPaymentId.value}`)) : Promise.resolve(null),
transferPaymentId.value ? fetch(getClientRequestUrl(`/api/transfer-payments/${transferPaymentId.value}/streams/${streamId.value}`)) : Promise.resolve(null)
])

if (!extensionResponse.ok) await throwFetchResponseError(extensionResponse)
if (profileResponse && !profileResponse.ok) await throwFetchResponseError(profileResponse)
if (streamResponse && !streamResponse.ok) await throwFetchResponseError(streamResponse)

const payload = await extensionResponse.json() as ExtensionStreamRegistryResponse
item.value = payload.items.find(row => row.extension.key === extensionKey) ?? null
profile.value = profileResponse ? await profileResponse.json() as TransferPaymentProfileItem : null
stream.value = streamResponse ? await streamResponse.json() as TransferPaymentStreamItem : null

if (!item.value) {
throw new Error(t('apiErrors.extensions.not_found'))
}

resetDraft(item.value.config)
} catch (error: unknown) {
loadError.value = error
showError(error)
} finally {
isLoading.value = false
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current implementation of the refresh function fetches both essential extension data and secondary breadcrumb data within a single Promise.all. This means that if the fetches for breadcrumb data (profile or stream) fail, the entire page will render an error state, preventing the user from configuring the extension.

To improve robustness, consider handling failures in fetching breadcrumb data gracefully (e.g., by logging it and showing a toast notification) without blocking the primary functionality of the page.

  try {
    isLoading.value = true
    loadError.value = null
    const [extensionResponse, profileResponse, streamResponse] = await Promise.all([
      fetch(getClientRequestUrl(`/api/extensions/streams/${streamId.value}`)),
      transferPaymentId.value ? fetch(getClientRequestUrl(`/api/transfer-payments/${transferPaymentId.value}`)) : Promise.resolve(null),
      transferPaymentId.value ? fetch(getClientRequestUrl(`/api/transfer-payments/${transferPaymentId.value}/streams/${streamId.value}`)) : Promise.resolve(null)
    ])

    if (!extensionResponse.ok) await throwFetchResponseError(extensionResponse)

    // Gracefully handle breadcrumb fetch errors
    if (profileResponse && !profileResponse.ok) {
      showError(new Error('Failed to load profile for breadcrumbs'))
    }
    if (streamResponse && !streamResponse.ok) {
      showError(new Error('Failed to load stream for breadcrumbs'))
    }

    const payload = await extensionResponse.json() as ExtensionStreamRegistryResponse
    item.value = payload.items.find(row => row.extension.key === extensionKey) ?? null
    profile.value = profileResponse?.ok ? await profileResponse.json() as TransferPaymentProfileItem : null
    stream.value = streamResponse?.ok ? await streamResponse.json() as TransferPaymentStreamItem : null

    if (!item.value) {
      throw new Error(t('apiErrors.extensions.not_found'))
    }

    resetDraft(item.value.config)
  } catch (error: unknown) {
    loadError.value = error
    showError(error)
  } finally {
    isLoading.value = false
  }

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in the current commit. The required extension registry fetch now runs independently, and the optional profile/stream breadcrumb fetches are consumed through fetchOptionalJson, which catches failures, shows the existing error toast, and returns null without setting the page-level load error.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Confirmed against current commit 1dab0a2: the extension registry fetch is awaited independently, and the optional transfer payment / stream breadcrumb fetches are wrapped in fetchOptionalJson, which catches failures and returns null. Optional breadcrumb failures no longer block the configuration page.

@omarmir omarmir force-pushed the gcform-ext-changes branch 2 times, most recently from 8f0161c to fe10ed5 Compare May 18, 2026 07:36
@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@omarmir omarmir force-pushed the gcform-ext-changes branch from fe10ed5 to 25ab233 Compare May 18, 2026 15:49
@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review
/gemini

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@omarmir, triggering a review of PR #34 now. Note that /gemini is not a recognized CodeRabbit command — if you intended to invoke a different AI reviewer, please check your integrations. CodeRabbit will proceed with its own review.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@omarmir omarmir force-pushed the gcform-ext-changes branch from 25ab233 to 1dab0a2 Compare May 18, 2026 16:06
@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review
/gemini

@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@omarmir, triggering a review of PR #34 now. As noted previously, /gemini is not a recognized CodeRabbit command — if you're looking to invoke a specific AI model or integration, please verify your integrations configuration. CodeRabbit will proceed with its own review.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@omarmir omarmir force-pushed the gcform-ext-changes branch from 1dab0a2 to a55125b Compare May 18, 2026 16:23
@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review
/gemini

@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@omarmir, triggering a review of PR #34 now. Just a friendly note — /gemini is not a recognized CodeRabbit command, so it won't invoke any additional AI model. If you're looking to use a different reviewer integration, please check your repository's integrations settings. CodeRabbit will proceed with its own review.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@omarmir omarmir force-pushed the gcform-ext-changes branch from a55125b to a9ae5e2 Compare May 18, 2026 16:29
@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review
/gemini

@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@omarmir, triggering a review of PR #34 now. As a reminder, /gemini is not a recognized CodeRabbit command and won't invoke any additional AI model — CodeRabbit will proceed with its own review. If you'd like to use a different AI reviewer, please verify your repository's integrations settings.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/components/Extension/StreamExtensionsTab.vue`:
- Around line 75-81: The click handler openConfiguration dereferences
item.extension without guarding for null which can throw; update
openConfiguration to first check that item.extension exists and that
item.extension.admin.streamConfigPage?.componentName is truthy before calling
navigateTo(localePath(appRouteLocations.extensionStreamConfig(...))); if
item.extension is null/undefined, call the existing fallback openConfigure
instead. Ensure you reference the same symbols (openConfiguration,
item.extension, openConfigure, navigateTo, localePath,
appRouteLocations.extensionStreamConfig) when adding the null-check and
branching logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 33f2b184-2f64-4125-a582-8776696dc806

📥 Commits

Reviewing files that changed from the base of the PR and between 4434f49 and a9ae5e2.

📒 Files selected for processing (13)
  • app/components/Extension/StreamExtensionsTab.vue
  • app/pages/extension/[id]/config.vue
  • app/utils/route-locations.ts
  • extensions/gcs-gcforms-integration
  • i18n/locales/en.json
  • i18n/locales/fr.json
  • modules/gcs-extensions.ts
  • packages/gcs-ssc-extensions
  • server/database/migrations/0009_funding_case_agreement.ts
  • server/database/migrations/9999_seed.ts
  • shared/types/database.d.ts
  • tests/unit/extensions-core.test.ts
  • tests/unit/seed-advance-assessment.test.ts

Comment thread app/components/Extension/StreamExtensionsTab.vue
@omarmir omarmir force-pushed the gcform-ext-changes branch from a9ae5e2 to 1a222a0 Compare May 18, 2026 17:07
@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini

@omarmir

omarmir commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review
/gemini

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@omarmir, triggering a review of PR #34 now. As a reminder, /gemini is not a recognized CodeRabbit command — if you're looking to use a different AI reviewer, please verify your repository's integrations settings. CodeRabbit will proceed with its own review.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@omarmir omarmir merged commit 89d803b into main May 18, 2026
2 checks passed
@omarmir omarmir deleted the gcform-ext-changes branch May 18, 2026 17:26
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.

1 participant