AdminObjectView.fields (and the analogous flexible-field maps on PublicView and the ObjectCreateRequest/set_fields request body) are annotated on the Rust side with #[schema(value_type = Object)]. utoipa emits that as a bare {"type":"object"} with no additionalProperties, which openapi-typescript narrows to Record<string, never> — i.e. the generated TS type says the object can have no keys.
This surfaced while building the frontend SPA (milestone 1): the object-detail view must read flexible field values out of fields, but the generated type makes that impossible without a cast. The interim workaround in the web client is Object.entries(object.fields as Record<string, unknown>) in web/src/objects/object-detail.tsx, plus test fixtures that return fields as plain object literals.
What to do
Annotate the flexible-field maps so the OpenAPI document describes an open string→any map (additionalProperties present), so openapi-typescript generates { [key: string]: unknown } / Record<string, unknown> instead of Record<string, never>. Likely options in utoipa: use #[schema(value_type = HashMap<String, serde_json::Value>)] (or an equivalent that yields additionalProperties) on the fields field of AdminObjectView, PublicView, and any request DTO carrying a free-form field map. Verify the emitted schema has additionalProperties and regenerate web/src/api/schema.d.ts.
Acceptance
The OpenAPI JSON shows fields as an object with additionalProperties (not an empty closed object).
Regenerated schema.d.ts types fields as an open map; the as Record<string, unknown> cast in object-detail.tsx (and any fixture workarounds) can be removed.
Backend tests stay green.
Source: frontend SPA milestone 1 implementation (the typed client consumes this contract).
## Context
`AdminObjectView.fields` (and the analogous flexible-field maps on `PublicView` and the `ObjectCreateRequest`/`set_fields` request body) are annotated on the Rust side with `#[schema(value_type = Object)]`. utoipa emits that as a bare `{"type":"object"}` with no `additionalProperties`, which **`openapi-typescript` narrows to `Record<string, never>`** — i.e. the generated TS type says the object can have *no* keys.
This surfaced while building the frontend SPA (milestone 1): the object-detail view must read flexible field values out of `fields`, but the generated type makes that impossible without a cast. The interim workaround in the web client is `Object.entries(object.fields as Record<string, unknown>)` in `web/src/objects/object-detail.tsx`, plus test fixtures that return `fields` as plain object literals.
## What to do
Annotate the flexible-field maps so the OpenAPI document describes an **open string→any map** (`additionalProperties` present), so `openapi-typescript` generates `{ [key: string]: unknown }` / `Record<string, unknown>` instead of `Record<string, never>`. Likely options in utoipa: use `#[schema(value_type = HashMap<String, serde_json::Value>)]` (or an equivalent that yields `additionalProperties`) on the `fields` field of `AdminObjectView`, `PublicView`, and any request DTO carrying a free-form field map. Verify the emitted schema has `additionalProperties` and regenerate `web/src/api/schema.d.ts`.
## Acceptance
- The OpenAPI JSON shows `fields` as an object with `additionalProperties` (not an empty closed object).
- Regenerated `schema.d.ts` types `fields` as an open map; the `as Record<string, unknown>` cast in `object-detail.tsx` (and any fixture workarounds) can be removed.
- Backend tests stay green.
_Source: frontend SPA milestone 1 implementation (the typed client consumes this contract)._
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
AdminObjectView.fields(and the analogous flexible-field maps onPublicViewand theObjectCreateRequest/set_fieldsrequest body) are annotated on the Rust side with#[schema(value_type = Object)]. utoipa emits that as a bare{"type":"object"}with noadditionalProperties, whichopenapi-typescriptnarrows toRecord<string, never>— i.e. the generated TS type says the object can have no keys.This surfaced while building the frontend SPA (milestone 1): the object-detail view must read flexible field values out of
fields, but the generated type makes that impossible without a cast. The interim workaround in the web client isObject.entries(object.fields as Record<string, unknown>)inweb/src/objects/object-detail.tsx, plus test fixtures that returnfieldsas plain object literals.What to do
Annotate the flexible-field maps so the OpenAPI document describes an open string→any map (
additionalPropertiespresent), soopenapi-typescriptgenerates{ [key: string]: unknown }/Record<string, unknown>instead ofRecord<string, never>. Likely options in utoipa: use#[schema(value_type = HashMap<String, serde_json::Value>)](or an equivalent that yieldsadditionalProperties) on thefieldsfield ofAdminObjectView,PublicView, and any request DTO carrying a free-form field map. Verify the emitted schema hasadditionalPropertiesand regenerateweb/src/api/schema.d.ts.Acceptance
fieldsas an object withadditionalProperties(not an empty closed object).schema.d.tstypesfieldsas an open map; theas Record<string, unknown>cast inobject-detail.tsx(and any fixture workarounds) can be removed.Source: frontend SPA milestone 1 implementation (the typed client consumes this contract).