Skip to content

feature(crr): add wizard shell and Configure step with source/destination/replication sections#1243

Merged
bert-e merged 4 commits into
development/4from
feature/ARTESCA-16787-crr-wizard-shell
Jul 21, 2026
Merged

feature(crr): add wizard shell and Configure step with source/destination/replication sections#1243
bert-e merged 4 commits into
development/4from
feature/ARTESCA-16787-crr-wizard-shell

Conversation

@hervedombya

@hervedombya hervedombya commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Lands the CRR Provisioning Wizard's shell and its first step. Users open it from a Start CRR Configuration button on the Locations page (only visible when the CRR_CONFIGURATOR feature flag is enabled) and are presented with a single Configure page grouped into three sections: Source (create or reuse an account on the source cluster), Destination Connection (network mode, URL or base domain + S3 endpoint, admin credentials, PEM certificate, destination account name), and Replication (an optional replication rule with source bucket, target bucket and prefix). A Check Connection button inside the Destination section validates the destination on demand and shows a success or error toast tied to the ARTESCA problem code. Continue silently re-verifies unless the last verify already covered the exact same connection values, and blocks progression with an error toast if that verify fails; a successful advance is transparent, as expected in a wizard flow. Apply actions and Summary land as placeholders and are filled in by the follow-up brick.

Under the hood, the Configure step is composed of three small section components that share form state via FormProvider, wrapping a strict Joi schema with conditional branches on the connection mode and the replication toggle. The PEM certificate input is a reusable CertificateSection copied from identity-ui's identity-provider form (drag-and-drop or paste) — long-term this belongs in @scality/core-ui so both apps share it.

Deviation from the plan: F5 was originally scoped to just a Configure destination step; scope was widened during review to also cover the Source and Replication sections and the Locations-page entry point.

Next: the Apply actions step, which streams the destination-side setup chain and reports its progress.

screenshots :

Screenshot 2026-07-20 at 16 43 06 (2) Screenshot 2026-07-20 at 16 43 24 (2)

@bert-e

bert-e commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Hello hervedombya,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request TBA
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e

bert-e commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

Comment thread src/react/locations/CRRSetupWizard/CRRSetupWizard.test.tsx Outdated
@claude

claude Bot commented Jul 17, 2026

Copy link
Copy Markdown

LGTM — clean scaffold. One minor test hygiene nit:

- CRRSetupWizard.test.tsx:21: document.getElementById for the password input bypasses RTL's accessibility queries. Use screen.getByLabelText(/Admin password/i) to match the project pattern.

Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from e96b205 to 31af7cd Compare July 20, 2026 08:40
@bert-e

bert-e commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 31af7cd to c719e6d Compare July 20, 2026 08:42
@bert-e

bert-e commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

Comment thread src/react/locations/CRRSetupWizard/steps/ConfigureDestinationStep.tsx Outdated
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • Verify mutation state (success/error banner) is not cleared when the user switches between management-network and data-network modes, leaving a stale "Destination verified" or error banner visible for the wrong mode
    - Call verify.reset() in each radio's onChange callback

    Review by Claude Code

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

LGTM

Clean, well-structured PR. The wizard shell and Configure destination step follow the same Stepper pattern as ISVSteps, the Joi schema with conditional validation is properly set up, the discriminated-union handling in toBody and the success banner is correct, and the feature-flag gating is consistent with other flags in the codebase. API client, types, and test coverage for both happy and error paths look solid.

Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from c719e6d to 37a8801 Compare July 20, 2026 08:50
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

LGTM

Well-structured scaffold — feature flag gating is correct, the form validation and error handling in ConfigureDestinationStep are solid, and the API client layer (ServiceError, problem code mapping) is thorough. Tests cover both the happy path and the error path meaningfully. No bugs, security issues, or breaking changes found.

Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 37a8801 to 9e5b6b5 Compare July 20, 2026 08:58
Comment thread src/react/locations/CRRSetupWizard/steps/ConfigureDestinationStep.tsx Outdated
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • Stale verify banner persists when the user switches between management-network and data-network modes after a verify attempt. The mutation state should be reset on mode change.
    • Call verify.reset() in each radio button's onChange handler in ConfigureDestinationStep.tsx.

Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 9e5b6b5 to 7b4ef55 Compare July 20, 2026 10:10
@hervedombya hervedombya changed the title feature(crr): add wizard shell with Configure destination step feature(crr): add wizard shell and Configure step with source/destination/replication sections Jul 20, 2026
setValue(name, '', { shouldValidate: true, shouldDirty: true });
return;
}
const reader = new FileReader();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

reader.onerror is not handled. If the dropped file cannot be read (binary, permission error, etc.), the user gets no feedback — the certificate field silently stays unchanged.

— Claude Code


export const DestinationConnectionSection = ({ isCheckingConnection, onCheckConnection }: Props) => {
const {
control,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Typo: "Connexion" should be "Connection" — the rest of the UI is in English.

— Claude Code

}
};

const onContinue = handleSubmit(async (values) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

onCheckConnection calls getValues() without triggering form validation first. Unlike onContinue (which is gated by handleSubmit), this sends the request even when required destination fields are empty or invalid, producing confusing server errors instead of form-level validation messages. Consider guarding with trigger() or at least checking isValid before firing.

— Claude Code

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • Typo: "Connexion" label should be "Connection" (DestinationConnectionSection.tsx:14)
    - onCheckConnection bypasses form validation — can fire the verify request with empty/invalid fields, producing confusing server errors instead of inline validation messages (ConfigureStep.tsx:77)
    - FileReader.onerror unhandled in CertificateSection — a dropped file that cannot be read is silently ignored (CertificateSection.tsx:41)

    Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 7b4ef55 to e0f773f Compare July 20, 2026 10:19
});
});

const onCheckConnection = async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unlike the Continue button which gates on !isValid, Check Connection has no guard — clicking it with empty fields sends blank credentials to the verify endpoint. Consider either disabling the button when destination fields are incomplete, or calling trigger() on the relevant fields before sending the request.

— Claude Code

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • DestinationConnectionSection.tsx:25 — Label "Connexion" is French; should be "Connection".
    - Apply the inline suggestion to fix the typo.
    - ConfigureStep.tsx:67 — Check Connection sends the verify request without validating the form first. The Continue button is gated on !isValid, but Check Connection is always enabled.
    - Disable the button when destination fields are incomplete, or call trigger() before sending.

    Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch 2 times, most recently from 9238fed to b4e9889 Compare July 20, 2026 10:33
const reader = new FileReader();
reader.onload = () => {
setValue(name, reader.result as string, { shouldValidate: true, shouldDirty: true });
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

reader.onerror is never set — if the FileReader fails (e.g. the browser cannot read the dropped file), the certificate field stays empty with no feedback to the user. Add an onerror handler that clears the field and shows a validation error.

— Claude Code

Comment thread src/react/ui-elements/CertificateSection.tsx Outdated
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • Hardcoded color: white in CertificateSection breaks light themes — use theme.textPrimary like the rest of the codebase
    - No FileReader.onerror handler in CertificateSection — if reading a dropped file fails the user gets no feedback
    - Empty <p /> in DestinationConnectionSection used for spacing — semantically wrong and an accessibility issue for screen readers
    - onCheckConnection in ConfigureStep bypasses form validation — can fire verify requests with empty fields, showing confusing server errors instead of validation messages

    Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from a8eb3cb to 4bfeebb Compare July 20, 2026 12:16
Comment thread src/react/locations/CRRSetupWizard/steps/ConfigureStep/ConfigureStep.tsx Outdated
Comment thread src/react/locations/CRRSetupWizard/steps/ConfigureStep/schema.ts
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • onCheckConnection calls trigger() with no arguments, validating the entire form. The Check Connection button sits in section 2 of 4, so destination account name and replication fields below it are still empty — trigger() returns false and the click silently does nothing (errors are hidden behind touchedFields guards).
    - Pass only connection-relevant field names: trigger(['connectionMode', 'url', 'baseDomain', 's3Endpoint', 'username', 'password', 'certificate'])

    - managementUrlPattern accepts invalid IP octets (e.g. 999.0.0.1) because it uses digit-count matching instead of range validation.
    - Either tighten the regex to enforce 0-255 per octet, or accept the current trade-off (backend rejects, but the user-facing error is less helpful).

    Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 4bfeebb to 6ffc5b1 Compare July 20, 2026 12:24
Comment thread src/react/locations/CRRSetupWizard/steps/ConfigureStep/SourceSection.tsx Outdated
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • SourceSection: accountName form value persists when switching between create/existing modes, leading to stale data in the input or select control
    - Reset accountName to '' via setValue in the accountNameType radio onChange handler

    Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 6ffc5b1 to 27b798b Compare July 20, 2026 12:32
Comment thread src/react/ui-elements/CertificateSection.tsx
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • CertificateSection (src/react/ui-elements/CertificateSection.tsx) does not display validation errors — unlike every other field in the form, certificate validation failures are silent, leaving the user with a disabled Continue button and no feedback
    - Read formState.errors[name] from useFormContext() and render the error message below the TextArea, or wrap the content in a FormGroup with an error prop

    Review by Claude Code

@hervedombya
hervedombya force-pushed the feature/ARTESCA-16787-crr-wizard-shell branch from 27b798b to 69956ff Compare July 20, 2026 12:40
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

LGTM

Reviewed the wizard shell, all five ConfigureStep section components, the Joi schema with conditional branches, the custom RHF resolver, the verify flow (including the lastVerifiedRef skip-reverification optimisation), the reusable CertificateSection, the feature-flagged route and sidebar registration, and the three MSW-based tests. No issues found — types are correct, hooks follow rules-of-hooks, accessibility labels are in place, credentials are handled safely (password input + bearer-token auth), the conditional schema branches match the conditional UI, and test assertions target user-visible behaviour.

Review by Claude Code

.required()
.messages({ 'string.pattern.base': 'Paste a PEM-encoded certificate' }),

destinationAccountName: Joi.string().min(1).required(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can use accountNameValidationSchema in AccountCreate.tsx

lastVerifiedRef.current = JSON.stringify(body);
};

const onCheckConnection = async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When click "Check Connection" on an empty form silently does nothing.

// biome-ignore-start lint/suspicious/noThenProperty: `then` is Joi's conditional schema branch, not a promise-like method
export const configureSchema = Joi.object<ConfigureFormValues>({
accountNameType: Joi.string().valid('create', 'existing').required(),
accountName: Joi.string().min(1).required(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

accountNameValidationSchema is already imported but only applied to destinationAccountName. When accountNameType is create, the source account name passes with a single character or characters outside [\w+=,.@ -] that the API will reject. Add a conditional branch so new account names get the same validation:

```suggestion
accountName: Joi.when('accountNameType', {
is: 'create',
then: accountNameValidationSchema,
otherwise: Joi.string().min(1).required(),
}),

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
  • Source accountName validation is weaker than destination: accepts single-char names and characters outside [\w+=,.@ -] when creating a new account, which the API will reject. Apply accountNameValidationSchema conditionally when accountNameType === 'create'.
    - Use Joi.when('accountNameType', { is: 'create', then: accountNameValidationSchema, otherwise: Joi.string().min(1).required() }) in schema.ts:57.

    Review by Claude Code

/>
</Stack>
{errorMessage && <ErrorText>{errorMessage}</ErrorText>}
</CertificateContainer>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The ErrorText is not programmatically associated with the TextArea — screen readers will not announce validation errors when the field is focused. The other form fields go through FormGroup which handles this, but since CertificateSection renders its own error display, it needs its own aria-describedby wiring. Add aria-describedby={errorMessage ? \${name}-error` : undefined}to the TextArea andid={`${name}-error`}` to ErrorText.

— Claude Code

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Clean PR — well-structured wizard with proper conditional Joi validation, verify caching, and good integration test coverage. One minor accessibility issue:

- CertificateSection error message is not programmatically linked to the TextArea via aria-describedby, so screen readers won't announce validation errors
- Add aria-describedby to the TextArea and an id to the ErrorText span

Review by Claude Code

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

LGTM

Clean wizard implementation with solid form architecture — conditional Joi schema, resolver-based validation, and proper feature-flag gating. The verify-caching via lastVerifiedRef is a nice touch to avoid redundant round-trips on Continue. Tests cover the key user-facing flows (success toast, ARTESCA problem-code mapping, silent-verify failure).

Review by Claude Code

@ZiyangLinScality ZiyangLinScality left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@hervedombya

Copy link
Copy Markdown
Contributor Author

/approve

@bert-e

bert-e commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

I have successfully merged the changeset of this pull request
into targetted development branches:

  • ✔️ development/4

The following branches have NOT changed:

  • development/1.4
  • development/1.5
  • development/1.6
  • development/2.0
  • development/2.1
  • development/2.2
  • development/3.0
  • development/3.1
  • development/3.2
  • development/4.0
  • development/4.1
  • development/4.2

Please check the status of the associated issue ARTESCA-16787.

Goodbye hervedombya.

The following options are set: approve

@bert-e
bert-e merged commit eb18919 into development/4 Jul 21, 2026
10 checks passed
@bert-e
bert-e deleted the feature/ARTESCA-16787-crr-wizard-shell branch July 21, 2026 08:24
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.

3 participants