core: type platform api key timestamps
This commit is contained in:
@@ -84,8 +84,10 @@ pub struct PlatformApiKey {
|
||||
pub prefix: String,
|
||||
pub scopes: Vec<PlatformApiKeyScope>,
|
||||
pub status: PlatformApiKeyStatus,
|
||||
pub created_at: String,
|
||||
pub last_used_at: Option<String>,
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub created_at: OffsetDateTime,
|
||||
#[serde(with = "time::serde::rfc3339::option")]
|
||||
pub last_used_at: Option<OffsetDateTime>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -93,8 +95,8 @@ mod tests {
|
||||
use serde_json::json;
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
|
||||
use super::{User, UserStatus};
|
||||
use crate::ids::UserId;
|
||||
use super::{PlatformApiKey, PlatformApiKeyScope, PlatformApiKeyStatus, User, UserStatus};
|
||||
use crate::ids::{PlatformApiKeyId, UserId, WorkspaceId};
|
||||
|
||||
#[test]
|
||||
fn user_serializes_created_at_as_rfc3339() {
|
||||
@@ -127,4 +129,23 @@ mod tests {
|
||||
OffsetDateTime::parse("2026-03-25T12:00:00Z", &Rfc3339).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn platform_api_key_serializes_timestamps_as_rfc3339() {
|
||||
let api_key = PlatformApiKey {
|
||||
id: PlatformApiKeyId::new("pk_01"),
|
||||
workspace_id: WorkspaceId::new("ws_01"),
|
||||
name: "Primary".to_owned(),
|
||||
prefix: "crk_live".to_owned(),
|
||||
scopes: vec![PlatformApiKeyScope::Read, PlatformApiKeyScope::Write],
|
||||
status: PlatformApiKeyStatus::Active,
|
||||
created_at: OffsetDateTime::parse("2026-03-25T12:01:00Z", &Rfc3339).unwrap(),
|
||||
last_used_at: Some(OffsetDateTime::parse("2026-03-25T12:05:00Z", &Rfc3339).unwrap()),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(&api_key).unwrap();
|
||||
|
||||
assert_eq!(value["created_at"], json!("2026-03-25T12:01:00Z"));
|
||||
assert_eq!(value["last_used_at"], json!("2026-03-25T12:05:00Z"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ impl PostgresRegistry {
|
||||
prefix,
|
||||
scopes_json,
|
||||
status,
|
||||
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as \"created_at!\",
|
||||
to_char(last_used_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as last_used_at
|
||||
created_at as \"created_at!: time::OffsetDateTime\",
|
||||
last_used_at as \"last_used_at: time::OffsetDateTime\"
|
||||
from platform_api_keys
|
||||
where workspace_id = $1
|
||||
order by created_at desc",
|
||||
@@ -54,8 +54,8 @@ impl PostgresRegistry {
|
||||
k.prefix,
|
||||
k.scopes_json,
|
||||
k.status,
|
||||
to_char(k.created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as \"created_at!\",
|
||||
to_char(k.last_used_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as last_used_at
|
||||
k.created_at as \"created_at!: time::OffsetDateTime\",
|
||||
k.last_used_at as \"last_used_at: time::OffsetDateTime\"
|
||||
from platform_api_keys k
|
||||
join workspaces w on w.id = k.workspace_id
|
||||
where w.slug = $1
|
||||
@@ -112,8 +112,8 @@ impl PostgresRegistry {
|
||||
.bind(request.secret_hash)
|
||||
.bind(Json(serialize_json_value(&request.api_key.scopes)?))
|
||||
.bind(serialize_enum_text(&request.api_key.status, "status")?)
|
||||
.bind(&request.api_key.created_at)
|
||||
.bind(request.api_key.last_used_at.as_deref())
|
||||
.bind(request.api_key.created_at)
|
||||
.bind(request.api_key.last_used_at)
|
||||
.bind(Option::<&str>::None)
|
||||
.execute(&self.pool)
|
||||
.await;
|
||||
@@ -133,7 +133,7 @@ impl PostgresRegistry {
|
||||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
key_id: &PlatformApiKeyId,
|
||||
revoked_at: &str,
|
||||
revoked_at: &time::OffsetDateTime,
|
||||
) -> Result<(), RegistryError> {
|
||||
let result = sqlx::query(
|
||||
"update platform_api_keys
|
||||
@@ -185,7 +185,7 @@ impl PostgresRegistry {
|
||||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
key_id: &PlatformApiKeyId,
|
||||
used_at: &str,
|
||||
used_at: &time::OffsetDateTime,
|
||||
) -> Result<(), RegistryError> {
|
||||
let result = sqlx::query(
|
||||
"update platform_api_keys
|
||||
|
||||
@@ -1676,7 +1676,7 @@ mod tests {
|
||||
prefix: "crk_live".to_owned(),
|
||||
scopes: vec![PlatformApiKeyScope::Read, PlatformApiKeyScope::Write],
|
||||
status: PlatformApiKeyStatus::Active,
|
||||
created_at: "2026-03-25T12:01:00Z".to_owned(),
|
||||
created_at: timestamp("2026-03-25T12:01:00Z"),
|
||||
last_used_at: None,
|
||||
};
|
||||
let secret_hash = "secret_hash_01";
|
||||
@@ -1717,7 +1717,7 @@ mod tests {
|
||||
.touch_platform_api_key(
|
||||
&workspace.id,
|
||||
&PlatformApiKeyId::new("key_01"),
|
||||
"2026-03-25T12:05:00Z",
|
||||
×tamp("2026-03-25T12:05:00Z"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -1727,8 +1727,8 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
touched[0].api_key.last_used_at.as_deref(),
|
||||
Some("2026-03-25T12:05:00Z")
|
||||
touched[0].api_key.last_used_at,
|
||||
Some(timestamp("2026-03-25T12:05:00Z"))
|
||||
);
|
||||
|
||||
database.cleanup().await;
|
||||
|
||||
Reference in New Issue
Block a user