Several enum-valued fields are emitted in the OpenAPI document as bare string, so the generated TypeScript client (web/src/api/schema.d.ts) types them as string rather than a literal union. The frontend then carries as-casts to the real union at each use site:
AdminObjectView.visibility / PublicView.visibility → string. Cast as Visibility in web/src/objects/visibility-badge.tsx, object-detail.tsx, and publish-control.tsx (milestones 1 & 3).
FieldDefinitionView.data_type → string (the frontend switches on it in field-input.tsx).
These are almost certainly annotated #[schema(value_type = String)] (or similar) on the Rust side, which flattens the enum to a string in the schema.
What to do
Where the Rust enum is a fixed, closed set (Visibility = draft/internal/public; FieldType's data_type tag; AuthorityKind = person/organisation/place), let utoipa emit a proper string enum (e.g. derive ToSchema on the enum so the schema lists the allowed values) instead of a bare string. Then regenerate web/src/api/schema.d.ts — the generated types become literal unions and the frontend as Visibility / data_type casts can be removed.
Acceptance
The OpenAPI JSON lists the allowed values for visibility, data_type, and authority kind (string enums).
Regenerated schema.d.ts types them as unions; the frontend casts drop; web typecheck/tests stay green.
Sibling of #24 (free-form fields map typing). Both are "tighten the generated client contract" cleanups.
## Context
Several enum-valued fields are emitted in the OpenAPI document as bare `string`, so the generated TypeScript client (`web/src/api/schema.d.ts`) types them as `string` rather than a literal union. The frontend then carries `as`-casts to the real union at each use site:
- `AdminObjectView.visibility` / `PublicView.visibility` → `string`. Cast `as Visibility` in `web/src/objects/visibility-badge.tsx`, `object-detail.tsx`, and `publish-control.tsx` (milestones 1 & 3).
- `FieldDefinitionView.data_type` → `string` (the frontend switches on it in `field-input.tsx`).
- `AuthorityView.kind` / `FieldDefinitionView.authority_kind` → `string`.
These are almost certainly annotated `#[schema(value_type = String)]` (or similar) on the Rust side, which flattens the enum to a string in the schema.
## What to do
Where the Rust enum is a fixed, closed set (`Visibility` = draft/internal/public; `FieldType`'s data_type tag; `AuthorityKind` = person/organisation/place), let utoipa emit a proper string **enum** (e.g. derive `ToSchema` on the enum so the schema lists the allowed values) instead of a bare `string`. Then regenerate `web/src/api/schema.d.ts` — the generated types become literal unions and the frontend `as Visibility` / `data_type` casts can be removed.
## Acceptance
- The OpenAPI JSON lists the allowed values for `visibility`, `data_type`, and authority `kind` (string enums).
- Regenerated `schema.d.ts` types them as unions; the frontend casts drop; web typecheck/tests stay green.
## References
- Rust DTOs: `crates/api/src/admin_objects.rs`, `admin_authorities.rs`, `public.rs`; `domain::{Visibility, FieldType, AuthorityKind}` (all have `as_str`/`from_db` + serde lowercase).
- Frontend cast sites listed above.
- Sibling of #24 (free-form `fields` map typing). Both are "tighten the generated client contract" cleanups.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
Several enum-valued fields are emitted in the OpenAPI document as bare
string, so the generated TypeScript client (web/src/api/schema.d.ts) types them asstringrather than a literal union. The frontend then carriesas-casts to the real union at each use site:AdminObjectView.visibility/PublicView.visibility→string. Castas Visibilityinweb/src/objects/visibility-badge.tsx,object-detail.tsx, andpublish-control.tsx(milestones 1 & 3).FieldDefinitionView.data_type→string(the frontend switches on it infield-input.tsx).AuthorityView.kind/FieldDefinitionView.authority_kind→string.These are almost certainly annotated
#[schema(value_type = String)](or similar) on the Rust side, which flattens the enum to a string in the schema.What to do
Where the Rust enum is a fixed, closed set (
Visibility= draft/internal/public;FieldType's data_type tag;AuthorityKind= person/organisation/place), let utoipa emit a proper string enum (e.g. deriveToSchemaon the enum so the schema lists the allowed values) instead of a barestring. Then regenerateweb/src/api/schema.d.ts— the generated types become literal unions and the frontendas Visibility/data_typecasts can be removed.Acceptance
visibility,data_type, and authoritykind(string enums).schema.d.tstypes them as unions; the frontend casts drop; web typecheck/tests stay green.References
crates/api/src/admin_objects.rs,admin_authorities.rs,public.rs;domain::{Visibility, FieldType, AuthorityKind}(all haveas_str/from_db+ serde lowercase).fieldsmap typing). Both are "tighten the generated client contract" cleanups.