Skip to content

feat(core): add ExtensibleEnum schema and templated model#1006

Draft
SnowboardTechie wants to merge 1 commit into
HOLD-core-v0.4.0from
961-extensible-enum
Draft

feat(core): add ExtensibleEnum schema and templated model#1006
SnowboardTechie wants to merge 1 commit into
HOLD-core-v0.4.0from
961-extensible-enum

Conversation

@SnowboardTechie

Copy link
Copy Markdown
Collaborator

Summary

Changes proposed

  • Adds a Fields.ExtensibleEnum base model and Fields.ExtensibleEnumT<T> template to the core library, formalizing the extensible enum pattern (value + optional customValue + description) that our status-style fields all repeat by hand.
  • Rewrites the five existing extensible enum fields — OppStatus, AppStatus, ApplicantType, FormResponseStatus, CompetitionStatus — as one-line instantiations of the template, so the pattern has a single source of truth.
  • Adds the custom option to FormResponseStatusOptions at v0.4.0 — its docstring already listed custom, but the enum was missing it (the only one of the five that was).
  • Adds a docs page for the new field at /protocol/fields/extensible-enum/, regenerates the committed schema artifacts, and re-pins the TypeSpec line references in the affected model pages.

Context for reviewers

Approach matches CommonBenefits (extensible-enum.tsp): an untyped ExtensibleEnum plus a typed ExtensibleEnumT<T>, consumed as model AppStatus is Fields.ExtensibleEnumT<AppStatusOptions>;. One deliberate wording difference: CommonBenefits' template property docs say "typed to T", which leaks the template parameter into every emitted consumer schema — I reworded the property docs to be reader-facing instead.

Breaking-change review (per the issue's acceptance criteria):

  • No structural schema changes. I diffed the full emitted output (JSON Schema + OpenAPI 0.1.0–0.4.0) against the branch point: required, $ref targets, types, and enum membership are all byte-identical, except the intended custom addition, which appears only in the 0.4.0 output (the @added(v0_4) gate works — 0.2.0/0.3.0 emit the enum without it).
  • Property descriptions change in the emitted schemas for the five refactored models — each model's bespoke wording ("The status of the opportunity, from a predefined set of options") is replaced by the template's shared wording ("The selected value, from a predefined set of options"). This is docs-only, but it does alter published-version artifacts, so calling it out explicitly.
  • The TS SDK fuzz suite (Zod vs. emitted JSON schema, 474 tests) passes with zero SDK changes, which is the working proof that validation semantics are unchanged. Python SDK is likewise untouched.

Also fixed in passing: the Examples.Competition.status example set customValue: "custom" while value was open — the custom value only applies when value is custom, so it's dropped.

Verified with: pnpm --filter @common-grants/core run checks && build && typespec, full emitted-schema diff against the branch point, pnpm --filter @common-grants/sdk run build && test:coverage, and a full website build (163 pages, links validated).

Additional information

Defining a new extensible enum field is now:

enum MyStatusOptions {
  active,
  inactive,
  custom,
}

model MyStatus is Fields.ExtensibleEnumT<MyStatusOptions>;

Formalize the extensible enum pattern (value + optional customValue +
description) as a reusable Fields.ExtensibleEnum model and
Fields.ExtensibleEnumT<T> template, mirroring the CommonBenefits protocol.
OppStatus, AppStatus, ApplicantType, FormResponseStatus, and
CompetitionStatus are now one-line instantiations of the template.

Adds the custom option to FormResponseStatusOptions at v0.4.0 (its
docstring already listed it) and drops a stray customValue from the
CompetitionStatus example. Emitted schemas are unchanged apart from
property description wording; published versions 0.1.0-0.3.0 keep their
exact validation shape.
@github-actions github-actions Bot added website Issues related to the website core Issues related to @common-grants/core library typescript Issue or PR related to TypeScript tooling labels Jul 15, 2026
@SnowboardTechie SnowboardTechie added this to the [Core] v0.4.0 release milestone Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Website Preview Deployed!

Preview your changes at: https://cg-pr-1006.billy-daly.workers.dev

This preview will be automatically deleted when the PR is closed.

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

Labels

core Issues related to @common-grants/core library typescript Issue or PR related to TypeScript tooling website Issues related to the website

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant