Skip to content

[SOLID] Architecture refinement#14

Open
thangqp wants to merge 3 commits into
mainfrom
solid_principes_reorganize
Open

[SOLID] Architecture refinement#14
thangqp wants to merge 3 commits into
mainfrom
solid_principes_reorganize

Conversation

@thangqp
Copy link
Copy Markdown

@thangqp thangqp commented May 15, 2026

PR Summary

Signed-off-by: Thang PHAM <phamthang37@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Review Change Stack

Warning

Rate limit exceeded

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

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

⌛ How to resolve this issue?

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

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

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

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

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3851cbbd-8466-48e5-b4f2-3e98d4a70e1c

📥 Commits

Reviewing files that changed from the base of the PR and between 5cf061e and 4ce60b5.

📒 Files selected for processing (6)
  • src/features/top-bar/components/AppTopBar.tsx
  • src/shared/api/config-api/config-api.type.ts
  • src/shared/config/config-params.ts
  • src/shared/test-utils/config-params/create-test-config-params.ts
  • src/shared/test-utils/config-params/setup-test-config-params.ts
  • vitest.setup.ts
📝 Walkthrough

Walkthrough

This PR refactors application configuration and authentication token handling by introducing a centralized configuration system, converting app parameter hooks from Redux-dependent to prop-based authentication, and updating the test infrastructure with a new context builder.

Changes

Configuration, Authentication & Hook Refactoring

Layer / File(s) Summary
Centralized configuration system
src/shared/config/config-params.ts, src/app/config/app-config.ts, src/app/store/store.ts, src/shared/test-utils/create-test-config-params.ts
Introduces one-time centralized configuration for appName and tokenSelector, initialized in app-config.ts and registered in the store. Test setup via createTestConfigParams().
Authentication token selector and RTK Query integration
src/features/authentication/store/authentication.type.ts, src/features/authentication/store/authentication.selectors.ts, src/shared/api/rtk-query/base-api.ts, src/shared/api/ws/config-ws.ts, src/shared/api/ws/monitor-ws.ts, src/shared/api/ws/ws.utils.ts
Adds StateWithAuthentication type and selectToken selector; RTK Query prepareHeaders and WebSocket utilities now derive token and appName from centralized config instead of static imports or direct Redux access.
Unified dispatch typing for shared modules
src/shared/store/state.type.ts, src/shared/api/config-api/config.enhanced.ts, src/shared/api/monitor-api/monitor.enhanced.ts
Introduces AnyAppDispatch type for broader testability; updates shared API helpers to accept the new dispatch type.
App parameter hooks refactoring to prop-based authentication
src/features/app-parameters/hooks/use-get-config-parameter-with-fallback.ts, src/features/app-parameters/hooks/use-app-parameter-state.ts, src/features/app-parameters/hooks/use-app-parameters-invalidation-listener.ts, src/features/app-parameters/store/app-parameters.type.ts, src/features/app-parameters/store/app-parameters.local-storage.ts, src/shared/api/config-api/config-api.type.ts, src/shared/api/config-api/config-api.local-storage.ts
Hooks now accept isAuthenticated as a prop instead of deriving from Redux; type definitions and localStorage helpers are centralized in shared/api/config-api modules and re-exported from features.
App initialization and hook wiring
src/app/providers/AppProviders.tsx, src/app/App.tsx, src/features/top-bar/components/AppTopBar.tsx, src/features/top-bar/api/get-servers-infos.ts
AppProviders reads authenticated user and passes isAuthenticated to config hooks; AppTopBar derives isAuthenticated, uses typed dispatch, and passes it through component hierarchy; getServersInfos now accepts dispatch parameter.
Process invalidation listener refactoring
src/features/process-config/hooks/use-process-invalidation-listener.ts
Renames useProcessInvalidationsListener to useProcessInvalidationListener, introduces UseProcessInvalidationListenerProps type, and uses typed AnyAppDispatch.
Import path consolidation and re-exports
src/shared/api/ws/ws-client.ts, src/features/process/execute/components/ExecuteProcessResult.tsx, src/features/process/results/models/process-result.ts, src/shared/store/rtk-query-error-middleware.ts
Consolidates module imports and switches type imports to shared API paths instead of deep relative paths.

Test Infrastructure Migration

Layer / File(s) Summary
Test context builder with store setup
src/features/test-utils/create-base-context.tsx, src/shared/test-utils/create-test-config-params.ts, vitest.setup.ts
Introduces createBaseContext() that configures Redux store with API reducers and errorMiddleware, returning store and Provider wrapper; vitest.setup.ts calls createTestConfigParams() early to initialize test config singleton.
App parameter hook tests migration
src/features/app-parameters/__tests__/hooks/*
Tests updated to use createBaseContext; hook invocations changed to match new prop-based signatures; coverage extended for unauthenticated scenarios with local-storage fallback tests.
Feature page tests migration to createBaseContext
src/features/process-config/__tests__/pages/*, src/features/process/__tests__/pages/*
ProcessConfigListPage, ProcessExecutePage, ProcessResultsPage, and ProcessStepInfosPage tests now use createBaseContext wrapper instead of createTestContext.

Linting and Build Configuration

Layer / File(s) Summary
Path-based import restrictions
eslint.config.js
Adds import-x/no-restricted-paths rule to enforce layer separation: src/shared cannot import from src/features or src/app; src/features cannot import from src/app.

Suggested reviewers

  • antoinebhs
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[SOLID] Architecture refinement' is partially related to the main changes. While the PR implements SOLID principles and architectural rules, the title is somewhat generic and does not clearly indicate the specific architectural refinement (e.g., introducing import restriction zones).
Description check ✅ Passed The description directly relates to the changeset, explaining both the architectural rules being added (zones for enforcing contracts between app, features, shared) and the SOLID principle refactoring. It accurately summarizes the PR's intent.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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

❤️ Share

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

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

license-eye has totally checked 137 files.

Valid Invalid Ignored Fixed
106 1 30 0
Click to see the invalid file list
  • src/shared/api/study-api/study-api.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (5)
eslint.config.js (1)

143-154: ⚡ Quick win

Consider adding custom error messages for each zone restriction.

Adding a message property to each zone would provide clearer feedback when developers accidentally violate the architectural boundaries.

💬 Suggested enhancement with custom messages
 'import-x/no-restricted-paths': [
     'error',
     {
         zones: [
             // shared must not import from features or app
-            { target: './src/shared', from: './src/features' },
-            { target: './src/shared', from: './src/app' },
+            { 
+                target: './src/shared', 
+                from: './src/features',
+                message: 'Shared modules cannot import from features. Shared must remain dependency-free.'
+            },
+            { 
+                target: './src/shared', 
+                from: './src/app',
+                message: 'Shared modules cannot import from app. Shared must remain dependency-free.'
+            },
             // features must not import from app
-            { target: './src/features', from: './src/app' },
+            { 
+                target: './src/features', 
+                from: './src/app',
+                message: 'Features cannot import from app. Move shared logic to features or shared layers.'
+            },
         ],
     },
 ],

The rule syntax is compatible with eslint-plugin-import-x v4.16.2 and the zone configuration format is properly supported.

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

In `@eslint.config.js` around lines 143 - 154, The import-x/no-restricted-paths
rule currently blocks imports between zones but omits human-friendly messages;
update the zones array used by 'import-x/no-restricted-paths' to add a message
string to each zone object (e.g., the entries with target './src/shared' from
'./src/features' and './src/app', and the entry with target './src/features'
from './src/app') so ESLint reports a clear, custom error when a developer
violates these architectural boundaries; keep the existing targets and from
fields and only add concise, actionable 'message' values explaining why the
import is disallowed.
src/app/config/app-config.ts (1)

11-11: 💤 Low value

Remove unnecessary type assertion.

The selectToken function signature (state: StateWithAuthentication) => string | undefined is compatible with TokenSelector = (state: unknown) => string | undefined due to TypeScript's structural subtyping (contravariance on parameter types). The as TokenSelector assertion is unnecessary and could mask future signature drift.

♻️ Simplify to implicit type compatibility
-configureParams({ appName: APP_NAME, tokenSelector: selectToken as TokenSelector });
+configureParams({ appName: APP_NAME, tokenSelector: selectToken });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/config/app-config.ts` at line 11, The code currently uses an
unnecessary type assertion on selectToken when calling configureParams; remove
the "as TokenSelector" cast so the call becomes configureParams({ appName:
APP_NAME, tokenSelector: selectToken }); this relies on TypeScript's structural
typing and avoids masking future signature drift—update the call site that
references configureParams, APP_NAME and selectToken accordingly.
src/app/providers/AppProviders.tsx (1)

19-20: ⚖️ Poor tradeoff

Fragile module initialization order dependency.

The side-effect import on line 19 must execute before line 20 because:

  1. app/config/app-config calls configureParams(...) at module load
  2. app/store/store creates the store (line 31) and calls updateConfigParams({ store }) (line 33)
  3. updateConfigParams will throw if configureParams hasn't been called first

This ordering is correct but fragile—swapping these imports would cause a runtime error. The ES module specification guarantees import order, but this implicit dependency is easy to break during refactoring.

Consider making initialization explicit:

  • Move configureParams call to an exported initialization function in app-config.ts
  • Call it explicitly from an app entry point before importing the store
  • Or use a lazy store initialization pattern
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/providers/AppProviders.tsx` around lines 19 - 20, The current
side-effect import of app/config/app-config (which runs configureParams at
module load) is a fragile implicit dependency for app/store/store (which creates
store and calls updateConfigParams); refactor to make initialization explicit by
exporting a setup function (e.g., initAppConfig or configureParamsExplicit) from
app-config that performs configureParams, then call that setup from a single app
entry point before any import/use of store or useAppSelector, or alternatively
implement a lazyStore initializer inside app/store/store that defers store
creation until after configureParamsExplicit is called; update references to
configureParams, app-config, store, useAppSelector, and updateConfigParams
accordingly so initialization order is enforced explicitly rather than relying
on side-effect import order.
src/features/authentication/store/authentication.selectors.ts (1)

12-12: 💤 Low value

Consider adding explicit return type for clarity.

While TypeScript correctly infers string | undefined, adding an explicit return type improves readability and prevents unintended signature changes, especially since this selector is used as a TokenSelector in the centralized configuration.

📝 Add explicit return type
-export const selectToken = (state: StateWithAuthentication) => selectUser(state)?.id_token;
+export const selectToken = (state: StateWithAuthentication): string | undefined => 
+    selectUser(state)?.id_token;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/authentication/store/authentication.selectors.ts` at line 12,
The selector selectToken currently relies on inferred return type; update its
signature to include an explicit return type (e.g., string | undefined) to match
the TokenSelector expectation and avoid accidental signature changes—modify
selectToken(state: StateWithAuthentication): string | undefined { ... } (ensure
the return type aligns with the TokenSelector used in your centralized
configuration).
src/shared/config/config-params.ts (1)

28-33: ⚡ Quick win

Validate store is not updated after initial registration.

updateConfigParams allows replacing the store reference after initialization. Since the store should only be set once (after creation in store.ts), consider preventing subsequent store updates to avoid accidental reconfigurations.

🛡️ Proposed safeguard
 export function updateConfigParams(config: Partial<ConfigParams>): void {
     if (configParams === undefined) {
         throw new Error('Config params not initialized. Call configureParams() before using modules.');
     }
+    if (config.store && configParams.store) {
+        throw new Error('Store already registered. Cannot update store reference.');
+    }
     Object.assign(configParams, config);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/config/config-params.ts` around lines 28 - 33, updateConfigParams
currently allows replacing the existing store reference which can lead to
accidental reconfiguration; modify updateConfigParams to detect when the
incoming partial config contains a store and the existing configParams.store is
already set, and in that case prevent overwriting (either by throwing an Error
or by ignoring the store field) while still applying other allowed fields via
Object.assign; refer to updateConfigParams and the configParams.store field (and
the store creation in store.ts) when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/features/top-bar/components/AppTopBar.tsx`:
- Line 38: The current authentication boolean uses a strict null check (const
isAuthenticated = user !== null) which treats undefined as authenticated; change
the derivation to a nullish check so only actual users are considered
authenticated (update the isAuthenticated assignment in AppTopBar.tsx to use
user != null to cover both null and undefined, referencing the user variable and
the isAuthenticated const).

In `@src/shared/api/config-api/config-api.type.ts`:
- Around line 27-29: The UpdateConfigParameterRequest allows invalid name/value
pairs because it uses a widened union; replace it with a discriminated-union
style definition that ties each name to its specific value type (matching the
existing ConfigParameter pattern). Concretely, redefine
UpdateConfigParameterRequest to map each AppParametersKey K to an object { name:
K; value: AppParameters[K] } and take the union of those entries (i.e., the
mapped type indexed over AppParametersKey) so that name and value are always
consistent; reference UpdateConfigParameterRequest, AppParametersKey,
AppParameters, and ConfigParameter when making the change.

In `@src/shared/config/config-params.ts`:
- Around line 46-48: Declare an explicit return type for getToken (e.g. unknown
| undefined) and guard against a missing store before calling the selector: call
getConfigParams(), extract cfg.tokenSelector and cfg.store, if cfg.store is
undefined return undefined immediately, otherwise call
cfg.tokenSelector(cfg.store.getState()) and return its result; reference
getToken, getConfigParams, tokenSelector and store.getState in your changes.

In `@vitest.setup.ts`:
- Around line 10-15: The createTestConfigParams() call must run before any
module side-effects in setup-msw; fix by moving the call into a small
side-effect module (e.g., initTestConfigParams) that imports and invokes
createTestConfigParams(), then import that new side-effect module before
importing setup-msw in vitest.setup.ts so initialization order guarantees are
upheld; update vitest.setup.ts to import initTestConfigParams (which calls
createTestConfigParams) first, then import setup-msw.

---

Nitpick comments:
In `@eslint.config.js`:
- Around line 143-154: The import-x/no-restricted-paths rule currently blocks
imports between zones but omits human-friendly messages; update the zones array
used by 'import-x/no-restricted-paths' to add a message string to each zone
object (e.g., the entries with target './src/shared' from './src/features' and
'./src/app', and the entry with target './src/features' from './src/app') so
ESLint reports a clear, custom error when a developer violates these
architectural boundaries; keep the existing targets and from fields and only add
concise, actionable 'message' values explaining why the import is disallowed.

In `@src/app/config/app-config.ts`:
- Line 11: The code currently uses an unnecessary type assertion on selectToken
when calling configureParams; remove the "as TokenSelector" cast so the call
becomes configureParams({ appName: APP_NAME, tokenSelector: selectToken }); this
relies on TypeScript's structural typing and avoids masking future signature
drift—update the call site that references configureParams, APP_NAME and
selectToken accordingly.

In `@src/app/providers/AppProviders.tsx`:
- Around line 19-20: The current side-effect import of app/config/app-config
(which runs configureParams at module load) is a fragile implicit dependency for
app/store/store (which creates store and calls updateConfigParams); refactor to
make initialization explicit by exporting a setup function (e.g., initAppConfig
or configureParamsExplicit) from app-config that performs configureParams, then
call that setup from a single app entry point before any import/use of store or
useAppSelector, or alternatively implement a lazyStore initializer inside
app/store/store that defers store creation until after configureParamsExplicit
is called; update references to configureParams, app-config, store,
useAppSelector, and updateConfigParams accordingly so initialization order is
enforced explicitly rather than relying on side-effect import order.

In `@src/features/authentication/store/authentication.selectors.ts`:
- Line 12: The selector selectToken currently relies on inferred return type;
update its signature to include an explicit return type (e.g., string |
undefined) to match the TokenSelector expectation and avoid accidental signature
changes—modify selectToken(state: StateWithAuthentication): string | undefined {
... } (ensure the return type aligns with the TokenSelector used in your
centralized configuration).

In `@src/shared/config/config-params.ts`:
- Around line 28-33: updateConfigParams currently allows replacing the existing
store reference which can lead to accidental reconfiguration; modify
updateConfigParams to detect when the incoming partial config contains a store
and the existing configParams.store is already set, and in that case prevent
overwriting (either by throwing an Error or by ignoring the store field) while
still applying other allowed fields via Object.assign; refer to
updateConfigParams and the configParams.store field (and the store creation in
store.ts) when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5ff8315e-2b95-41d3-a17d-85ce7363df4e

📥 Commits

Reviewing files that changed from the base of the PR and between e763cec and 5cf061e.

📒 Files selected for processing (44)
  • eslint.config.js
  • src/app/App.tsx
  • src/app/config/app-config.ts
  • src/app/providers/AppProviders.tsx
  • src/app/store/store.ts
  • src/features/app-parameters/__tests__/hooks/use-app-parameter-state.test.ts
  • src/features/app-parameters/__tests__/hooks/use-app-parameters-invalidation-listener.test.ts
  • src/features/app-parameters/__tests__/hooks/use-get-config-parameter-with-fallback.test.ts
  • src/features/app-parameters/hooks/use-app-parameter-state.ts
  • src/features/app-parameters/hooks/use-app-parameters-invalidation-listener.ts
  • src/features/app-parameters/hooks/use-get-config-parameter-with-fallback.ts
  • src/features/app-parameters/store/app-parameters.local-storage.ts
  • src/features/app-parameters/store/app-parameters.type.ts
  • src/features/authentication/store/authentication.selectors.ts
  • src/features/authentication/store/authentication.type.ts
  • src/features/process-config/__tests__/hooks/use-process-invalidation-listener.test.ts
  • src/features/process-config/__tests__/pages/ProcessConfigListPage.test.tsx
  • src/features/process-config/hooks/use-process-invalidation-listener.ts
  • src/features/process/execute/__tests__/pages/ProcessExecutePage.test.tsx
  • src/features/process/execute/components/ExecuteProcessResult.tsx
  • src/features/process/results/__tests__/pages/ProcessResultsPage.test.tsx
  • src/features/process/results/__tests__/pages/ProcessStepInfosPage.test.tsx
  • src/features/process/results/models/process-result.ts
  • src/features/test-utils/create-base-context.tsx
  • src/features/top-bar/api/get-servers-infos.ts
  • src/features/top-bar/components/AppNavBar.tsx
  • src/features/top-bar/components/AppTopBar.tsx
  • src/shared/api/config-api/config-api.local-storage.ts
  • src/shared/api/config-api/config-api.type.ts
  • src/shared/api/config-api/config.enhanced.ts
  • src/shared/api/monitor-api/monitor.enhanced.ts
  • src/shared/api/rtk-query/base-api.ts
  • src/shared/api/study-api/study-api.ts
  • src/shared/api/ws/config-ws.ts
  • src/shared/api/ws/monitor-ws.ts
  • src/shared/api/ws/ws-client.ts
  • src/shared/api/ws/ws.utils.ts
  • src/shared/config/config-params.ts
  • src/shared/store/rtk-query-error-middleware.ts
  • src/shared/store/state.type.ts
  • src/shared/test-utils/create-test-config-params.ts
  • src/shared/test-utils/msw/server.ts
  • src/shared/test-utils/msw/setup-msw.ts
  • vitest.setup.ts
💤 Files with no reviewable changes (1)
  • src/shared/api/ws/ws.utils.ts

const navigate = useNavigate();
const dispatch = useAppDispatch();
const dispatch = useDispatch<AnyAppDispatch>();
const isAuthenticated = user !== null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix authentication boolean derivation for optional user.

Line 38 treats undefined as authenticated. Since user is optional, use a nullish check (!= null) so only real users are authenticated.

✅ Proposed fix
-    const isAuthenticated = user !== null;
+    const isAuthenticated = user != null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isAuthenticated = user !== null;
const isAuthenticated = user != null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/top-bar/components/AppTopBar.tsx` at line 38, The current
authentication boolean uses a strict null check (const isAuthenticated = user
!== null) which treats undefined as authenticated; change the derivation to a
nullish check so only actual users are considered authenticated (update the
isAuthenticated assignment in AppTopBar.tsx to use user != null to cover both
null and undefined, referencing the user variable and the isAuthenticated
const).

Comment on lines +27 to +29
export type UpdateConfigParameterRequest = {
name: AppParametersKey;
value: AppParameters[AppParametersKey];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current definition and inspect all usages of UpdateConfigParameterRequest.
set -euo pipefail

sed -n '1,120p' src/shared/api/config-api/config-api.type.ts
rg -n -C3 'UpdateConfigParameterRequest' src

Repository: gridsuite/gridmonitor-app

Length of output: 1492


🏁 Script executed:

#!/bin/bash
# Find all usages of UpdateConfigParameterRequest in the codebase
rg 'UpdateConfigParameterRequest' src --max-count=100 -B 2 -A 5

Repository: gridsuite/gridmonitor-app

Length of output: 469


🏁 Script executed:

#!/bin/bash
# Search for imports and usages of UpdateConfigParameterRequest
rg 'UpdateConfigParameterRequest' . --max-count=50

# Also search for files that might use it (config-api related files)
find src -name "*config*api*" -type f

# Check if it's used in service/API files
rg -l 'config.*api' src --max-count=20

Repository: gridsuite/gridmonitor-app

Length of output: 923


🏁 Script executed:

#!/bin/bash
# Search for imports of UpdateConfigParameterRequest
rg 'import.*UpdateConfigParameterRequest' src

# Check config-base-api.ts which likely has API service methods
cat -n src/shared/api/config-api/config-base-api.ts

# Check for any reference to the type name in broader context
rg -i 'updateconfigparameterrequest' . --type ts

Repository: gridsuite/gridmonitor-app

Length of output: 975


🏁 Script executed:

#!/bin/bash
# Check the enhanced config API file
cat -n src/shared/api/config-api/config.enhanced.ts

# Also check local storage implementation
cat -n src/shared/api/config-api/config-api.local-storage.ts

Repository: gridsuite/gridmonitor-app

Length of output: 4476


🏁 Script executed:

#!/bin/bash
# Check the generated config API file
cat -n src/shared/api/config-api/config.generated.ts

Repository: gridsuite/gridmonitor-app

Length of output: 1619


Improve type safety for UpdateConfigParameterRequest to prevent invalid name/value combinations.

The current type allows pairing incompatible values (e.g., PARAM_LANGUAGE with a theme value) due to the widened union. Although this type is not currently used in the codebase, standardizing it to a discriminated union pattern—matching the existing ConfigParameter type—ensures type safety if it's used in the future.

✅ Proposed type-safe fix
-export type UpdateConfigParameterRequest = {
-    name: AppParametersKey;
-    value: AppParameters[AppParametersKey];
-};
+export type UpdateConfigParameterRequest =
+    | { name: typeof PARAM_LANGUAGE; value: GsLang }
+    | { name: typeof PARAM_THEME; value: GsTheme };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/api/config-api/config-api.type.ts` around lines 27 - 29, The
UpdateConfigParameterRequest allows invalid name/value pairs because it uses a
widened union; replace it with a discriminated-union style definition that ties
each name to its specific value type (matching the existing ConfigParameter
pattern). Concretely, redefine UpdateConfigParameterRequest to map each
AppParametersKey K to an object { name: K; value: AppParameters[K] } and take
the union of those entries (i.e., the mapped type indexed over AppParametersKey)
so that name and value are always consistent; reference
UpdateConfigParameterRequest, AppParametersKey, AppParameters, and
ConfigParameter when making the change.

Comment thread src/shared/config/config-params.ts Outdated
Comment thread vitest.setup.ts Outdated
thangqp added 2 commits May 15, 2026 18:48
Signed-off-by: Thang PHAM <phamthang37@gmail.com>
Signed-off-by: Thang PHAM <phamthang37@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
64.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant