feat(sources): add an optional Section field to data sources#2432
feat(sources): add an optional Section field to data sources#2432alex-fedotyev wants to merge 3 commits into
Conversation
Add a `section` field to the shared source schema, persist it on the Mongoose source model, expose it as an input on the source settings form, and document it on the read-only GET /api/v2/sources surface (OpenAPI plus a round-trip test). The field is optional, so sources without one keep today's behavior. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 9446407 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🔴 Tier 4 — CriticalTouches auth, data models, config, tasks, OTel pipeline, ClickHouse, or CI/CD. Why this tier:
Review process: Deep review from a domain expert. Synchronous walkthrough may be required. Stats
|
Greptile SummaryThis PR adds an optional
Confidence Score: 5/5Safe to merge; the change is additive and backward-compatible with no impact on existing sources. The change is purely additive — a new optional field on the base schema, model, and form. Existing sources without a section are unaffected, the external API remains read-only, and the two new integration tests cover the key read paths. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Source Settings Form] -->|section input maxLength=256| B[useForm submit]
B -->|internal write API| C[Mongoose sourceBaseSchema\nsection: String]
C -->|strict: true drops unknown fields\nsection is explicit so it persists| D[(MongoDB)]
D -->|GET /api/v2/sources| E[formatExternalSource]
E -->|SourceSchema.safeParse\nsection: z.string.min1.max256.optional| F[External API response]
F -->|section present if set, absent otherwise| G[API consumer]
Reviews (3): Last reviewed commit: "chore(sources): remove implementation-co..." | Re-trigger Greptile |
E2E Test Results✅ All tests passed • 198 passed • 3 skipped • 1297s
Tests ran across 4 shards in parallel. |
- OpenAPI: drop `nullable: true` from the `section` field on all four
source schemas. The field is optional (string or absent), never
null, so the spec should not advertise null to API consumers.
- Form: add `maxLength={256}` to the Section input so the 256-char
cap from the schema is enforced client-side, not only after a
server round-trip.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
| // Optional, free-text grouping label for a source. Persisted and exposed | ||
| // through the read API; the source selector will group and search by it in | ||
| // a later change. The cap lives on the shared schema so every writer (form, | ||
| // internal API, future migrations) inherits it; sources without a section | ||
| // keep today's behavior. |
There was a problem hiding this comment.
This comment is superfluous and describes the implementation context rather than wider functionality. I would remove it.
There was a problem hiding this comment.
Good catch. Removed in 9446407. The push reset the review, so it will need another approval when you have a moment.
Karl noted the comment on `section` describes implementation context rather than wider functionality. Drop it; the surrounding fields in BaseSourceSchema carry no comments and the field is self-explanatory. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add an optional
sectionlabel to data sources. A source can be tagged with a free-text section from the source settings form; the value is persisted and returned by the read-onlyGET /api/v2/sourcesendpoint. Sources without a section are unchanged.This is the first PR for HDX-4507 (grouping the data source selector by section, with tag-style search). It lands the data model and the read API surface; the selector grouping and search UI follow in later PRs.
Summary
section(optional, max 256 chars) to the sharedBaseSourceSchema, so all five source kinds inherit it.sectionon the Mongoose source model. The base schema runsstrict: true, so an unlisted field is dropped on write; the model needssectionexplicitly.sectionon the four external source schemas in theGET /api/v2/sourcesOpenAPI spec and regenerateopenapi.json.Why
sectionlives onBaseSourceSchemarather than per-kind so every writer (the form, the internal API, any future migration) inherits the same optional field and the same 256-char cap in one place. The external API already re-parses each source throughSourceSchemabefore responding, so oncesectionis on the schema it rides through toGET /api/v2/sourceson its own; the only external-API work needed was documenting it in the OpenAPI spec and regeneratingopenapi.json. The endpoint is read-only (no external write route for sources), sosectionis read-only externally.The field is optional, so existing sources, and any source created without one, keep today's behavior:
sectionis absent from the response, not null.Test plan
make ci-lint(lint, type check, andlint:openapi, which regenerates the spec and confirmsopenapi.jsonis in sync)make ci-unitGET /api/v2/sourceshandler: a source created with a section returns it; a source created without one omits it. Extendspackages/api/src/routers/external-api/__tests__/sources.test.ts(full file is 22/22 green).[ui-states: allow] The Section input is a plain optional text field with no empty/loading/error states.
[viewport: allow] Standard full-width form row, identical layout to the existing Name field.
What's not in this PR (follow-up, HDX-4507)
sectionin the source selector (the selector UI).describeSourceexposure ofsection.