-
Notifications
You must be signed in to change notification settings - Fork 7
Frontend/admin search update #1234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Frontend/admin search update #1234
Conversation
- Renamed unusable list / paging components as Legacy - Added new blank components that will hold new core list / paging functionality
- Implement roughed out version of standard paging for staff licensee search
- Implement roughed out version of the admin search form - Implement roughed out version of server payload prep for the opensearch provider query
- Add search terms display to list view - Style the new paging UI - Updates to opensearch queries
- Added the provider vs. privilege search UI variants - Added an export-only UI flow to the privilege search
- Moved the search API to a new network folder - Added env param for search API URI - Added env param for specifically disabling statsig - Updated opensearch syntax to keyword for sort fields
- Updated queries for more complex nested search scenarios - Started testing with privilege export CSVs - Disabled the military status search until the next PR
- Added window function to log query output for helping with query debugging as needed - Minor updates to pagination
📝 WalkthroughWalkthroughThis PR implements enhanced licensee and privilege search/export functionality with a new search API infrastructure, introduces dual paging implementations (modern and legacy), refactors licensing list components with new search parameters (state variants, dates, military/investigation status, NPI), and adds UI controls for search type selection and direct export capabilities. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client/Component
participant LicenseeList
participant LicenseeSearch
participant DataApi
participant SearchDataApi
participant Store
participant Server
Client->>LicenseeSearch: User selects provider search
LicenseeSearch->>LicenseeSearch: updateSearchType()
Client->>LicenseeSearch: User enters search criteria
LicenseeSearch->>LicenseeList: emit searchParams (searchType, fields)
LicenseeList->>LicenseeList: prepareSearchBody()
LicenseeList->>LicenseeList: fetchListData()
LicenseeList->>DataApi: getLicenseesSearchStaff(params)
DataApi->>SearchDataApi: getLicenseesSearchStaff(params)
SearchDataApi->>SearchDataApi: prepRequestSearchParams()
SearchDataApi->>Server: POST search query (Elasticsearch)
Server-->>SearchDataApi: licensees results
SearchDataApi->>Store: dispatch setStoreLicensees
Store-->>LicenseeList: updated licensees
LicenseeList-->>Client: render results list
sequenceDiagram
participant Client as Client/Component
participant LicenseeSearch
participant LicenseeList
participant DataApi
participant SearchDataApi
participant Server
Client->>LicenseeSearch: User selects privilege search
LicenseeSearch->>LicenseeSearch: updateSearchType(SearchTypes.PRIVILEGES)
Client->>LicenseeSearch: User enters privilege criteria
LicenseeSearch->>LicenseeList: emit searchParams (isDirectExport: true)
LicenseeList->>LicenseeList: fetchListData()
LicenseeList->>LicenseeList: handlePrivilegeDownload()
LicenseeList->>DataApi: getPrivilegesExportStaff(params)
DataApi->>SearchDataApi: getPrivilegesExportStaff(params)
SearchDataApi->>SearchDataApi: prepRequestSearchParams()
SearchDataApi->>Server: POST export request
Server-->>SearchDataApi: fileUrl
SearchDataApi->>LicenseeList: response with fileUrl
LicenseeList->>Store: dispatch setStoreExporting(false)
LicenseeList-->>Client: trigger file download
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🧹 Nitpick comments (15)
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.spec.ts (1)
16-17: Redundant assertion in test.Line 17 checks if the mounted component exists by finding itself, which duplicates the check on line 16. Since
wrapperis already the LicenseeSearch component, the second assertion is unnecessary.🔎 Optional: Simplify the test by removing the redundant assertion
it('should mount the component', async () => { const wrapper = await mountShallow(LicenseeSearch); expect(wrapper.exists()).to.equal(true); - expect(wrapper.findComponent(LicenseeSearch).exists()).to.equal(true); });webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.ts (1)
39-39: Class name mismatch with component name.The class is named
Paginationbut the component decorator specifiesname: 'PaginationLegacy'. This inconsistency could cause confusion when debugging or searching the codebase.🔎 Suggested fix:
-export default class Pagination extends mixins(MixinForm) { +export default class PaginationLegacy extends mixins(MixinForm) {webroot/src/network/searchApi/interceptors.ts (1)
78-82:requestErroris not included in the default export.The
requestErrorfunction is exported individually but omitted from the default export object. If consumers rely on the default export for all interceptors, they'll missrequestError. This may be intentional ifrequestErroris rarely needed.🔎 Suggested fix if this was unintentional:
export default { requestSuccess, + requestError, responseSuccess, responseError, };webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts (1)
33-33: Class name mismatch with component name.Similar to
PaginationLegacy.ts, the class is namedLicenseeListbut the component decorator specifiesname: 'LicenseeListLegacy'. Consider renaming for consistency.🔎 Suggested fix:
-class LicenseeList extends Vue { +class LicenseeListLegacy extends Vue {webroot/src/components/Lists/ListContainer/ListContainer.spec.ts (1)
12-12: Consider adding tests for the new pagination path.All tests now reference
PaginationLegacy, which aligns with the defaultisLegacyPaging: truebehavior. However, according to the AI summary,ListContainersupports a new pagination component whenisLegacyPagingis false. Consider adding tests to cover this new code path.🔎 Example test to add:
it('should render modern Pagination when isLegacyPaging is false', async () => { const wrapper = await mountShallow(ListContainer, { props: { listData: ['x'], paginationId: 'component', pageChange: () => null, isLegacyPaging: false, sortOptions: [] }, }); expect(wrapper.findAllComponents(Pagination).length).to.equal(2); expect(wrapper.findAllComponents(PaginationLegacy).length).to.equal(0); });Also applies to: 44-44, 60-60, 75-75, 90-90, 106-106
webroot/src/pages/LicensingList/LicensingList.vue (1)
10-10: Consider removing or documenting the commented code.The commented-out
LicenseeListLegacycomponent doesn't affect runtime behavior, but commented code can accumulate and reduce maintainability. If this is intentionally kept for easy toggling during development, consider:
- Adding a comment explaining why it's kept
- Using a prop/config to switch between legacy/new list instead
- Removing it and relying on version control
webroot/src/store/license/license.state.ts (1)
7-8: Consider importing types from.tsfiles instead of.vuefiles.Importing interfaces from
.vuefiles works but is unconventional. The relevant code snippets show these interfaces are defined in the corresponding.tsfiles (LicenseeSearchLegacy.tsandLicenseeSearch.ts). Importing from the TypeScript modules directly would be more idiomatic.🔎 Suggested change:
-import { LicenseSearchLegacy } from '@components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vue'; -import { LicenseSearch } from '@components/Licensee/LicenseeSearch/LicenseeSearch.vue'; +import { LicenseSearchLegacy } from '@components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy'; +import { LicenseSearch } from '@components/Licensee/LicenseeSearch/LicenseeSearch';webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.ts (1)
11-11: Misleading import alias: rename to match component name.The import alias
LicenseeListis confusing since the component being tested isLicenseeListLegacy. This could cause confusion when reading the test file.🔎 Apply this diff to improve clarity:
-import LicenseeList from '@components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue'; +import LicenseeListLegacy from '@components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue';Then update usages in the test file:
-describe('LicenseeList component', async () => { +describe('LicenseeListLegacy component', async () => {webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue (1)
43-44: Consider removingthis.prefix in template expressions.Using
this.licenseStore.modelin Vue 3 templates is non-standard. While it works, the conventional approach is to access component properties directly withoutthis.in templates.🔎 Apply this diff for consistency:
- :listData="this.licenseStore.model" - :listSize="this.licenseStore.total" + :listData="licenseStore.model" + :listSize="licenseStore.total"- v-for="(record, index) in this.licenseStore.model" + v-for="(record, index) in licenseStore.model"Also applies to: 68-68
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue (1)
82-83: Hardcoded year 2025 in yearRange will require updates.The
yearRangestarts at 2025, which will need to be updated annually. Consider making this dynamic or configurable.🔎 Suggested approach:
You could compute a dynamic start year in the component's TypeScript file:
// In LicenseeSearch.ts get privilegeSearchStartYear(): number { return 2025; // Or derive from compact configuration/launch date }Then use it in the template:
- :yearRange="[2025, new Date().getFullYear()]" + :yearRange="[privilegeSearchStartYear, new Date().getFullYear()]"Also applies to: 92-93
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts (2)
65-77: Consider adding explicit return type annotation.The
compactOptionsgetter returnsArray<any>, but the structure is well-defined. Consider using a more specific type for better type safety.🔎 Suggested type improvement:
- get compactOptions(): Array<any> { + get compactOptions(): Array<{ value: string, name: string | ReturnType<typeof computed> }> {
87-102: Consider refininganytype usage.The
defaultSelectOptionis typed asanybut has a predictable shape. This aligns with the PR TODO to replace TypeScriptanytypes.🔎 Suggested type improvement:
- const defaultSelectOption: any = { value: '' }; + const defaultSelectOption: { value: string; name: string | ReturnType<typeof computed> } = { value: '', name: '' }; if (!compactMemberStates.length) { defaultSelectOption.name = ''; } else { defaultSelectOption.name = computed(() => this.$t('common.selectOption')); }webroot/src/network/searchApi/data.api.ts (2)
370-378: Minor: Typo in variable name.
serverReponseshould beserverResponse(missing 's'). This appears in bothgetLicenseesSearchStaffandgetPrivilegesExportStaff.🔎 Suggested fix:
- const serverReponse: any = await this.api.post(`/v1/compacts/${params.compact}/providers/search`, requestParams); - const { total = {}, providers } = serverReponse; + const serverResponse: any = await this.api.post(`/v1/compacts/${params.compact}/providers/search`, requestParams); + const { total = {}, providers } = serverResponse;And similarly at line 395:
- const serverReponse: any = await this.api.post(`/v1/compacts/${params.compact}/privileges/export`, requestParams); + const serverResponse: any = await this.api.post(`/v1/compacts/${params.compact}/privileges/export`, requestParams); - return serverReponse; + return serverResponse;
399-402: Remove commented-out debug code.The commented mock URL block appears to be leftover development code. Consider removing it to keep the codebase clean.
🔎 Suggested removal:
return serverReponse; - - // return { - // downloadUrl: 'https://cdn.prod.website-files.com/66a083c22bdfd06a6aee5193/6913a447111789a56d2f13b9_IA-Logo-Primary-FullColor.svg', - // }; }webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts (1)
322-326: Consider consolidating search type state.The
selectedSearchTypedata property duplicates state fromformData.searchType.value. Consider using a computed getter instead to avoid potential sync issues:get selectedSearchType(): SearchTypes { return this.formData?.searchType?.value || SearchTypes.PROVIDER; }Alternatively, ensure
updateSearchType()is called consistently whenever the radio input changes.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (51)
.github/workflows/check-webroot.yml(2 hunks)webroot/.env.example(2 hunks)webroot/README.md(2 hunks)webroot/src/components/Forms/InputSubmit/InputSubmit.ts(1 hunks)webroot/src/components/Forms/InputSubmit/InputSubmit.vue(1 hunks)webroot/src/components/Licensee/LicenseeList/LicenseeList.less(3 hunks)webroot/src/components/Licensee/LicenseeList/LicenseeList.spec.ts(1 hunks)webroot/src/components/Licensee/LicenseeList/LicenseeList.ts(7 hunks)webroot/src/components/Licensee/LicenseeList/LicenseeList.vue(3 hunks)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.less(1 hunks)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.ts(1 hunks)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts(1 hunks)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue(1 hunks)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.less(3 hunks)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.spec.ts(1 hunks)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts(9 hunks)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue(3 hunks)webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.less(1 hunks)webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.ts(1 hunks)webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts(1 hunks)webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vue(1 hunks)webroot/src/components/Lists/ListContainer/ListContainer.spec.ts(6 hunks)webroot/src/components/Lists/ListContainer/ListContainer.ts(1 hunks)webroot/src/components/Lists/ListContainer/ListContainer.vue(2 hunks)webroot/src/components/Lists/Pagination/Pagination.less(2 hunks)webroot/src/components/Lists/Pagination/Pagination.spec.ts(1 hunks)webroot/src/components/Lists/Pagination/Pagination.ts(8 hunks)webroot/src/components/Lists/Pagination/Pagination.vue(2 hunks)webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.less(1 hunks)webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.spec.ts(1 hunks)webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.ts(1 hunks)webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.vue(1 hunks)webroot/src/components/Page/PageContainer/PageContainer.less(1 hunks)webroot/src/components/Page/PageHeader/PageHeader.less(1 hunks)webroot/src/locales/en.json(8 hunks)webroot/src/locales/es.json(8 hunks)webroot/src/network/data.api.ts(3 hunks)webroot/src/network/licenseApi/data.api.ts(1 hunks)webroot/src/network/mocks/mock.data.api.ts(1 hunks)webroot/src/network/searchApi/data.api.ts(1 hunks)webroot/src/network/searchApi/interceptors.ts(1 hunks)webroot/src/pages/LicensingList/LicensingList.ts(1 hunks)webroot/src/pages/LicensingList/LicensingList.vue(1 hunks)webroot/src/pages/PublicLicensingList/PublicLicensingList.ts(1 hunks)webroot/src/plugins/EnvConfig/envConfig.plugin.ts(4 hunks)webroot/src/plugins/Statsig/statsig.plugin.ts(1 hunks)webroot/src/store/license/license.actions.ts(3 hunks)webroot/src/store/license/license.mutations.ts(4 hunks)webroot/src/store/license/license.spec.ts(6 hunks)webroot/src/store/license/license.state.ts(3 hunks)webroot/src/styles.common/mixins/buttons.less(1 hunks)
🧰 Additional context used
🧠 Learnings (25)
📚 Learning: 2025-08-29T18:44:53.901Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/PublicDashboard/PublicDashboard.spec.ts:39-45
Timestamp: 2025-08-29T18:44:53.901Z
Learning: In webroot/src/pages/PublicDashboard/PublicDashboard.spec.ts, the test intentionally calls getCognitoConfig() without arguments to test runtime fallback behavior and improve code coverage, even though this causes a TypeScript error. This is a valid testing pattern for verifying that functions handle invalid arguments gracefully.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.spec.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.tswebroot/src/store/license/license.spec.tswebroot/src/components/Lists/Pagination/Pagination.spec.tswebroot/src/components/Lists/PaginationLegacy/PaginationLegacy.spec.ts
📚 Learning: 2025-09-09T19:28:53.260Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1071
File: webroot/tests/helpers/setup.ts:153-155
Timestamp: 2025-09-09T19:28:53.260Z
Learning: In the CompactConnect project, component tests are kept minimal and focus primarily on basic functionality. The main testing effort is concentrated on the data layer (models, store, etc.). For component tests, API stub methods only need to exist to prevent runtime errors - they don't need to return specific mock data since components aren't being tested for full API integration scenarios.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.spec.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.tswebroot/src/components/Lists/Pagination/Pagination.spec.ts
📚 Learning: 2025-08-29T18:22:23.275Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/MfaResetConfirmLicensee/MfaResetConfirmLicensee.spec.ts:12-12
Timestamp: 2025-08-29T18:22:23.275Z
Learning: In the CompactConnect frontend codebase, async describe blocks are widely used and supported in their version of Mocha. The pattern `describe('Test Suite', async () => {` is an accepted and working approach throughout their test files, so suggestions to remove the async keyword from describe blocks should not be made for this codebase.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.spec.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.ts
📚 Learning: 2025-05-28T16:09:12.906Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/Forms/InputEmailList/InputEmailList.spec.ts:12-19
Timestamp: 2025-05-28T16:09:12.906Z
Learning: The CompactConnect application uses mount testing as the general component testing strategy. They focus their testing efforts on the data layer (models and store) rather than extensive component testing, and mount tests meet their coverage needs.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.spec.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.ts
📚 Learning: 2025-05-28T16:09:24.547Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/StateSettingsConfig/StateSettingsConfig.spec.ts:12-19
Timestamp: 2025-05-28T16:09:24.547Z
Learning: The CompactConnect app uses mount testing as their general component testing strategy, focusing more on testing the data layer (models and store) rather than comprehensive component testing. This meets their test coverage needs and is their preferred approach.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.spec.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.ts
📚 Learning: 2025-06-09T19:57:51.519Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 851
File: webroot/src/pages/RegisterLicensee/RegisterLicensee.ts:0-0
Timestamp: 2025-06-09T19:57:51.519Z
Learning: In the RegisterLicensee component, when handling DOM element availability issues, the developer prefers using Vue Watchers over retry mechanisms with requestAnimationFrame to avoid infinite recursion risks and maintain Vue's reactive patterns.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.spec.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.tswebroot/src/pages/LicensingList/LicensingList.vuewebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vuewebroot/src/pages/PublicLicensingList/PublicLicensingList.tswebroot/src/store/license/license.mutations.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.vuewebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.tswebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/pages/LicensingList/LicensingList.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.tswebroot/src/store/license/license.state.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vuewebroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-08-12T22:51:48.937Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1009
File: webroot/src/pages/LicenseeProof/LicenseeProof.less:158-165
Timestamp: 2025-08-12T22:51:48.937Z
Learning: In webroot/src/pages/LicenseeProof/LicenseeProof.vue, the .max-gap elements inside .licenses-container are intentionally hard-coded as empty elements that serve as space placeholders for tablet+ screen widths. On mobile, they are hidden completely using the :empty pseudo-class. This is an intentional design pattern where the developers have full control over keeping these elements truly empty.
Applied to files:
webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.vuewebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.lesswebroot/src/pages/LicensingList/LicensingList.vuewebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.lesswebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vuewebroot/src/pages/PublicLicensingList/PublicLicensingList.tswebroot/src/components/Licensee/LicenseeList/LicenseeList.vuewebroot/src/components/Licensee/LicenseeList/LicenseeList.lesswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.lesswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/pages/LicensingList/LicensingList.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-08-29T18:29:16.953Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/MfaResetStartLicensee/MfaResetStartLicensee.vue:141-146
Timestamp: 2025-08-29T18:29:16.953Z
Learning: In the MfaResetStartLicensee component, license type keys (like "audiologist") are displayed directly in the summary using CSS `text-transform: capitalize` because the keys are human-readable strings, rather than using separate display name lookups.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.lesswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.lesswebroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-09-16T18:43:23.028Z
Learnt from: ChiefStief
Repo: csg-org/CompactConnect PR: 1093
File: webroot/src/components/Icons/ExpirationExplanationIcon/ExpirationExplanationIcon.less:7-16
Timestamp: 2025-09-16T18:43:23.028Z
Learning: In the CompactConnect codebase, _reset.less applies `position: relative;` globally to almost all HTML elements, so additional position: relative declarations on individual components are redundant.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.lesswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.less
📚 Learning: 2025-08-13T18:20:12.967Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1010
File: webroot/src/components/Icons/DownloadFile/DownloadFile.vue:8-20
Timestamp: 2025-08-13T18:20:12.967Z
Learning: In the CompactConnect codebase, SVG icons in the webroot/src/components/Icons/ directory are designed to be styled by their parent components via CSS, not with inline SVG attributes. This allows the same icon to be reused with different sizes, colors, and stroke properties across different components. Accessibility attributes like aria-hidden are handled at the parent container level, not on the SVG element itself.
Applied to files:
webroot/src/components/Lists/Pagination/Pagination.less
📚 Learning: 2025-06-24T00:02:39.944Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:414-443
Timestamp: 2025-06-24T00:02:39.944Z
Learning: In LicenseCard component's clickUnencumberItem method (webroot/src/components/LicenseCard/LicenseCard.ts), complex event handling for checkbox interactions is intentionally designed to ensure consistent behavior across checkbox input, wrapper label, and outer selection parent elements for custom UI requirements. This complexity should be preserved rather than simplified.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vuewebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.tswebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.tswebroot/src/store/license/license.state.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vuewebroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-05-28T16:13:19.506Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/Forms/InputEmailList/InputEmailList.vue:26-30
Timestamp: 2025-05-28T16:13:19.506Z
Learning: In the InputEmailList component (webroot/src/components/Forms/InputEmailList/InputEmailList.vue), the formInput.labelSubtext property rendered with v-html contains only developer-controlled content, not user-controlled content, so XSS concerns do not apply.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vuewebroot/src/components/Forms/InputSubmit/InputSubmit.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-07-03T15:35:57.893Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 905
File: webroot/src/components/UpdateHomeJurisdiction/UpdateHomeJurisdiction.vue:32-41
Timestamp: 2025-07-03T15:35:57.893Z
Learning: In the CompactConnect frontend codebase, the team prefers to keep non-dynamic text directly in Vue templates rather than moving it to computed properties in TypeScript modules, as this approach prevents cluttering the TS files with template labels.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vuewebroot/src/components/Lists/Pagination/Pagination.vuewebroot/src/components/Licensee/LicenseeList/LicenseeList.vuewebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.tswebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-24T00:07:10.463Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:509-528
Timestamp: 2025-06-24T00:07:10.463Z
Learning: In the CompactConnect frontend codebase, the project prefers to avoid early returns in frontend code when possible, as mentioned by jsandoval81 in webroot/src/components/LicenseCard/LicenseCard.ts.
Applied to files:
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vuewebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.tswebroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.tswebroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts
📚 Learning: 2025-08-29T18:16:12.078Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/store/user/user.mutations.ts:269-272
Timestamp: 2025-08-29T18:16:12.078Z
Learning: The CONFIRM_MFA_LICENSEE_ACCOUNT_REQUEST mutation intentionally sets isLoadingAccount = false (rather than true like other REQUEST mutations) because the MfaResetConfirmLicensee page handles its own loading UI with a custom LoadingSpinner component and isLoading state, rather than triggering the global app loading state.
Applied to files:
webroot/src/store/license/license.mutations.tswebroot/src/store/license/license.spec.ts
📚 Learning: 2025-07-08T18:40:24.408Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 882
File: backend/compact-connect/lambdas/python/common/cc_common/data_model/compact_configuration_client.py:287-359
Timestamp: 2025-07-08T18:40:24.408Z
Learning: In the CompactConnect codebase, landonshumway-ia prefers to avoid extraneous unit tests when existing test coverage is already sufficient to catch bugs. For the get_privilege_purchase_options method's live-jurisdiction filtering logic, the existing tests in the purchases test suite provide adequate coverage without needing additional edge case tests.
Applied to files:
webroot/src/store/license/license.spec.ts
📚 Learning: 2025-11-06T18:11:58.272Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/network/mocks/mock.data.ts:1919-1944
Timestamp: 2025-11-06T18:11:58.272Z
Learning: In CompactConnect, the investigation event type (`updateType: 'investigation'`) in privilege/license history is intentionally not yet fully supported in the frontend UI translation and categorization logic (webroot/src/locales/*.json and webroot/src/models/LicenseHistoryItem/LicenseHistoryItem.model.ts). The server license history API needs to be updated first to return sufficient information about investigation events. Until then, the UI gracefully falls back to displaying "Unknown" for investigation events, which is acceptable as an interim solution.
<!--
Applied to files:
webroot/src/store/license/license.spec.tswebroot/src/locales/es.jsonwebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.tswebroot/src/locales/en.jsonwebroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-08-29T17:54:57.683Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/locales/es.json:958-958
Timestamp: 2025-08-29T17:54:57.683Z
Learning: Spanish translations in webroot/src/locales/es.json are currently generated using Google Translate and are considered nice-to-have. The team plans to use professional translation services if formal Spanish support is needed in the future. Don't spend time on nuanced translation quality issues for Spanish locale files.
Applied to files:
webroot/src/locales/es.json
📚 Learning: 2025-08-13T18:24:06.298Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1010
File: webroot/src/components/MilitaryDocumentRow/MilitaryDocumentRow.vue:19-21
Timestamp: 2025-08-13T18:24:06.298Z
Learning: In MilitaryAffiliationInfoBlock, the militaryDocumentHeader() getter returns an object with wrapper functions that provide translated labels for header display, including firstDownloadLink: () => this.$t('common.downloadFile'). When used as a header item in MilitaryDocumentRow, these wrapper functions return appropriate column labels rather than actual data values.
Applied to files:
webroot/src/locales/es.jsonwebroot/src/locales/en.json
📚 Learning: 2025-04-29T02:52:40.532Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 769
File: backend/compact-connect/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py:138-147
Timestamp: 2025-04-29T02:52:40.532Z
Learning: In CompactConnect tests, hardcoded values (like license type abbreviations 'slp') in test queries are sometimes used intentionally rather than using dynamic lookups. This is a deliberate design decision to make tests fail if default test data changes, requiring developers to consciously update related tests.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.spec.ts
📚 Learning: 2025-08-21T16:36:48.723Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1019
File: webroot/src/components/PrivilegeCard/PrivilegeCard.vue:270-278
Timestamp: 2025-08-21T16:36:48.723Z
Learning: In PrivilegeCard component's unencumber modal (webroot/src/components/PrivilegeCard/PrivilegeCard.vue), the unencumber-select wrapper element intentionally uses space key handling to catch bubbled events from child InputCheckbox elements for custom handling actions. When adverseAction.hasEndDate() is true, items show an inactive-category div and are designed to be non-interactive (not focusable), while items without end dates contain focusable InputCheckbox child elements. This design pattern is consistent with prior implementation and represents intentional UX behavior.
Applied to files:
webroot/src/components/Forms/InputSubmit/InputSubmit.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-08-21T19:17:21.038Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1025
File: webroot/src/models/Licensee/Licensee.model.ts:276-312
Timestamp: 2025-08-21T19:17:21.038Z
Learning: In CompactConnect, address information should only come from License objects, not from top-level Licensee fields. The API no longer returns top-level licensee address fields, so all address data flows through individual license objects that contain fields like homeAddressStreet1, homeAddressCity, etc. The bestLicense() and bestLicenseMailingAddress() methods are used to access the most appropriate address from a licensee's collection of licenses.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts
📚 Learning: 2025-06-04T22:04:14.373Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 843
File: webroot/src/components/Forms/InputDate/InputDate.ts:0-0
Timestamp: 2025-06-04T22:04:14.373Z
Learning: In the InputDate component (webroot/src/components/Forms/InputDate/InputDate.ts), immediate validation on every keystroke is intentional design behavior. The team prefers to alert users to encourage expected date format completion rather than deferring validation until the date is complete. This provides immediate feedback to guide users toward proper MM/dd/yyyy format completion.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts
📚 Learning: 2025-06-19T23:43:25.512Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/PrivilegeCard/PrivilegeCard.ts:0-0
Timestamp: 2025-06-19T23:43:25.512Z
Learning: In Vue form components, when programmatically setting form input values, it's more efficient to validate just the specific form element being updated (e.g., `formInput.validate()`) rather than calling `validateAll()` on the entire form.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-07-10T19:50:56.745Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 922
File: webroot/src/components/UserAccount/UserAccount.ts:0-0
Timestamp: 2025-07-10T19:50:56.745Z
Learning: In the UserAccount component (webroot/src/components/UserAccount/UserAccount.ts), the email field should be disabled for staff users (`isDisabled: this.isStaff`) to maintain existing restrictions, while licensees should be able to change their email address through the new verification process. This is the intended behavior per PR #922 requirements.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
🧬 Code graph analysis (14)
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.spec.ts (1)
webroot/tests/helpers/setup.ts (1)
mountShallow(265-265)
webroot/src/network/searchApi/interceptors.ts (1)
webroot/src/app.config.ts (1)
authStorage(98-98)
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.spec.ts (3)
webroot/tests/helpers/setup.ts (2)
mountShallow(265-265)mountFull(266-266)webroot/src/components/Licensee/LicenseeList/LicenseeList.ts (1)
fetchListData(302-321)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts (1)
fetchListData(256-351)
webroot/src/store/license/license.mutations.ts (2)
webroot/src/store/license/license.state.ts (1)
state(21-35)webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts (1)
LicenseSearchLegacy(26-31)
webroot/src/store/license/license.spec.ts (1)
webroot/src/store/license/license.state.ts (1)
state(21-35)
webroot/src/components/Lists/Pagination/Pagination.ts (5)
webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.ts (3)
currentPage(115-119)pageSize(121-125)pageCount(127-129)webroot/src/components/Lists/_mixins/Pagination.mixin.ts (2)
currentPage(92-94)pagination(84-86)webroot/src/components/Licensee/LicenseeList/LicenseeList.ts (1)
paginationStore(76-78)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts (1)
paginationStore(76-78)webroot/src/components/StyleGuide/ExampleList/ExampleList.ts (1)
paginationStore(45-47)
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts (4)
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts (1)
LicenseSearchLegacy(26-31)webroot/src/store/license/license.state.ts (2)
state(21-35)State(10-19)webroot/src/store/pagination/pagination.state.ts (3)
DEFAULT_PAGE(8-8)DEFAULT_PAGE_SIZE(9-9)PageChangeConfig(23-27)webroot/src/store/pagination/index.ts (1)
PageExhaustError(12-17)
webroot/src/network/data.api.ts (1)
webroot/src/network/searchApi/data.api.ts (1)
searchDataApi(405-405)
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts (3)
webroot/src/store/license/license.state.ts (2)
State(10-19)state(21-35)webroot/src/models/FormInput/FormInput.model.ts (1)
FormInput(59-170)webroot/src/models/Compact/Compact.model.ts (1)
CompactSerializer(129-139)
webroot/src/pages/LicensingList/LicensingList.ts (1)
webroot/src/pages/PublicLicensingList/PublicLicensingList.ts (1)
Component(12-20)
webroot/src/store/license/license.actions.ts (2)
webroot/src/network/mocks/mock.data.api.ts (1)
dataApi(837-837)webroot/src/network/data.api.ts (1)
dataApi(712-712)
webroot/src/network/searchApi/data.api.ts (3)
webroot/src/network/licenseApi/data.api.ts (1)
DataApiInterface(56-58)webroot/src/network/searchApi/interceptors.ts (4)
requestSuccess(16-27)requestError(34-34)responseSuccess(43-47)responseError(54-76)webroot/src/models/Licensee/Licensee.model.ts (1)
LicenseeSerializer(402-470)
webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.spec.ts (3)
webroot/tests/helpers/setup.ts (2)
mountShallow(265-265)mountFull(266-266)webroot/src/components/Lists/Pagination/Pagination.ts (1)
pages(148-195)webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.ts (1)
pages(139-155)
webroot/src/store/license/license.state.ts (2)
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts (1)
LicenseSearchLegacy(26-31)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts (1)
LicenseSearch(40-55)
🪛 dotenv-linter (4.0.0)
webroot/.env.example
[warning] 8-8: [UnorderedKey] The VUE_APP_API_SEARCH_ROOT key should go before the VUE_APP_API_STATE_ROOT key
(UnorderedKey)
[warning] 17-17: [UnorderedKey] The VUE_APP_STATSIG_DISABLED key should go before the VUE_APP_STATSIG_KEY key
(UnorderedKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: CheckWebroot
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue
Outdated
Show resolved
Hide resolved
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
Outdated
Show resolved
Hide resolved
- PR review updates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (5)
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue (3)
43-44: Remove redundantthiskeyword in template bindings.In Vue templates, the
thiskeyword is implicit and not required. Removing it follows Vue conventions and improves readability.🔎 Proposed changes
- :listData="this.licenseStore.model" - :listSize="this.licenseStore.total" + :listData="licenseStore.model" + :listSize="licenseStore.total"- <LicenseeRow - v-for="(record, index) in this.licenseStore.model" + <LicenseeRow + v-for="(record, index) in licenseStore.model"Also applies to: 68-68
68-70: Use a unique identifier as the key instead of the array index.Using the array index as the
keyinv-forcan lead to rendering issues if the list is manipulated. Each licensee record likely has a unique identifier (such asidorlicenseId) that should be used instead.🔎 Proposed change
<LicenseeRow - v-for="(record, index) in licenseStore.model" - :key="index" + v-for="record in licenseStore.model" + :key="record.id" :listId="listId" :item="record"Note: Adjust
record.idto match the actual unique identifier property in your record structure.
23-27: Remove redundanttabindex="0"from button.The
tabindex="0"attribute is unnecessary on button elements, as they are naturally focusable. This can be safely removed.🔎 Proposed change
<button class="search-toggle" @click="toggleSearch()" - tabindex="0" >webroot/src/network/searchApi/data.api.ts (1)
59-69: Consider type-safe window augmentation.The current approach uses
window as anyto add debugging utilities. While functional, consider declaring a proper interface augmentation for better type safety.🔎 Suggested approach
At the top of the file or in a shared types file:
declare global { interface Window { ccQueryToggle?: () => void; ccIsQueryLogEnabled?: boolean; } }Then replace lines 59-69:
-const appWindow = window as any; - -appWindow.ccQueryToggle = (): void => { - if (appWindow.ccIsQueryLogEnabled) { - appWindow.ccIsQueryLogEnabled = false; +window.ccQueryToggle = (): void => { + if (window.ccIsQueryLogEnabled) { + window.ccIsQueryLogEnabled = false; console.log('CompactConnect search query logging: DISABLED'); } else { - appWindow.ccIsQueryLogEnabled = true; + window.ccIsQueryLogEnabled = true; console.log('CompactConnect search query logging: ENABLED'); } };webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue (1)
78-98: Hardcoded year will require annual maintenance.The date pickers have
yearRangestarting at2025, which is hardcoded. This will need updating each year and may already be outdated if privileges can be purchased earlier.🔎 Suggested approach
Consider using a dynamic year range based on a reasonable lookback period:
- :yearRange="[2025, new Date().getFullYear()]" + :yearRange="[new Date().getFullYear() - 5, new Date().getFullYear()]"Or define a constant in the component if 2025 represents a significant business date (e.g., system launch year):
// In the TypeScript file const SYSTEM_START_YEAR = 2025;- :yearRange="[2025, new Date().getFullYear()]" + :yearRange="[SYSTEM_START_YEAR, new Date().getFullYear()]"This applies to both the privilege purchase date range (lines 78-98) and the encumber date range (lines 120-140).
Also applies to: 120-140
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py(1 hunks)webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue(1 hunks)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue(3 hunks)webroot/src/locales/es.json(8 hunks)webroot/src/network/searchApi/data.api.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (17)
📚 Learning: 2025-10-10T18:45:43.801Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1114
File: backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py:34-35
Timestamp: 2025-10-10T18:45:43.801Z
Learning: In backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py, the cdk.context.deploy-example.json file is intentionally minimal and serves as a template, not for actual deployments. Actual deployment environments (test, beta, prod, sandbox) contain all required environment-specific keys like statsig_key, app_env, recaptcha_public_key, and robots_meta. This is by design.
Applied to files:
backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py
📚 Learning: 2025-08-12T22:51:48.937Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1009
File: webroot/src/pages/LicenseeProof/LicenseeProof.less:158-165
Timestamp: 2025-08-12T22:51:48.937Z
Learning: In webroot/src/pages/LicenseeProof/LicenseeProof.vue, the .max-gap elements inside .licenses-container are intentionally hard-coded as empty elements that serve as space placeholders for tablet+ screen widths. On mobile, they are hidden completely using the :empty pseudo-class. This is an intentional design pattern where the developers have full control over keeping these elements truly empty.
Applied to files:
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-09T19:57:51.519Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 851
File: webroot/src/pages/RegisterLicensee/RegisterLicensee.ts:0-0
Timestamp: 2025-06-09T19:57:51.519Z
Learning: In the RegisterLicensee component, when handling DOM element availability issues, the developer prefers using Vue Watchers over retry mechanisms with requestAnimationFrame to avoid infinite recursion risks and maintain Vue's reactive patterns.
Applied to files:
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-08-29T18:29:16.953Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/MfaResetStartLicensee/MfaResetStartLicensee.vue:141-146
Timestamp: 2025-08-29T18:29:16.953Z
Learning: In the MfaResetStartLicensee component, license type keys (like "audiologist") are displayed directly in the summary using CSS `text-transform: capitalize` because the keys are human-readable strings, rather than using separate display name lookups.
Applied to files:
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue
📚 Learning: 2025-07-03T15:35:57.893Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 905
File: webroot/src/components/UpdateHomeJurisdiction/UpdateHomeJurisdiction.vue:32-41
Timestamp: 2025-07-03T15:35:57.893Z
Learning: In the CompactConnect frontend codebase, the team prefers to keep non-dynamic text directly in Vue templates rather than moving it to computed properties in TypeScript modules, as this approach prevents cluttering the TS files with template labels.
Applied to files:
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vuewebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-24T00:07:10.463Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:509-528
Timestamp: 2025-06-24T00:07:10.463Z
Learning: In the CompactConnect frontend codebase, the project prefers to avoid early returns in frontend code when possible, as mentioned by jsandoval81 in webroot/src/components/LicenseCard/LicenseCard.ts.
Applied to files:
webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.vue
📚 Learning: 2025-11-06T18:11:58.272Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/network/mocks/mock.data.ts:1919-1944
Timestamp: 2025-11-06T18:11:58.272Z
Learning: In CompactConnect, the investigation event type (`updateType: 'investigation'`) in privilege/license history is intentionally not yet fully supported in the frontend UI translation and categorization logic (webroot/src/locales/*.json and webroot/src/models/LicenseHistoryItem/LicenseHistoryItem.model.ts). The server license history API needs to be updated first to return sufficient information about investigation events. Until then, the UI gracefully falls back to displaying "Unknown" for investigation events, which is acceptable as an interim solution.
<!--
Applied to files:
webroot/src/locales/es.jsonwebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-08-29T17:54:57.683Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/locales/es.json:958-958
Timestamp: 2025-08-29T17:54:57.683Z
Learning: Spanish translations in webroot/src/locales/es.json are currently generated using Google Translate and are considered nice-to-have. The team plans to use professional translation services if formal Spanish support is needed in the future. Don't spend time on nuanced translation quality issues for Spanish locale files.
Applied to files:
webroot/src/locales/es.json
📚 Learning: 2025-08-13T18:24:06.298Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1010
File: webroot/src/components/MilitaryDocumentRow/MilitaryDocumentRow.vue:19-21
Timestamp: 2025-08-13T18:24:06.298Z
Learning: In MilitaryAffiliationInfoBlock, the militaryDocumentHeader() getter returns an object with wrapper functions that provide translated labels for header display, including firstDownloadLink: () => this.$t('common.downloadFile'). When used as a header item in MilitaryDocumentRow, these wrapper functions return appropriate column labels rather than actual data values.
Applied to files:
webroot/src/locales/es.json
📚 Learning: 2025-08-21T15:23:26.019Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1025
File: webroot/src/models/Licensee/Licensee.model.ts:242-254
Timestamp: 2025-08-21T15:23:26.019Z
Learning: In the CompactConnect codebase, the LicenseSerializer.fromServer() method maps the server response field `dateOfIssuance` to the License model's `issueDate` property. After serialization, License instances only contain `issueDate` and never have `dateOfIssuance`. When reviewing date comparisons in reducers that work with License objects, check if they're working with serialized License instances (which use `issueDate`) rather than raw server data (which uses `dateOfIssuance`).
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-13T22:13:48.430Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1188
File: backend/compact-connect/tests/smoke/rollback_license_upload_smoke_tests.py:354-372
Timestamp: 2025-11-13T22:13:48.430Z
Learning: In the CompactConnect codebase, privilege records use datetime fields (not date fields) for dateOfIssuance, dateOfRenewal, and dateOfExpiration, which is intentionally different from license records that use date fields for these same attributes.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-13T20:28:33.191Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1011
File: webroot/src/models/Licensee/Licensee.model.ts:276-279
Timestamp: 2025-08-13T20:28:33.191Z
Learning: The two-year encumbrance wait period feature only applies to privileges, not licenses. The logic should only check if privilege encumbrances that are no longer active have lift dates within the past two years.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-12T21:06:06.981Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/components/LicenseCard/LicenseCard.ts:388-396
Timestamp: 2025-11-12T21:06:06.981Z
Learning: In the CompactConnect investigation creation flow, the backend APIs for creating investigations (both `createLicenseInvestigation` and `createPrivilegeInvestigation` in webroot/src/network/licenseApi/data.api.ts) do not accept a `startDate` parameter. The backend automatically sets the investigation creation date to the timestamp when the API request is received, so the frontend UI does not need to capture or submit an investigation start date during the creation workflow.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-21T16:36:48.723Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1019
File: webroot/src/components/PrivilegeCard/PrivilegeCard.vue:270-278
Timestamp: 2025-08-21T16:36:48.723Z
Learning: In PrivilegeCard component's unencumber modal (webroot/src/components/PrivilegeCard/PrivilegeCard.vue), the unencumber-select wrapper element intentionally uses space key handling to catch bubbled events from child InputCheckbox elements for custom handling actions. When adverseAction.hasEndDate() is true, items show an inactive-category div and are designed to be non-interactive (not focusable), while items without end dates contain focusable InputCheckbox child elements. This design pattern is consistent with prior implementation and represents intentional UX behavior.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-07-10T19:50:56.745Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 922
File: webroot/src/components/UserAccount/UserAccount.ts:0-0
Timestamp: 2025-07-10T19:50:56.745Z
Learning: In the UserAccount component (webroot/src/components/UserAccount/UserAccount.ts), the email field should be disabled for staff users (`isDisabled: this.isStaff`) to maintain existing restrictions, while licensees should be able to change their email address through the new verification process. This is the intended behavior per PR #922 requirements.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-24T00:02:39.944Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:414-443
Timestamp: 2025-06-24T00:02:39.944Z
Learning: In LicenseCard component's clickUnencumberItem method (webroot/src/components/LicenseCard/LicenseCard.ts), complex event handling for checkbox interactions is intentionally designed to ensure consistent behavior across checkbox input, wrapper label, and outer selection parent elements for custom UI requirements. This complexity should be preserved rather than simplified.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-19T23:43:25.512Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/PrivilegeCard/PrivilegeCard.ts:0-0
Timestamp: 2025-06-19T23:43:25.512Z
Learning: In Vue form components, when programmatically setting form input values, it's more efficient to validate just the specific form element being updated (e.g., `formInput.validate()`) rather than calling `validateAll()` on the entire form.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
🧬 Code graph analysis (2)
backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py (1)
backend/common-cdk/common_constructs/frontend_app_config_utility.py (1)
api_domain_name(226-228)
webroot/src/network/searchApi/data.api.ts (3)
webroot/src/network/licenseApi/data.api.ts (1)
DataApiInterface(56-58)webroot/src/network/searchApi/interceptors.ts (4)
requestSuccess(16-27)requestError(34-34)responseSuccess(43-47)responseError(54-76)webroot/src/models/Licensee/Licensee.model.ts (1)
LicenseeSerializer(402-470)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: TestApp
- GitHub Check: CheckWebroot
🔇 Additional comments (12)
webroot/src/locales/es.json (1)
27-28: LGTM! Previous translation issue resolved.The Spanish translations for the new search and export functionality are accurate and semantically appropriate. The previous issue with
exportInProgress(line 28) has been corrected—it now properly uses the gerund form "Exportando..." instead of the noun "Exportador...".All new translations cover:
- Export functionality and date filters
- Search UI labels and provider terminology
- Investigation and military status options with proper key/name structures
- Server error messages
Based on learnings, Spanish translations are auto-generated and considered nice-to-have for now, with professional translation services planned for formal Spanish support if needed.
Also applies to: 82-83, 85-86, 457-458, 568-568, 576-576, 578-578, 605-605, 613-614, 620-621, 644-653, 726-726, 926-943
webroot/src/network/searchApi/data.api.ts (5)
78-120: LGTM: Axios configuration and interceptor setup.The Axios instance configuration is appropriate for a search API with a 30-second timeout for potentially complex queries. The interceptor initialization follows the standard pattern and properly injects the store context for error handling.
127-188: LGTM: Licensee search parameter handling.The query construction for licensee-level search parameters uses appropriate OpenSearch query types:
match_phrase_prefixfor name prefix matching,termfor exact state/status matching, andmatchfor NPI search.
213-242: LGTM: Date filtering logic correctly implemented.The privilege date filtering has been correctly implemented using a
shouldclause withminimum_should_match: 1(lines 214-215). This properly matches privileges where eitherdateOfIssuanceordateOfRenewalfalls within the specified range, addressing the concern raised in the previous review.
249-328: LGTM: Adverse action and investigation filtering logic.The nested query structures for adverse actions and investigations are correctly implemented:
- Adverse actions use
shouldwithminimum_should_match: 1to match either licenses or privileges- Investigation status appropriately branches:
shouldfor "underInvestigation" (match either),must_nototherwise (exclude both)
335-356: LGTM: Pagination and sorting implementation.The pagination logic correctly calculates zero-based
fromoffset from one-based page numbers. The sorting appends.keywordsuffix, which is the correct approach for sorting on text fields in OpenSearch.webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue (6)
15-21: LGTM!The MockPopulate component integration is clean and properly bound.
37-42: LGTM!The InputRadioGroup component properly replaces the previous search type selector with appropriate bindings.
56-68: LGTM!The state selection fields are well-implemented, with the disabled state tooltip on homeState providing helpful user feedback.
99-104: Acknowledged: Military status field pending.The TODO comment clearly indicates this field will be added in a future PR with military status updates. This is acceptable for incremental development.
105-110: LGTM!The investigation status field is properly implemented.
141-145: LGTM!The NPI input field is correctly implemented.
backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py
Outdated
Show resolved
Hide resolved
- PR review updates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
webroot/src/network/searchApi/data.api.ts (1)
401-403: Remove commented-out mock code.This commented-out mock return statement should be removed as flagged in a previous review. Dead code clutters the codebase.
🔎 Suggested fix
return serverResponse; - - // return { - // downloadUrl: 'https://cdn.prod.website-files.com/66a083c22bdfd06a6aee5193/6913a447111789a56d2f13b9_IA-Logo-Primary-FullColor.svg', - // }; }
🧹 Nitpick comments (1)
webroot/src/network/searchApi/data.api.ts (1)
249-289: Consider filtering by active encumbrances only.The adverse action query filters by
effectiveStartDaterange but doesn't check whether the adverse action is still active. Since adverse actions have aneffectiveLiftDatefield that indicates when they were lifted, filtering should exclude adverse actions whereeffectiveLiftDateis in the past, to avoid returning providers with historical encumbrances that have already been resolved.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py(1 hunks)webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue(3 hunks)webroot/src/models/Investigation/Investigation.model.spec.ts(1 hunks)webroot/src/network/searchApi/data.api.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- backend/compact-connect-ui-app/stacks/frontend_deployment_stack/deployment.py
🧰 Additional context used
🧠 Learnings (24)
📚 Learning: 2025-11-12T21:06:06.981Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/components/LicenseCard/LicenseCard.ts:388-396
Timestamp: 2025-11-12T21:06:06.981Z
Learning: In the CompactConnect investigation creation flow, the backend APIs for creating investigations (both `createLicenseInvestigation` and `createPrivilegeInvestigation` in webroot/src/network/licenseApi/data.api.ts) do not accept a `startDate` parameter. The backend automatically sets the investigation creation date to the timestamp when the API request is received, so the frontend UI does not need to capture or submit an investigation start date during the creation workflow.
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.tswebroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-21T15:23:26.019Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1025
File: webroot/src/models/Licensee/Licensee.model.ts:242-254
Timestamp: 2025-08-21T15:23:26.019Z
Learning: In the CompactConnect codebase, the LicenseSerializer.fromServer() method maps the server response field `dateOfIssuance` to the License model's `issueDate` property. After serialization, License instances only contain `issueDate` and never have `dateOfIssuance`. When reviewing date comparisons in reducers that work with License objects, check if they're working with serialized License instances (which use `issueDate`) rather than raw server data (which uses `dateOfIssuance`).
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.tswebroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-06T18:14:40.626Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/models/Investigation/Investigation.model.ts:67-86
Timestamp: 2025-11-06T18:14:40.626Z
Learning: In the Investigation model (webroot/src/models/Investigation/Investigation.model.ts), the isActive() method intentionally includes defensive logic to handle potential backend bug states where the start date (startDate) might be missing. If an investigation record exists but lacks a start date, it should still be considered active as long as it hasn't ended (updateDate is null or in the future), because the record's existence implies it was created and just has missing date metadata.
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.ts
📚 Learning: 2025-11-06T18:11:58.272Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/network/mocks/mock.data.ts:1919-1944
Timestamp: 2025-11-06T18:11:58.272Z
Learning: In CompactConnect, the investigation event type (`updateType: 'investigation'`) in privilege/license history is intentionally not yet fully supported in the frontend UI translation and categorization logic (webroot/src/locales/*.json and webroot/src/models/LicenseHistoryItem/LicenseHistoryItem.model.ts). The server license history API needs to be updated first to return sufficient information about investigation events. Until then, the UI gracefully falls back to displaying "Unknown" for investigation events, which is acceptable as an interim solution.
<!--
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.tswebroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-08-20T17:27:40.673Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1009
File: webroot/src/models/License/License.model.spec.ts:599-601
Timestamp: 2025-08-20T17:27:40.673Z
Learning: The `dateDisplay` utility function in the License model can handle both date-only strings (serverDateFormat) and datetime strings (serverDatetimeFormat) correctly. When testing date display methods like `activeFromDateDisplay()`, use the format that matches the expected parsing behavior rather than the input format.
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.ts
📚 Learning: 2025-08-21T15:23:30.649Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1025
File: webroot/src/models/Licensee/Licensee.model.ts:242-254
Timestamp: 2025-08-21T15:23:30.649Z
Learning: In the CompactConnect frontend codebase, the LicenseSerializer.fromServer() method maps server response field `dateOfIssuance` to the License model field `issueDate`. After serialization, License objects only contain `issueDate` and never `dateOfIssuance`, so reducer logic only needs to check for null `issueDate` values.
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.ts
📚 Learning: 2025-08-20T17:27:40.673Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1009
File: webroot/src/models/License/License.model.spec.ts:599-601
Timestamp: 2025-08-20T17:27:40.673Z
Learning: The `dateDisplay` utility function in the CompactConnect codebase can intelligently handle both date-only strings (serverDateFormat) and datetime strings (serverDatetimeFormat) automatically. When writing tests for date display methods, the expectation should match the parsing behavior rather than assuming the input format needs to be specified explicitly.
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.ts
📚 Learning: 2025-04-29T01:57:43.684Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 769
File: backend/compact-connect/lambdas/python/common/tests/resources/dynamo/provider.json:5-5
Timestamp: 2025-04-29T01:57:43.684Z
Learning: The provider.json test data contains both "providerDateOfUpdate" and "dateOfUpdate" fields which serve different purposes, and both should be maintained in the test files.
Applied to files:
webroot/src/models/Investigation/Investigation.model.spec.ts
📚 Learning: 2025-11-13T22:13:48.430Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1188
File: backend/compact-connect/tests/smoke/rollback_license_upload_smoke_tests.py:354-372
Timestamp: 2025-11-13T22:13:48.430Z
Learning: In the CompactConnect codebase, privilege records use datetime fields (not date fields) for dateOfIssuance, dateOfRenewal, and dateOfExpiration, which is intentionally different from license records that use date fields for these same attributes.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-13T20:28:33.191Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1011
File: webroot/src/models/Licensee/Licensee.model.ts:276-279
Timestamp: 2025-08-13T20:28:33.191Z
Learning: The two-year encumbrance wait period feature only applies to privileges, not licenses. The logic should only check if privilege encumbrances that are no longer active have lift dates within the past two years.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-07-08T18:40:24.408Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 882
File: backend/compact-connect/lambdas/python/common/cc_common/data_model/compact_configuration_client.py:287-359
Timestamp: 2025-07-08T18:40:24.408Z
Learning: In the CompactConnect codebase, landonshumway-ia prefers to avoid extraneous unit tests when existing test coverage is already sufficient to catch bugs. For the get_privilege_purchase_options method's live-jurisdiction filtering logic, the existing tests in the purchases test suite provide adequate coverage without needing additional edge case tests.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-07-02T21:10:06.663Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 904
File: webroot/src/components/StateSettingsList/StateSettingsList.ts:49-49
Timestamp: 2025-07-02T21:10:06.663Z
Learning: In the CompactConnect TypeScript codebase, the team generally avoids `any` types but makes an exception for server responses. They use `any` for server response data to prevent overly verbose TypeScript syntax and avoid double casting as `unknown` when updating values from the server. These server responses get reorganized as typed models elsewhere in the codebase, maintaining type safety where it matters most while keeping the code clean.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-12T22:51:48.937Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1009
File: webroot/src/pages/LicenseeProof/LicenseeProof.less:158-165
Timestamp: 2025-08-12T22:51:48.937Z
Learning: In webroot/src/pages/LicenseeProof/LicenseeProof.vue, the .max-gap elements inside .licenses-container are intentionally hard-coded as empty elements that serve as space placeholders for tablet+ screen widths. On mobile, they are hidden completely using the :empty pseudo-class. This is an intentional design pattern where the developers have full control over keeping these elements truly empty.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-08-21T16:36:48.723Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1019
File: webroot/src/components/PrivilegeCard/PrivilegeCard.vue:270-278
Timestamp: 2025-08-21T16:36:48.723Z
Learning: In PrivilegeCard component's unencumber modal (webroot/src/components/PrivilegeCard/PrivilegeCard.vue), the unencumber-select wrapper element intentionally uses space key handling to catch bubbled events from child InputCheckbox elements for custom handling actions. When adverseAction.hasEndDate() is true, items show an inactive-category div and are designed to be non-interactive (not focusable), while items without end dates contain focusable InputCheckbox child elements. This design pattern is consistent with prior implementation and represents intentional UX behavior.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-07-10T19:50:56.745Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 922
File: webroot/src/components/UserAccount/UserAccount.ts:0-0
Timestamp: 2025-07-10T19:50:56.745Z
Learning: In the UserAccount component (webroot/src/components/UserAccount/UserAccount.ts), the email field should be disabled for staff users (`isDisabled: this.isStaff`) to maintain existing restrictions, while licensees should be able to change their email address through the new verification process. This is the intended behavior per PR #922 requirements.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-24T00:02:39.944Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:414-443
Timestamp: 2025-06-24T00:02:39.944Z
Learning: In LicenseCard component's clickUnencumberItem method (webroot/src/components/LicenseCard/LicenseCard.ts), complex event handling for checkbox interactions is intentionally designed to ensure consistent behavior across checkbox input, wrapper label, and outer selection parent elements for custom UI requirements. This complexity should be preserved rather than simplified.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-05-28T16:10:55.628Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/Forms/InputEmailList/InputEmailList.less:17-26
Timestamp: 2025-05-28T16:10:55.628Z
Learning: The `.add-email-help` element in the InputEmailList component (webroot/src/components/Forms/InputEmailList/InputEmailList.less) is display-only and not meant to handle interaction states like hover or focus. It should not have cursor: pointer or interactive styling.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-24T00:17:31.188Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/styles.common/_inputs.less:115-118
Timestamp: 2025-06-24T00:17:31.188Z
Learning: The team intentionally uses broad CSS selectors like `.dp__input_wrap div { position: static; }` to fix styling issues with the Vue Date-Picker library. They have experience with these styles working well, keep the library version pinned in yarn.lock, and have established processes to re-test everything when updating the library version. This approach is acceptable given their testing discipline and version control.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-05-28T16:13:19.506Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/Forms/InputEmailList/InputEmailList.vue:26-30
Timestamp: 2025-05-28T16:13:19.506Z
Learning: In the InputEmailList component (webroot/src/components/Forms/InputEmailList/InputEmailList.vue), the formInput.labelSubtext property rendered with v-html contains only developer-controlled content, not user-controlled content, so XSS concerns do not apply.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-24T00:07:10.463Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:509-528
Timestamp: 2025-06-24T00:07:10.463Z
Learning: In the CompactConnect frontend codebase, the project prefers to avoid early returns in frontend code when possible, as mentioned by jsandoval81 in webroot/src/components/LicenseCard/LicenseCard.ts.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-07-10T19:52:40.366Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 922
File: webroot/src/components/UserAccount/UserAccount.ts:250-267
Timestamp: 2025-07-10T19:52:40.366Z
Learning: In focus trap implementations for modals, when there's only one focusable element (like in a success state), it's correct for both firstTabIndex and lastTabIndex to reference the same element. This keeps focus appropriately trapped on that single element. Optional chaining operators (?.focus()) provide adequate null safety for DOM element access in focus management code.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-04T22:04:14.373Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 843
File: webroot/src/components/Forms/InputDate/InputDate.ts:0-0
Timestamp: 2025-06-04T22:04:14.373Z
Learning: In the InputDate component (webroot/src/components/Forms/InputDate/InputDate.ts), immediate validation on every keystroke is intentional design behavior. The team prefers to alert users to encourage expected date format completion rather than deferring validation until the date is complete. This provides immediate feedback to guide users toward proper MM/dd/yyyy format completion.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-06-09T19:57:51.519Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 851
File: webroot/src/pages/RegisterLicensee/RegisterLicensee.ts:0-0
Timestamp: 2025-06-09T19:57:51.519Z
Learning: In the RegisterLicensee component, when handling DOM element availability issues, the developer prefers using Vue Watchers over retry mechanisms with requestAnimationFrame to avoid infinite recursion risks and maintain Vue's reactive patterns.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
📚 Learning: 2025-07-03T15:35:57.893Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 905
File: webroot/src/components/UpdateHomeJurisdiction/UpdateHomeJurisdiction.vue:32-41
Timestamp: 2025-07-03T15:35:57.893Z
Learning: In the CompactConnect frontend codebase, the team prefers to keep non-dynamic text directly in Vue templates rather than moving it to computed properties in TypeScript modules, as this approach prevents cluttering the TS files with template labels.
Applied to files:
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
🧬 Code graph analysis (2)
webroot/src/models/Investigation/Investigation.model.spec.ts (1)
webroot/src/app.config.ts (1)
serverDateFormat(175-175)
webroot/src/network/searchApi/data.api.ts (3)
webroot/src/network/licenseApi/data.api.ts (1)
DataApiInterface(56-58)webroot/src/network/searchApi/interceptors.ts (4)
requestSuccess(16-27)requestError(34-34)responseSuccess(43-47)responseError(54-76)webroot/src/models/Licensee/Licensee.model.ts (1)
LicenseeSerializer(402-470)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: CheckWebroot
- GitHub Check: TestApp
🔇 Additional comments (6)
webroot/src/network/searchApi/data.api.ts (1)
59-69: Debug toggle implementation looks reasonable for development.The
ccQueryToggle()function provides a useful runtime debugging capability. This is a reasonable approach for development-time query inspection.webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue (4)
15-29: Dev-only tooling accepted as-is.The MockPopulate and clear button are development-only utilities. Per previous discussion, accessibility rigor isn't required for these local development helpers.
74-96: Date inputs have proper accessibility associations.Good use of
aria-labelledbyto associate the date inputs with their section labels. This addresses the previous accessibility concerns while keeping the labels as visual grouping elements.Minor note: The
yearRangestarts at 2025, which may need adjustment in future years or based on data availability.
143-159: Submit button prop issue resolved.Both InputSubmit components now correctly use the
:isEnabledprop instead of the previously flagged:isDisabled. The conditional rendering for provider search vs. privilege export is clean.
97-102: Commented placeholder with clear TODO.The military status field is appropriately commented out with a clear TODO indicating it will be added in the next PR with military status updates.
webroot/src/models/Investigation/Investigation.model.spec.ts (1)
136-138: No changes needed. The test is self-contained—it generates test data withmoment().format(serverDateFormat)and immediately asserts the serializer preserves it exactly. Since no hardcoded date values or UTC-based comparisons are involved, the test won't experience timezone-related flakiness in different CI environments. This pattern aligns with how date handling is used elsewhere in the codebase.
- PR review updates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
webroot/src/network/searchApi/data.api.ts (1)
104-104: Add type annotation for the router parameter.While the JSDoc indicates this should be a
Routertype, the parameter lacks a TypeScript type annotation. Adding the type improves type safety and IDE support.🔎 Suggested fix
- public initInterceptors(router) { + public initInterceptors(router: any) {Or, if the Router type is available:
+import { Router } from 'vue-router'; + // ... - public initInterceptors(router) { + public initInterceptors(router: Router) {
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
webroot/src/network/searchApi/data.api.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-12-19T16:04:23.341Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1234
File: webroot/src/network/searchApi/data.api.ts:83-95
Timestamp: 2025-12-19T16:04:23.341Z
Learning: In the CompactConnect codebase, all network API files under webroot/src/network/*/data.api.ts use a specific axios.create header configuration pattern with nested get/post/put objects inside the headers config. Reviewers should not flag this pattern as an issue, since it aligns with the project’s Axios version and conventions. If enforcing general axios patterns, treat this as a project-specific exception and focus on consistency within this path.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-21T15:23:26.019Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1025
File: webroot/src/models/Licensee/Licensee.model.ts:242-254
Timestamp: 2025-08-21T15:23:26.019Z
Learning: In the CompactConnect codebase, the LicenseSerializer.fromServer() method maps the server response field `dateOfIssuance` to the License model's `issueDate` property. After serialization, License instances only contain `issueDate` and never have `dateOfIssuance`. When reviewing date comparisons in reducers that work with License objects, check if they're working with serialized License instances (which use `issueDate`) rather than raw server data (which uses `dateOfIssuance`).
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-13T22:13:48.430Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1188
File: backend/compact-connect/tests/smoke/rollback_license_upload_smoke_tests.py:354-372
Timestamp: 2025-11-13T22:13:48.430Z
Learning: In the CompactConnect codebase, privilege records use datetime fields (not date fields) for dateOfIssuance, dateOfRenewal, and dateOfExpiration, which is intentionally different from license records that use date fields for these same attributes.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-13T20:28:33.191Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1011
File: webroot/src/models/Licensee/Licensee.model.ts:276-279
Timestamp: 2025-08-13T20:28:33.191Z
Learning: The two-year encumbrance wait period feature only applies to privileges, not licenses. The logic should only check if privilege encumbrances that are no longer active have lift dates within the past two years.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-12T21:06:06.981Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/components/LicenseCard/LicenseCard.ts:388-396
Timestamp: 2025-11-12T21:06:06.981Z
Learning: In the CompactConnect investigation creation flow, the backend APIs for creating investigations (both `createLicenseInvestigation` and `createPrivilegeInvestigation` in webroot/src/network/licenseApi/data.api.ts) do not accept a `startDate` parameter. The backend automatically sets the investigation creation date to the timestamp when the API request is received, so the frontend UI does not need to capture or submit an investigation start date during the creation workflow.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-07-08T18:40:24.408Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 882
File: backend/compact-connect/lambdas/python/common/cc_common/data_model/compact_configuration_client.py:287-359
Timestamp: 2025-07-08T18:40:24.408Z
Learning: In the CompactConnect codebase, landonshumway-ia prefers to avoid extraneous unit tests when existing test coverage is already sufficient to catch bugs. For the get_privilege_purchase_options method's live-jurisdiction filtering logic, the existing tests in the purchases test suite provide adequate coverage without needing additional edge case tests.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-07-02T21:10:06.663Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 904
File: webroot/src/components/StateSettingsList/StateSettingsList.ts:49-49
Timestamp: 2025-07-02T21:10:06.663Z
Learning: In the CompactConnect TypeScript codebase, the team generally avoids `any` types but makes an exception for server responses. They use `any` for server response data to prevent overly verbose TypeScript syntax and avoid double casting as `unknown` when updating values from the server. These server responses get reorganized as typed models elsewhere in the codebase, maintaining type safety where it matters most while keeping the code clean.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-05-28T16:12:31.310Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/router/routes.ts:96-99
Timestamp: 2025-05-28T16:12:31.310Z
Learning: In webroot/src/router/routes.ts, the team prefers to keep router logic simple and handle route parameter validation (like state abbreviations) in the page components themselves based on user permissions, rather than adding validation at the router level.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-25T19:04:48.800Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1014
File: backend/compact-connect/lambdas/python/provider-data-v1/tests/function/test_handlers/test_account_recovery.py:288-293
Timestamp: 2025-08-25T19:04:48.800Z
Learning: In the CompactConnect project, landonshumway-ia has already provided feedback on patch cleanup patterns in test setup methods for the account recovery tests, so similar suggestions about stopping patches in setUp/tearDown should not be repeated.
Applied to files:
webroot/src/network/searchApi/data.api.ts
🧬 Code graph analysis (1)
webroot/src/network/searchApi/data.api.ts (3)
webroot/src/network/licenseApi/data.api.ts (1)
DataApiInterface(56-58)webroot/src/network/searchApi/interceptors.ts (1)
requestSuccess(16-27)webroot/src/models/Licensee/Licensee.model.ts (1)
LicenseeSerializer(402-470)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: CheckWebroot
- GitHub Check: TestApp
🔇 Additional comments (1)
webroot/src/network/searchApi/data.api.ts (1)
213-242: Excellent work addressing previous feedback!All the issues from the previous review have been resolved:
- The date range logic now correctly uses
shouldwithminimum_should_match: 1(lines 214-215, 240), allowing privileges to match if eitherdateOfIssuanceORdateOfRenewalfalls within the range.- Variable naming typos (
serverReponse→serverResponse) have been fixed on lines 372 and 397.- Default empty array for
providershas been added on line 373 to prevent potential TypeError.The query building logic is well-structured and handles the OpenSearch nested queries correctly for privileges, adverse actions, and investigations.
Also applies to: 372-373, 397-397
|
Not related to this PR but active since doesn't seem to be fully functional here: http://localhost:3018/Search/octp/a87cc993-100d-42dc-8769-a36b0580b621
|
|
Im not sure how to validate the pagination on legacy lists. Do we have an example that has multiple pages? |
ChiefStief
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good! I have a couple nitpicks
|
|
|
@jlkravitz This is ready for your review. |
jlkravitz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought I submitted this, but I guess not. I'd still like to test locally, but leaving these here to start!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts (2)
118-134: Infinity symbol visual alignment noted in PR discussion.The use of
∞for unbounded date ranges is clear, but as noted in the PR comments, there's a visual concern about the infinity symbol's size and vertical centering with the dash. While the author asked if a design cycle is needed, consider whether a small CSS adjustment (e.g.,vertical-align: middleor adjustedfont-size) could address the visual issue without a full design cycle.Also applies to: 168-184
399-423: Consider dynamic filename for privilege exports.The hardcoded filename
privilege_export.csvcould be enhanced with a timestamp or search criteria summary to help users distinguish between multiple exports.📝 Optional filename enhancement
- tempLink.download = `privilege_export.csv`; + const timestamp = moment().format('YYYY-MM-DD_HHmmss'); + tempLink.download = `privilege_export_${timestamp}.csv`;
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
webroot/src/components/Licensee/LicenseeList/LicenseeList.tswebroot/src/components/Lists/ListContainer/ListContainer.vuewebroot/src/network/mocks/mock.data.api.tswebroot/src/network/searchApi/data.api.ts
🧰 Additional context used
🧠 Learnings (15)
📚 Learning: 2025-12-18T19:09:11.026Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1234
File: webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.spec.ts:68-112
Timestamp: 2025-12-18T19:09:11.026Z
Learning: In webroot/src/components/Lists/PaginationLegacy/PaginationLegacy.spec.ts, the tests for "should advance with next page (2)" and "should advance with next page (3)" intentionally share pagination state by reusing the same paginationId ('test'). This shared state is a deliberate testing pattern, not a test isolation issue.
Applied to files:
webroot/src/components/Lists/ListContainer/ListContainer.vue
📚 Learning: 2025-12-19T16:04:23.341Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1234
File: webroot/src/network/searchApi/data.api.ts:83-95
Timestamp: 2025-12-19T16:04:23.341Z
Learning: In the CompactConnect codebase, all network API files under webroot/src/network/*/data.api.ts use a specific axios.create header configuration pattern with nested get/post/put objects inside the headers config. Reviewers should not flag this pattern as an issue, since it aligns with the project’s Axios version and conventions. If enforcing general axios patterns, treat this as a project-specific exception and focus on consistency within this path.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-21T15:23:26.019Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1025
File: webroot/src/models/Licensee/Licensee.model.ts:242-254
Timestamp: 2025-08-21T15:23:26.019Z
Learning: In the CompactConnect codebase, the LicenseSerializer.fromServer() method maps the server response field `dateOfIssuance` to the License model's `issueDate` property. After serialization, License instances only contain `issueDate` and never have `dateOfIssuance`. When reviewing date comparisons in reducers that work with License objects, check if they're working with serialized License instances (which use `issueDate`) rather than raw server data (which uses `dateOfIssuance`).
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-13T22:13:48.430Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1188
File: backend/compact-connect/tests/smoke/rollback_license_upload_smoke_tests.py:354-372
Timestamp: 2025-11-13T22:13:48.430Z
Learning: In the CompactConnect codebase, privilege records use datetime fields (not date fields) for dateOfIssuance, dateOfRenewal, and dateOfExpiration, which is intentionally different from license records that use date fields for these same attributes.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-13T20:28:33.191Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 1011
File: webroot/src/models/Licensee/Licensee.model.ts:276-279
Timestamp: 2025-08-13T20:28:33.191Z
Learning: The two-year encumbrance wait period feature only applies to privileges, not licenses. The logic should only check if privilege encumbrances that are no longer active have lift dates within the past two years.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-11-12T21:06:06.981Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/components/LicenseCard/LicenseCard.ts:388-396
Timestamp: 2025-11-12T21:06:06.981Z
Learning: In the CompactConnect investigation creation flow, the backend APIs for creating investigations (both `createLicenseInvestigation` and `createPrivilegeInvestigation` in webroot/src/network/licenseApi/data.api.ts) do not accept a `startDate` parameter. The backend automatically sets the investigation creation date to the timestamp when the API request is received, so the frontend UI does not need to capture or submit an investigation start date during the creation workflow.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-07-08T18:40:24.408Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 882
File: backend/compact-connect/lambdas/python/common/cc_common/data_model/compact_configuration_client.py:287-359
Timestamp: 2025-07-08T18:40:24.408Z
Learning: In the CompactConnect codebase, landonshumway-ia prefers to avoid extraneous unit tests when existing test coverage is already sufficient to catch bugs. For the get_privilege_purchase_options method's live-jurisdiction filtering logic, the existing tests in the purchases test suite provide adequate coverage without needing additional edge case tests.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-07-02T21:10:06.663Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 904
File: webroot/src/components/StateSettingsList/StateSettingsList.ts:49-49
Timestamp: 2025-07-02T21:10:06.663Z
Learning: In the CompactConnect TypeScript codebase, the team generally avoids `any` types but makes an exception for server responses. They use `any` for server response data to prevent overly verbose TypeScript syntax and avoid double casting as `unknown` when updating values from the server. These server responses get reorganized as typed models elsewhere in the codebase, maintaining type safety where it matters most while keeping the code clean.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-05-28T16:12:31.310Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/router/routes.ts:96-99
Timestamp: 2025-05-28T16:12:31.310Z
Learning: In webroot/src/router/routes.ts, the team prefers to keep router logic simple and handle route parameter validation (like state abbreviations) in the page components themselves based on user permissions, rather than adding validation at the router level.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-06-18T21:57:02.978Z
Learnt from: jusdino
Repo: csg-org/CompactConnect PR: 864
File: backend/compact-connect/tests/smoke/encumbrance_smoke_tests.py:256-262
Timestamp: 2025-06-18T21:57:02.978Z
Learning: The `licenseJurisdiction` field is a required field in the provider data API response from the `/v1/providers/users/me` endpoint, so it can be accessed directly without defensive programming checks.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-08-25T19:04:48.800Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1014
File: backend/compact-connect/lambdas/python/provider-data-v1/tests/function/test_handlers/test_account_recovery.py:288-293
Timestamp: 2025-08-25T19:04:48.800Z
Learning: In the CompactConnect project, landonshumway-ia has already provided feedback on patch cleanup patterns in test setup methods for the account recovery tests, so similar suggestions about stopping patches in setUp/tearDown should not be repeated.
Applied to files:
webroot/src/network/searchApi/data.api.ts
📚 Learning: 2025-06-24T00:02:39.944Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 873
File: webroot/src/components/LicenseCard/LicenseCard.ts:414-443
Timestamp: 2025-06-24T00:02:39.944Z
Learning: In LicenseCard component's clickUnencumberItem method (webroot/src/components/LicenseCard/LicenseCard.ts), complex event handling for checkbox interactions is intentionally designed to ensure consistent behavior across checkbox input, wrapper label, and outer selection parent elements for custom UI requirements. This complexity should be preserved rather than simplified.
Applied to files:
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-11-06T18:11:58.272Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1196
File: webroot/src/network/mocks/mock.data.ts:1919-1944
Timestamp: 2025-11-06T18:11:58.272Z
Learning: In CompactConnect, the investigation event type (`updateType: 'investigation'`) in privilege/license history is intentionally not yet fully supported in the frontend UI translation and categorization logic (webroot/src/locales/*.json and webroot/src/models/LicenseHistoryItem/LicenseHistoryItem.model.ts). The server license history API needs to be updated first to return sufficient information about investigation events. Until then, the UI gracefully falls back to displaying "Unknown" for investigation events, which is acceptable as an interim solution.
<!--
Applied to files:
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-08-29T18:29:16.953Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/MfaResetStartLicensee/MfaResetStartLicensee.vue:141-146
Timestamp: 2025-08-29T18:29:16.953Z
Learning: In the MfaResetStartLicensee component, license type keys (like "audiologist") are displayed directly in the summary using CSS `text-transform: capitalize` because the keys are human-readable strings, rather than using separate display name lookups.
Applied to files:
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
📚 Learning: 2025-06-09T19:57:51.519Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 851
File: webroot/src/pages/RegisterLicensee/RegisterLicensee.ts:0-0
Timestamp: 2025-06-09T19:57:51.519Z
Learning: In the RegisterLicensee component, when handling DOM element availability issues, the developer prefers using Vue Watchers over retry mechanisms with requestAnimationFrame to avoid infinite recursion risks and maintain Vue's reactive patterns.
Applied to files:
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
🧬 Code graph analysis (3)
webroot/src/network/mocks/mock.data.api.ts (2)
webroot/src/network/mocks/mock.data.ts (1)
licensees(434-1261)webroot/src/models/Licensee/Licensee.model.ts (1)
LicenseeSerializer(402-470)
webroot/src/network/searchApi/data.api.ts (2)
webroot/src/network/searchApi/interceptors.ts (4)
requestSuccess(16-27)requestError(34-34)responseSuccess(43-47)responseError(54-76)webroot/src/models/Licensee/Licensee.model.ts (1)
LicenseeSerializer(402-470)
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts (3)
webroot/src/models/State/State.model.ts (1)
State(21-49)webroot/src/app.config.ts (2)
serverDateFormat(175-175)displayDateFormat(181-181)webroot/src/network/searchApi/data.api.ts (1)
SearchParamsInterfaceLocal(20-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: TestApp
- GitHub Check: CheckWebroot
🔇 Additional comments (14)
webroot/src/components/Lists/ListContainer/ListContainer.vue (2)
63-82: LGTM! Bottom pagination mirrors top pagination correctly.The bottom pagination block follows the same conditional rendering pattern as the top pagination (lines 24-41), ensuring consistency throughout the component. The dual-branch approach cleanly separates legacy and modern pagination implementations.
24-41: Verify that modern Pagination doesn't require prev/next key props.The modern
Paginationcomponent (lines 34-41 and 74-82) correctly omitspagingPrevKeyandpagingNextKeyprops. ThePaginationcomponent uses offset-based paging (withpageChangeacceptingfirstIndexandlastIndexExclusive), whilePaginationLegacyuses cursor-based pagination (requiring the prev/next key props and passingPageChangeConfigwithprevNextfield). This difference is intentional and the implementation is correct.The
v-else-ifcondition explicitly recheckinghasRecords && !excludeTopPaginationis redundant but acceptable for clarity and self-documentation.webroot/src/components/Licensee/LicenseeList/LicenseeList.ts (4)
382-394: Correct field mapping for sorting.The
lastName→familyNamemapping aligns with the server API expectations and correctly reverses the serialization mapping wherefamilyNamefrom the server is mapped tolastNamein the Licensee model.
43-43: Good error handling pattern with searchErrorOverride.The
searchErrorOverrideproperty provides a clean way to display custom error messages for privilege export failures while keeping the regular search error handling intact.Also applies to: 241-241, 408-408, 414-414
302-321: Clear separation of provider search and privilege export flows.The branching logic correctly routes provider searches to the standard list view and privilege searches to the export/download flow, with appropriate configuration for each path.
100-190: Well-structured display getters for search criteria.The new display getters provide a clean, consistent pattern for formatting search parameters with proper i18n support, state name lookups, and date formatting. The implementation correctly uses the State model and translation utilities.
webroot/src/network/mocks/mock.data.api.ts (2)
552-565: Mock implementation supports pagination testing.The mock correctly creates multi-page test data by concatenating providers and calculating a
totalMatchCountthat simulates 10 pages of results, which is suitable for testing pagination behavior.
568-573: LGTM!The privilege export mock provides appropriate simulation of the download flow with a realistic wait time for an export operation.
webroot/src/network/searchApi/data.api.ts (6)
78-97: Axios configuration follows project conventions.The nested headers structure (get/post/put inside headers config) aligns with the established pattern used throughout the CompactConnect network layer. The 30-second timeout is appropriate for search and export operations.
Based on learnings, this pattern is project-specific and should not be modified.
61-69: Useful runtime debugging utility.The
ccQueryToggle()function provides a convenient way to enable/disable query logging during development and troubleshooting, accessible directly from the browser console.
246-286: Correctly structured nested queries for adverse actions.The double-nested query structure (licensee → licenses/privileges → adverseActions) is appropriate for OpenSearch and correctly searches across both license and privilege adverse actions using a
shouldclause withminimum_should_match: 1.
290-325: Investigation status query logic is sound.The conditional branching correctly uses
shouldfor "underInvestigation" status (matching any investigation) andmust_notfor other statuses (excluding all investigations), with proper nested query structure across both licenses and privileges.
332-340: Correct pagination calculation.The
fromoffset calculationpageSize * (pageNumber - 1)correctly converts 1-based page numbers to 0-based offsets for OpenSearch pagination.
213-239: Date range queries correctly handle datetime fields. The privilegedateOfIssuanceanddateOfRenewalfields are DateTime fields in the backend schema (confirmed inprivilege/record.pylines 88-89), and the frontend passes date-only values (YYYY-MM-DD format) from the search parameters. OpenSearch/Elasticsearch correctly interprets date-only values in range queries against datetime fields, treating them as the start and end of day respectively. The current query construction is correct and no changes are needed.
jlkravitz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isabeleliassen Good to merge!





Requirements List
VUE_APP_API_SEARCH_ROOT=https://search.test.jcc.iaapi.ioVUE_APP_STATSIG_DISABLED=falseDescription List
searchApito the networking directory*Legacy- and added new versions in their place:ccQueryToggle()Testing List
yarn test:unit:allshould run without errors or warningsyarn serveshould run without errors or warningsyarn buildshould run without errors or warnings*Legacynamed files haven't changed any code from their previous version, they are just renamed; so not a lot of time needs to be spent code reviewing*Legacynamed files.anys used, either existing in the Legacy files, or in spot cases in new code where time was a factorVUE_APP_API_SEARCH_ROOTenv var aboveCloses #1177
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.