feat(ENG-823): setup and config field validation - #183
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds client-side validation support for connector setup/config fields in the integration picker, including Falcon-style validation (format/pattern) while preserving legacy (v2) connector validation behavior. It also adds a small CI-style guard to keep a local copy of format regexes aligned with the canonical @stackone/core accept/reject vectors.
Changes:
- Extend
ConnectorConfigField.validationto support both legacy and Falcon validation contracts (includingformat-based validation). - Add a local
FORMAT_PATTERNSregistry and rule-resolution helpers to apply validations in the Zod schema builder. - Add a
npm testscript that runs a vector-check script to prevent regex drift.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/modules/integration-picker/utils/zodSchema.ts | Introduces format/pattern validation resolution and applies the resolved regex rule to Zod field schemas. |
| src/modules/integration-picker/types.ts | Adds typed validation contracts for legacy vs Falcon connectors and updates ConnectorConfigField.validation. |
| scripts/check-format-vectors.ts | Adds a script to validate the local format regex registry against known accept/reject vectors. |
| package.json | Updates npm test to run the new vector-check script via tsx. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d920972 to
f8ac050
Compare
StuBehan
left a comment
There was a problem hiding this comment.
Reviewed against RFC 2026-037 (step 7). The step-7 scope itself looks right: the discriminated union matches the RFC's branch shapes, the two resolvers are properly independent, the Falcon fallback-message order matches the spec table exactly, and I verified the legacy path is behaviour-preserving — the "No V2 regression" AC holds. I also diffed FORMAT_PATTERNS, the vectors, and FormatName against connect@packages/core/src/connector/ and all three copies are byte-faithful, so the D3 copy is correct as of today.
Verified locally on a clean install of the PR head: npm run build, npm run lint, npm test, npx biome check scripts/, and tsc -p tsconfig.json all pass.
Four things I'd want resolved before merge:
-
D3's CI guard doesn't actually run. The RFC says three separate times that a drifted copy "fails that repo's CI" via the hub's
npm test, and both new comment blocks repeat it. But.github/workflows/node-ci.ymlrunsnpm ci→npm run build→npm run lintand nevernpm test. The check works — it's just never executed. One line in the workflow. -
The guard also can't catch the drift it exists for. Picking up @copilot's point on the script: the hub's vector table is a local copy iterated by key, so a format added to core with no corresponding hub update produces no failure here. That matters more than it looks, because the fall-through in
resolveFalconRuleis silent — an unrecognisedformatyields no rule at all, so a field the author declared as validated renders completely unvalidated. Confirmed:format: 'hostname'accepts"literally anything". D3 notes this mechanism exists precisely because "the copies had genuinely drifted three ways… while every stale vector copy still passed CI" — this is that hole again. -
Saved secrets will block reconnect as soon as a connector uses this. The RFC's risks table says "Pre-existing accounts not re-validated — existing accounts unaffected. Validation runs only as the user types." That doesn't hold on this surface: secret fields are pre-filled with the redacted sentinel, and RHF computes
isValideagerly fromdefaultValues, so validation runs before the user touches anything. Details inline — I think this is an RFC assumption that needs correcting, not just a code fix. -
The step-9 telemetry probably shouldn't be in this PR. As implemented it can't satisfy step 9 (no connector identifier, dedupe doesn't hold, no collector), and the RFC's rollout ordering has 9 trailing 1–8. Splitting it keeps step 7 shippable now — the frontends have to be deployed before step 8 authors anything.
Nits: branch says eng-821, title and commit say ENG-823. PR body is empty — worth linking the RFC and noting this is step 7. The RFC also describes this surface as mode: 'onChange' twice while it's actually onTouched — your comment has it right, so the RFC is the stale one.
StuBehan
left a comment
There was a problem hiding this comment.
Switching my earlier review to request-changes to gate the merge — full detail is already in the threads, nothing new here.
The two I'd want fixed first are the saved-secret reconnect blocker and the per-keystroke telemetry event. Neither breaks anything on merge, since no connector authors setup/config validation: yet — but the RFC's rollout ordering has all three frontends deployed before step 8 authors any, so there's no natural forcing function to come back to them. Easier to fix now than to find it live behind a customer's embedded hub.
Happy to be talked out of the telemetry one specifically if you'd rather split step 9 out and land step 7 as-is — that resolves it too.
…etup-and-config-field-validation
953ff37 to
56aa5c4
Compare
|
Thanks @StuBehan — addressed the threads:
Added tests for the secret short-circuit, unknown-format fail-open, uncompilable-pattern degrade, and widened datetime. Ready for another pass 🙏 |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
No description provided.