feat(api): expose object created_at/updated_at in AdminObjectView (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,10 @@ pub(crate) struct AdminObjectView {
|
|||||||
/// Flexible field values (key -> value).
|
/// Flexible field values (key -> value).
|
||||||
#[schema(value_type = std::collections::HashMap<String, serde_json::Value>)]
|
#[schema(value_type = std::collections::HashMap<String, serde_json::Value>)]
|
||||||
pub fields: serde_json::Value,
|
pub fields: serde_json::Value,
|
||||||
|
/// RFC3339 UTC timestamp.
|
||||||
|
pub created_at: String,
|
||||||
|
/// RFC3339 UTC timestamp.
|
||||||
|
pub updated_at: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AdminObjectView {
|
impl AdminObjectView {
|
||||||
@@ -61,6 +65,14 @@ impl AdminObjectView {
|
|||||||
recording_date: o.recording_date.map(format_date),
|
recording_date: o.recording_date.map(format_date),
|
||||||
visibility: o.visibility.as_str().to_owned(),
|
visibility: o.visibility.as_str().to_owned(),
|
||||||
fields: o.fields.clone(),
|
fields: o.fields.clone(),
|
||||||
|
created_at: o
|
||||||
|
.created_at
|
||||||
|
.format(&time::format_description::well_known::Rfc3339)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
updated_at: o
|
||||||
|
.updated_at
|
||||||
|
.format(&time::format_description::well_known::Rfc3339)
|
||||||
|
.unwrap_or_default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -843,6 +843,40 @@ async fn delete_field_definition_referenced_is_409(pool: PgPool) {
|
|||||||
assert_eq!(body["count"], 1);
|
assert_eq!(body["count"], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[sqlx::test(migrations = "../db/migrations")]
|
||||||
|
async fn listed_object_carries_timestamps(pool: PgPool) {
|
||||||
|
migrate_sessions(&db::Db::from_pool(pool.clone()))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
seed_user(&pool, "ed@example.com", "pw-editor-123", Role::Editor).await;
|
||||||
|
|
||||||
|
let app = build_app(state(pool));
|
||||||
|
let cookie = login(&app, "ed@example.com", "pw-editor-123").await;
|
||||||
|
|
||||||
|
let created = send(
|
||||||
|
&app,
|
||||||
|
&cookie,
|
||||||
|
"POST",
|
||||||
|
"/api/admin/objects",
|
||||||
|
Some(r#"{"object_number":"TS-1","object_name":"clock","number_of_objects":1,"visibility":"draft"}"#),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(created.status(), StatusCode::CREATED);
|
||||||
|
|
||||||
|
let list = send(&app, &cookie, "GET", "/api/admin/objects", None).await;
|
||||||
|
assert_eq!(list.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
let body: serde_json::Value =
|
||||||
|
serde_json::from_slice(&list.into_body().collect().await.unwrap().to_bytes()).unwrap();
|
||||||
|
|
||||||
|
let item = &body["items"][0];
|
||||||
|
let created_at = item["created_at"].as_str().unwrap();
|
||||||
|
let updated_at = item["updated_at"].as_str().unwrap();
|
||||||
|
assert!(!created_at.is_empty(), "created_at must be non-empty");
|
||||||
|
assert!(!updated_at.is_empty(), "updated_at must be non-empty");
|
||||||
|
}
|
||||||
|
|
||||||
#[sqlx::test(migrations = "../db/migrations")]
|
#[sqlx::test(migrations = "../db/migrations")]
|
||||||
async fn field_definition_edit_delete_requires_auth(pool: PgPool) {
|
async fn field_definition_edit_delete_requires_auth(pool: PgPool) {
|
||||||
migrate_sessions(&db::Db::from_pool(pool.clone()))
|
migrate_sessions(&db::Db::from_pool(pool.clone()))
|
||||||
|
|||||||
Reference in New Issue
Block a user