Skip to content

Conversation

@pggb25
Copy link
Collaborator

@pggb25 pggb25 commented Dec 30, 2025

… qovery admin)

Summary

Issue:

Screenshots / Recordings

Testing

  • Changes tested locally in the relevant Console's pages and Storybooks
  • yarn test or yarn test -u (if you need to regenerate snapshots)
  • yarn format
  • yarn lint

PR Checklist

  • I followed naming, styling, and TypeScript rules (see .cursor/rules)
  • I performed a self-review (diff inspected, dead code removed)
  • I titled the PR using Conventional Commits with a scope when possible (e.g. feat(service): add new Terraform service) - required for semantic-release
  • I only kept necessary comments, written in English (watch for useless AI comments)
  • I involved a designer to validate UI changes if I am not a designer
  • I covered new business logic with tests (unit)
  • I confirmed CI is green (Codecov red can be accepted)
  • I reviewed and executed locally any AI-assisted code

@RemiBonnet
Copy link
Member

Qovery Preview

Qovery can create a Preview Environment for this PR.
To trigger its creation, please post a comment with one of the following command.

Command Blueprint environment
/qovery preview cc1de7de-94e5-40f8-8e45-bc8986d9dfec storybook
/qovery preview 28c47145-c8e7-4b9d-8d9e-c65c95b48425 staging
/qovery preview {all|UUID1,UUID2,...} To preview multiple environments

This comment has been generated from Qovery AI 🤖.
Below, a word from its wisdom :

Help yourself at 2AM by putting some metrics to help observability

@codecov
Copy link

codecov bot commented Dec 31, 2025

Codecov Report

❌ Patch coverage is 34.25076% with 215 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.53%. Comparing base (a4d5d68) to head (5dbde4f).

Files with missing lines Patch % Lines
...ources-feature/page-settings-resources-feature.tsx 11.42% 24 Missing and 7 partials ⚠️
...re/src/lib/keda/components/keda-scalers-fields.tsx 0.00% 28 Missing ⚠️
...src/lib/keda/components/instances-range-inputs.tsx 33.33% 18 Missing and 4 partials ⚠️
...keda/scaled-object-status/scaled-object-status.tsx 0.00% 21 Missing ⚠️
...ture/step-summary-feature/step-summary-feature.tsx 9.09% 18 Missing and 2 partials ⚠️
...ture/src/lib/keda/components/hpa-metric-fields.tsx 0.00% 19 Missing ⚠️
...tings-resources/application-settings-resources.tsx 53.84% 12 Missing and 6 partials ⚠️
...ib/keda/autoscaling-payload/autoscaling-payload.ts 69.23% 2 Missing and 14 partials ⚠️
...eature/src/lib/service-details/service-details.tsx 0.00% 10 Missing ⚠️
...cation-settings-resources/fixed-instances-mode.tsx 35.71% 4 Missing and 5 partials ⚠️
... and 8 more
Additional details and impacted files
@@             Coverage Diff             @@
##           staging    #2265      +/-   ##
===========================================
- Coverage    49.14%   47.53%   -1.61%     
===========================================
  Files          811     1263     +452     
  Lines        16526    23002    +6476     
  Branches      4854     6757    +1903     
===========================================
+ Hits          8121    10935    +2814     
- Misses        6880     9964    +3084     
- Partials      1525     2103     +578     
Flag Coverage Δ
unittests 47.53% <34.25%> (-1.61%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pggb25 pggb25 force-pushed the feat/keda-cluster branch 10 times, most recently from 041a81e to aed396c Compare January 7, 2026 08:29
@pggb25 pggb25 force-pushed the feat/keda-cluster branch 7 times, most recently from bf0d6ba to 9d0dfd3 Compare January 14, 2026 16:54
Copy link
Member

@RemiBonnet RemiBonnet left a comment

Choose a reason for hiding this comment

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

Thanks Pierre 🙏

I added a few comments, but I think it would be better if I rewrite this part
The logic feels too complex for what are just small settings, and it currently affects some sensitive parts of the codebase. I think this logic should be isolated, as it is now, it’s hard to maintain and risky. Let’s talk about it tomorrow!

if (onChange) onChange(e)
setCurrentValue(e.currentTarget.value)
}}
onKeyDown={(e) => {
Copy link
Member

Choose a reason for hiding this comment

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

You can't change UI component need to remove it

* sanitizeKubernetesName('app__with--special!!!chars') // 'app-with-special-chars'
* sanitizeKubernetesName('-leading-and-trailing-') // 'leading-and-trailing'
*/
export function sanitizeKubernetesName(name: string): string {
Copy link
Member

Choose a reason for hiding this comment

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

Not used ?

autoscaling_scaler_type: __,
autoscaling_polling_interval: ___,
autoscaling_cooldown_period: ____,
scalers: _____,
Copy link
Member

Choose a reason for hiding this comment

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

Need to remove the fields field below?

min_running_instances: number
max_running_instances: number

// Autoscaling mode selection
Copy link
Member

Choose a reason for hiding this comment

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

Can we have an specific interface for keda and extends this one? (you can probably extends from the api doc)

payload,
},
{
onSuccess: () => {
Copy link
Member

Choose a reason for hiding this comment

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

Need to have an try catch instead of add it inside the onSuccess


editAdvancedSettings({
serviceId: service.id,
payload: advancedPayload as any,
Copy link
Member

Choose a reason for hiding this comment

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

We can't have any type


// HPA fields
hpa_metric_type: (() => {
const settings = advancedSettings as Record<string, any> | undefined
Copy link
Member

Choose a reason for hiding this comment

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

We can't use any

return 'CPU'
})(),
hpa_cpu_average_utilization_percent: (() => {
const settings = advancedSettings as Record<string, any> | undefined
Copy link
Member

Choose a reason for hiding this comment

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

We can't use any

return 60
})(),
hpa_memory_average_utilization_percent: (() => {
const settings = advancedSettings as Record<string, any> | undefined
Copy link
Member

Choose a reason for hiding this comment

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

We can't use any

@pggb25 pggb25 force-pushed the feat/keda-cluster branch 10 times, most recently from 7ec2455 to 7a94741 Compare January 16, 2026 11:35
@pggb25 pggb25 force-pushed the feat/keda-cluster branch 4 times, most recently from c03a9b5 to 7195bf1 Compare January 16, 2026 12:22
Copy link
Member

@RemiBonnet RemiBonnet left a comment

Choose a reason for hiding this comment

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

Thanks Pierre!

I added few comments and if you can all new files inside console-shared should be in your folder keda same for new files inside the util-services 🙏

@@ -0,0 +1,88 @@
import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios/dist/api'
Copy link
Member

Choose a reason for hiding this comment

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

Could you add an folder keda and add files associated inside ?

  • keda
    - scaled-object-status/scaled-object-status
    - keda-settings/keda-settings
    - autoscaling-payload/autoscaling-payload

@@ -0,0 +1,88 @@
import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios/dist/api'
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios/dist/api'
import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios'

import { isHelmGitSource, isHelmRepositorySource, isJobContainerSource, isJobGitSource } from '@qovery/shared/enums'
import { type ApplicationGeneralData, type JobGeneralData } from '@qovery/shared/interfaces'
import { joinArgsWithQuotes, parseCmd } from '@qovery/shared/util-js'
import { convertAutoscalingResponseToRequest } from '@qovery/shared/util-services'
Copy link
Member

Choose a reason for hiding this comment

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

See my comment below. It would be better to add it directly inside the keda folder.

Keeping a dedicated keda folder makes sense because we’re not sure about the future of this feature, the design may change, so having the file in a single place is safer and easier to maintain

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

extractAndProcessAutoscaling,
} from './autoscaling-payload'

type TestAutoscalingRequest = {
Copy link
Member

Choose a reason for hiding this comment

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

You can't have a type here, should be import from the .ts and not the spec

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

const gpu = Number(resourcesData['gpu'])
const variableImportRequest = prepareVariableImportRequest(variablesData)

// Parse KEDA autoscaling if autoscaling mode is KEDA (or legacy autoscaling_enabled for backward compatibility)
Copy link
Member

Choose a reason for hiding this comment

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

Could you create an util in the folder keda of your domain?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

],
}

const result = convertAutoscalingResponseToRequest(response as any)
Copy link
Member

Choose a reason for hiding this comment

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

You need to remove all as any in your PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

})

it('should use default values for KEDA when not provided', () => {
const formData: any = {
Copy link
Member

Choose a reason for hiding this comment

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

You need to remove all any in your PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

<div className="mb-5">
<label className="mb-3 block text-sm font-medium text-neutral-400">Autoscaling metric</label>
<div className="flex flex-col gap-3">
<InputRadio
Copy link
Member

Choose a reason for hiding this comment

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

This component InputRadio is deprecated you need to use RadioGroup

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

) : null}

{/* Mode NONE: Fixed instances */}
{autoscalingMode === 'NONE' && (
Copy link
Contributor

Choose a reason for hiding this comment

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

@pggb25 Could you use ts-pattern's match method instead ? That way we're sure all cases are covered.

): Record<string, unknown> {
const autoscalingMode = formData['autoscaling_mode'] || 'NONE'

switch (autoscalingMode) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@pggb25 Instead of a switch case, can you please use ts-pattern's match function 🙏

const autoscalingMode = request.autoscaling_mode

// KEDA mode: use scalers
if (autoscalingMode === 'KEDA' && request.scalers?.length) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@pggb25 Here, I'd suggest to use ts-pattern's match function as well, instead of a type-unsafe condition

@pggb25 pggb25 force-pushed the feat/keda-cluster branch 8 times, most recently from c57c64a to 900321c Compare January 21, 2026 17:31
Comment on lines 28 to 30
const isProduction = environmentMode === EnvironmentModeEnum.PRODUCTION
const hasLowMinimum = (minRunningInstances ?? 0) <= 1

Copy link
Contributor

Choose a reason for hiding this comment

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

@pggb25 These variables are not used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@pggb25 pggb25 force-pushed the feat/keda-cluster branch from 900321c to 5dbde4f Compare January 22, 2026 11:03
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.

4 participants