feat(domain): derive ToSchema on Visibility/AuthorityKind; add DataType enum (#3 Option A)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 20:08:41 +02:00
parent 331a6d7f34
commit d3c33a6c5d
5 changed files with 35 additions and 3 deletions
+1
View File
@@ -9,3 +9,4 @@ uuid.workspace = true
serde.workspace = true
serde_json.workspace = true
time.workspace = true
utoipa.workspace = true
+1 -1
View File
@@ -7,7 +7,7 @@ use crate::{AuthorityId, LocalizedLabel};
/// NOTE: kept in sync by hand with the
/// `CHECK (kind IN ('person', 'organisation', 'place'))` constraint in
/// `crates/db/migrations/0002_vocabularies_authorities.sql` — add a variant in both places.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum AuthorityKind {
Person,
+31
View File
@@ -74,6 +74,23 @@ impl FieldType {
}
}
/// The stored `data_type` discriminant of a field definition — mirrors the strings from
/// [`FieldType::kind_str`]. Exists so the OpenAPI schema can describe `data_type` as a
/// closed string enum (consumed by the typed web client). Keep in sync with `kind_str`.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, utoipa::ToSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum DataType {
Text,
LocalizedText,
Integer,
Date,
Boolean,
Term,
Authority,
}
/// A registered flexible field, with its multilingual display labels.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FieldDefinition {
@@ -152,4 +169,18 @@ mod tests {
);
assert_eq!(FieldType::from_parts("authority", Some(v), None), None);
}
#[test]
fn data_type_serde_matches_kind_str() {
use serde_json::json;
assert_eq!(
serde_json::to_value(DataType::LocalizedText).unwrap(),
json!("localized_text")
);
assert_eq!(serde_json::to_value(DataType::Text).unwrap(), json!("text"));
assert_eq!(
serde_json::to_value(DataType::Authority).unwrap(),
json!("authority")
);
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ mod vocabulary;
pub use audit::{AuditAction, AuditActor, AuditEntry, FieldChange, NewAuditEvent};
pub use authority::{Authority, AuthorityKind, AuthorityRef, NewAuthority};
pub use field_definition::{FieldDefinition, FieldType, NewFieldDefinition};
pub use field_definition::{DataType, FieldDefinition, FieldType, NewFieldDefinition};
pub use id::{AuthorityId, FieldDefinitionId, ObjectId, OrgId, TermId, UserId, VocabularyId};
pub use label::{LocalizedLabel, pick_label};
pub use object::{CatalogueObject, IllegalTransition, ObjectInput, Visibility};
+1 -1
View File
@@ -4,7 +4,7 @@ use time::{Date, OffsetDateTime};
use crate::ObjectId;
/// Publication state of a catalogue record.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default, utoipa::ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum Visibility {
/// Work in progress; not shown anywhere public.