refactor: 抽离 AI pipeline 与调度共享能力逻辑

This commit is contained in:
fawney19
2026-04-10 01:46:14 +08:00
parent b901a6ffc7
commit 5014e2f5fd
255 changed files with 15057 additions and 3115 deletions

View File

@@ -91,7 +91,7 @@ impl AnnouncementReadRepository for InMemoryAnnouncementReadRepository {
.is_pinned
.cmp(&left.is_pinned)
.then_with(|| right.priority.cmp(&left.priority))
.then_with(|| right.created_at_unix_secs.cmp(&left.created_at_unix_secs))
.then_with(|| right.created_at_unix_ms.cmp(&left.created_at_unix_ms))
.then_with(|| left.id.cmp(&right.id))
});

View File

@@ -21,7 +21,7 @@ SELECT
u.username AS author_username,
EXTRACT(EPOCH FROM a.start_time)::bigint AS start_time_unix_secs,
EXTRACT(EPOCH FROM a.end_time)::bigint AS end_time_unix_secs,
EXTRACT(EPOCH FROM a.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM a.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM a.updated_at)::bigint AS updated_at_unix_secs
FROM announcements a
LEFT JOIN users u ON u.id = a.author_id
@@ -42,7 +42,7 @@ SELECT
u.username AS author_username,
EXTRACT(EPOCH FROM a.start_time)::bigint AS start_time_unix_secs,
EXTRACT(EPOCH FROM a.end_time)::bigint AS end_time_unix_secs,
EXTRACT(EPOCH FROM a.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM a.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM a.updated_at)::bigint AS updated_at_unix_secs
FROM announcements a
LEFT JOIN users u ON u.id = a.author_id
@@ -125,7 +125,7 @@ RETURNING
(SELECT username FROM users WHERE id = announcements.author_id) AS author_username,
EXTRACT(EPOCH FROM start_time)::bigint AS start_time_unix_secs,
EXTRACT(EPOCH FROM end_time)::bigint AS end_time_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -154,7 +154,7 @@ RETURNING
(SELECT username FROM users WHERE id = announcements.author_id) AS author_username,
EXTRACT(EPOCH FROM start_time)::bigint AS start_time_unix_secs,
EXTRACT(EPOCH FROM end_time)::bigint AS end_time_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -350,7 +350,7 @@ fn map_announcement_row(row: &PgRow) -> Result<StoredAnnouncement, DataLayerErro
row.try_get("author_username").map_postgres_err()?,
row.try_get("start_time_unix_secs").map_postgres_err()?,
row.try_get("end_time_unix_secs").map_postgres_err()?,
row.try_get("created_at_unix_secs").map_postgres_err()?,
row.try_get("created_at_unix_ms").map_postgres_err()?,
row.try_get("updated_at_unix_secs").map_postgres_err()?,
)
}

View File

@@ -13,7 +13,7 @@ pub struct StoredAnnouncement {
pub author_username: Option<String>,
pub start_time_unix_secs: Option<u64>,
pub end_time_unix_secs: Option<u64>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub updated_at_unix_secs: u64,
}
@@ -31,7 +31,7 @@ impl StoredAnnouncement {
author_username: Option<String>,
start_time_unix_secs: Option<i64>,
end_time_unix_secs: Option<i64>,
created_at_unix_secs: i64,
created_at_unix_ms: i64,
updated_at_unix_secs: i64,
) -> Result<Self, crate::DataLayerError> {
if id.trim().is_empty() {
@@ -71,10 +71,7 @@ impl StoredAnnouncement {
end_time_unix_secs: end_time_unix_secs
.map(|value| parse_timestamp(value, "announcements.end_time"))
.transpose()?,
created_at_unix_secs: parse_timestamp(
created_at_unix_secs,
"announcements.created_at",
)?,
created_at_unix_ms: parse_timestamp(created_at_unix_ms, "announcements.created_at")?,
updated_at_unix_secs: parse_timestamp(
updated_at_unix_secs,
"announcements.updated_at",

View File

@@ -48,7 +48,7 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
left.candidate_index
.cmp(&right.candidate_index)
.then(left.retry_index.cmp(&right.retry_index))
.then(left.created_at_unix_secs.cmp(&right.created_at_unix_secs))
.then(left.created_at_unix_ms.cmp(&right.created_at_unix_ms))
});
Ok(rows)
}
@@ -68,7 +68,7 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
.values()
.cloned()
.collect::<Vec<_>>();
rows.sort_by(|left, right| right.created_at_unix_secs.cmp(&left.created_at_unix_secs));
rows.sort_by(|left, right| right.created_at_unix_ms.cmp(&left.created_at_unix_ms));
rows.truncate(limit);
Ok(rows)
}
@@ -90,7 +90,7 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
.filter(|row| row.provider_id.as_deref() == Some(provider_id))
.cloned()
.collect::<Vec<_>>();
rows.sort_by(|left, right| right.created_at_unix_secs.cmp(&left.created_at_unix_secs));
rows.sort_by(|left, right| right.created_at_unix_ms.cmp(&left.created_at_unix_ms));
rows.truncate(limit);
Ok(rows)
}
@@ -115,7 +115,7 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
row.endpoint_id
.as_ref()
.is_some_and(|endpoint_id| endpoint_ids.contains(endpoint_id))
&& row.created_at_unix_secs >= since_unix_secs
&& row.created_at_unix_ms >= since_unix_secs * 1000
&& matches!(
row.status,
RequestCandidateStatus::Success
@@ -125,7 +125,7 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
})
.cloned()
.collect::<Vec<_>>();
rows.sort_by(|left, right| right.created_at_unix_secs.cmp(&left.created_at_unix_secs));
rows.sort_by(|left, right| right.created_at_unix_ms.cmp(&left.created_at_unix_ms));
rows.truncate(limit);
Ok(rows)
}
@@ -150,7 +150,9 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
let Some(endpoint_id) = row.endpoint_id.as_ref() else {
continue;
};
if !endpoint_ids.contains(endpoint_id) || row.created_at_unix_secs < since_unix_secs {
if !endpoint_ids.contains(endpoint_id)
|| row.created_at_unix_ms < since_unix_secs * 1000
{
continue;
}
if !matches!(
@@ -200,7 +202,7 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
}
let endpoint_ids = endpoint_ids.iter().cloned().collect::<BTreeSet<_>>();
let span = until_unix_secs.saturating_sub(since_unix_secs);
let span_ms = until_unix_secs.saturating_sub(since_unix_secs) * 1000;
let mut buckets = BTreeMap::<(String, u32), PublicHealthTimelineBucket>::new();
for row in self
@@ -213,8 +215,8 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
continue;
};
if !endpoint_ids.contains(endpoint_id)
|| row.created_at_unix_secs < since_unix_secs
|| row.created_at_unix_secs > until_unix_secs
|| row.created_at_unix_ms < since_unix_secs * 1000
|| row.created_at_unix_ms > until_unix_secs * 1000
{
continue;
}
@@ -227,11 +229,13 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
continue;
}
let segment_idx = if span == 0 {
let segment_idx = if span_ms == 0 {
0
} else {
let offset = row.created_at_unix_secs.saturating_sub(since_unix_secs);
let idx = ((offset as u128) * (segments as u128) / (span as u128)) as u32;
let offset = row
.created_at_unix_ms
.saturating_sub(since_unix_secs * 1000);
let idx = ((offset as u128) * (segments as u128) / (span_ms as u128)) as u32;
idx.min(segments.saturating_sub(1))
};
let bucket = buckets
@@ -242,8 +246,8 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
total_count: 0,
success_count: 0,
failed_count: 0,
min_created_at_unix_secs: None,
max_created_at_unix_secs: None,
min_created_at_unix_ms: None,
max_created_at_unix_ms: None,
});
bucket.total_count += 1;
if row.status == RequestCandidateStatus::Success {
@@ -251,17 +255,17 @@ impl RequestCandidateReadRepository for InMemoryRequestCandidateRepository {
} else if row.status == RequestCandidateStatus::Failed {
bucket.failed_count += 1;
}
bucket.min_created_at_unix_secs = Some(
bucket.min_created_at_unix_ms = Some(
bucket
.min_created_at_unix_secs
.map(|value| value.min(row.created_at_unix_secs))
.unwrap_or(row.created_at_unix_secs),
.min_created_at_unix_ms
.map(|value| value.min(row.created_at_unix_ms))
.unwrap_or(row.created_at_unix_ms),
);
bucket.max_created_at_unix_secs = Some(
bucket.max_created_at_unix_ms = Some(
bucket
.max_created_at_unix_secs
.map(|value| value.max(row.created_at_unix_secs))
.unwrap_or(row.created_at_unix_secs),
.max_created_at_unix_ms
.map(|value| value.max(row.created_at_unix_ms))
.unwrap_or(row.created_at_unix_ms),
);
}
@@ -290,12 +294,12 @@ impl RequestCandidateWriteRepository for InMemoryRequestCandidateRepository {
})
.cloned();
let created_at_unix_secs = existing
let created_at_unix_ms = existing
.as_ref()
.map(|row| row.created_at_unix_secs)
.or(candidate.created_at_unix_secs)
.or(candidate.started_at_unix_secs)
.or(candidate.finished_at_unix_secs)
.map(|row| row.created_at_unix_ms)
.or(candidate.created_at_unix_ms)
.or(candidate.started_at_unix_ms)
.or(candidate.finished_at_unix_ms)
.unwrap_or_default();
let stored = StoredRequestCandidate {
@@ -357,13 +361,13 @@ impl RequestCandidateWriteRepository for InMemoryRequestCandidateRepository {
.as_ref()
.and_then(|row| row.required_capabilities.clone())
}),
created_at_unix_secs,
started_at_unix_secs: candidate
.started_at_unix_secs
.or_else(|| existing.as_ref().and_then(|row| row.started_at_unix_secs)),
finished_at_unix_secs: candidate
.finished_at_unix_secs
.or_else(|| existing.as_ref().and_then(|row| row.finished_at_unix_secs)),
created_at_unix_ms,
started_at_unix_ms: candidate
.started_at_unix_ms
.or_else(|| existing.as_ref().and_then(|row| row.started_at_unix_ms)),
finished_at_unix_ms: candidate
.finished_at_unix_ms
.or_else(|| existing.as_ref().and_then(|row| row.finished_at_unix_ms)),
};
by_id.insert(stored.id.clone(), stored.clone());
@@ -385,8 +389,8 @@ impl RequestCandidateWriteRepository for InMemoryRequestCandidateRepository {
.expect("request candidate repository lock");
let mut ids = by_id
.values()
.filter(|row| row.created_at_unix_secs < created_before_unix_secs)
.map(|row| (row.created_at_unix_secs, row.id.clone()))
.filter(|row| row.created_at_unix_ms < created_before_unix_secs * 1000)
.map(|row| (row.created_at_unix_ms, row.id.clone()))
.collect::<Vec<_>>();
ids.sort();
@@ -411,7 +415,7 @@ mod tests {
fn sample_candidate(
id: &str,
request_id: &str,
created_at_unix_secs: i64,
created_at_unix_ms: i64,
) -> StoredRequestCandidate {
StoredRequestCandidate::new(
id.to_string(),
@@ -435,9 +439,9 @@ mod tests {
Some(1),
None,
None,
created_at_unix_secs,
Some(created_at_unix_secs),
Some(created_at_unix_secs + 1),
created_at_unix_ms,
Some(created_at_unix_ms),
Some(created_at_unix_ms + 1),
)
.expect("candidate should build")
}
@@ -480,8 +484,8 @@ mod tests {
#[tokio::test]
async fn aggregates_finalized_health_data_by_endpoint_ids() {
let repository = InMemoryRequestCandidateRepository::seed(vec![
sample_candidate("cand-1", "req-1", 100),
sample_candidate("cand-2", "req-2", 200),
sample_candidate("cand-1", "req-1", 100_000),
sample_candidate("cand-2", "req-2", 200_000),
]);
let counts = repository
@@ -538,9 +542,9 @@ mod tests {
concurrent_requests: None,
extra_data: None,
required_capabilities: None,
created_at_unix_secs: Some(100),
started_at_unix_secs: None,
finished_at_unix_secs: None,
created_at_unix_ms: Some(100),
started_at_unix_ms: None,
finished_at_unix_ms: None,
})
.await
.expect("create should succeed");
@@ -570,9 +574,9 @@ mod tests {
concurrent_requests: Some(2),
extra_data: None,
required_capabilities: None,
created_at_unix_secs: None,
started_at_unix_secs: Some(101),
finished_at_unix_secs: Some(102),
created_at_unix_ms: None,
started_at_unix_ms: Some(101),
finished_at_unix_ms: Some(102),
})
.await
.expect("update should succeed");
@@ -580,7 +584,7 @@ mod tests {
assert_eq!(updated.status, RequestCandidateStatus::Success);
assert_eq!(updated.status_code, Some(200));
assert_eq!(updated.latency_ms, Some(25));
assert_eq!(updated.started_at_unix_secs, Some(101));
assert_eq!(updated.started_at_unix_ms, Some(101));
}
#[tokio::test]

View File

@@ -34,9 +34,9 @@ SELECT
concurrent_requests,
extra_data,
required_capabilities,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM started_at) AS BIGINT) AS started_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finished_at) AS BIGINT) AS finished_at_unix_secs
CAST(EXTRACT(EPOCH FROM created_at) * 1000 AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM started_at) * 1000 AS BIGINT) AS started_at_unix_ms,
CAST(EXTRACT(EPOCH FROM finished_at) * 1000 AS BIGINT) AS finished_at_unix_ms
FROM request_candidates
WHERE request_id = $1
ORDER BY candidate_index ASC, retry_index ASC, created_at ASC
@@ -65,9 +65,9 @@ SELECT
concurrent_requests,
extra_data,
required_capabilities,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM started_at) AS BIGINT) AS started_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finished_at) AS BIGINT) AS finished_at_unix_secs
CAST(EXTRACT(EPOCH FROM created_at) * 1000 AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM started_at) * 1000 AS BIGINT) AS started_at_unix_ms,
CAST(EXTRACT(EPOCH FROM finished_at) * 1000 AS BIGINT) AS finished_at_unix_ms
FROM request_candidates
ORDER BY created_at DESC
LIMIT $1
@@ -96,9 +96,9 @@ SELECT
concurrent_requests,
extra_data,
required_capabilities,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM started_at) AS BIGINT) AS started_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finished_at) AS BIGINT) AS finished_at_unix_secs
CAST(EXTRACT(EPOCH FROM created_at) * 1000 AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM started_at) * 1000 AS BIGINT) AS started_at_unix_ms,
CAST(EXTRACT(EPOCH FROM finished_at) * 1000 AS BIGINT) AS finished_at_unix_ms
FROM request_candidates
WHERE provider_id = $1
ORDER BY created_at DESC
@@ -128,9 +128,9 @@ SELECT
concurrent_requests,
extra_data,
required_capabilities,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM started_at) AS BIGINT) AS started_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finished_at) AS BIGINT) AS finished_at_unix_secs
CAST(EXTRACT(EPOCH FROM created_at) * 1000 AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM started_at) * 1000 AS BIGINT) AS started_at_unix_ms,
CAST(EXTRACT(EPOCH FROM finished_at) * 1000 AS BIGINT) AS finished_at_unix_ms
FROM request_candidates
WHERE endpoint_id = ANY($1)
AND created_at >= TO_TIMESTAMP($2)
@@ -158,8 +158,8 @@ SELECT
COUNT(id) AS total_count,
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS success_count,
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed_count,
CAST(EXTRACT(EPOCH FROM MIN(created_at)) AS BIGINT) AS min_created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM MAX(created_at)) AS BIGINT) AS max_created_at_unix_secs
CAST(EXTRACT(EPOCH FROM MIN(created_at)) * 1000 AS BIGINT) AS min_created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM MAX(created_at)) * 1000 AS BIGINT) AS max_created_at_unix_ms
FROM request_candidates
WHERE endpoint_id = ANY($1)
AND created_at >= TO_TIMESTAMP($2)
@@ -219,9 +219,9 @@ VALUES (
$19,
$20,
$21,
TO_TIMESTAMP(COALESCE($22, 0)),
TO_TIMESTAMP($23),
TO_TIMESTAMP($24)
TO_TIMESTAMP(COALESCE($22, 0) / 1000.0),
TO_TIMESTAMP($23 / 1000.0),
TO_TIMESTAMP($24 / 1000.0)
)
ON CONFLICT (request_id, candidate_index, retry_index)
DO UPDATE SET
@@ -266,9 +266,9 @@ RETURNING
concurrent_requests,
extra_data,
required_capabilities,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM started_at) AS BIGINT) AS started_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finished_at) AS BIGINT) AS finished_at_unix_secs
CAST(EXTRACT(EPOCH FROM created_at) * 1000 AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM started_at) * 1000 AS BIGINT) AS started_at_unix_ms,
CAST(EXTRACT(EPOCH FROM finished_at) * 1000 AS BIGINT) AS finished_at_unix_ms
"#;
const DELETE_CREATED_BEFORE_SQL: &str = r#"
@@ -481,30 +481,24 @@ impl SqlxRequestCandidateReadRepository {
)
},
)?,
min_created_at_unix_secs: row_get::<Option<i64>>(
row,
"min_created_at_unix_secs",
)?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"public health min_created_at_unix_secs out of range: {value}"
))
min_created_at_unix_ms: row_get::<Option<i64>>(row, "min_created_at_unix_ms")?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"public health min_created_at_unix_ms out of range: {value}"
))
})
})
})
.transpose()?,
max_created_at_unix_secs: row_get::<Option<i64>>(
row,
"max_created_at_unix_secs",
)?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"public health max_created_at_unix_secs out of range: {value}"
))
.transpose()?,
max_created_at_unix_ms: row_get::<Option<i64>>(row, "max_created_at_unix_ms")?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"public health max_created_at_unix_ms out of range: {value}"
))
})
})
})
.transpose()?,
.transpose()?,
})
})
.collect()
@@ -544,9 +538,9 @@ impl SqlxRequestCandidateReadRepository {
.bind(candidate.concurrent_requests.map(to_i32).transpose()?)
.bind(&candidate.extra_data)
.bind(&candidate.required_capabilities)
.bind(candidate.created_at_unix_secs.map(|value| value as f64))
.bind(candidate.started_at_unix_secs.map(|value| value as f64))
.bind(candidate.finished_at_unix_secs.map(|value| value as f64))
.bind(candidate.created_at_unix_ms.map(|value| value as f64))
.bind(candidate.started_at_unix_ms.map(|value| value as f64))
.bind(candidate.finished_at_unix_ms.map(|value| value as f64))
.fetch_one(&mut **tx)
.await
.map_postgres_err()?;
@@ -683,9 +677,9 @@ fn map_request_candidate_row(
row_get(row, "concurrent_requests")?,
row_get(row, "extra_data")?,
row_get(row, "required_capabilities")?,
row_get(row, "created_at_unix_secs")?,
row_get(row, "started_at_unix_secs")?,
row_get(row, "finished_at_unix_secs")?,
row_get(row, "created_at_unix_ms")?,
row_get(row, "started_at_unix_ms")?,
row_get(row, "finished_at_unix_ms")?,
)
}

View File

@@ -67,8 +67,8 @@ impl GeminiFileMappingReadRepository for InMemoryGeminiFileMappingRepository {
.collect::<Vec<_>>();
items.sort_by(|left, right| {
right
.created_at_unix_secs
.cmp(&left.created_at_unix_secs)
.created_at_unix_ms
.cmp(&left.created_at_unix_ms)
.then_with(|| left.file_name.cmp(&right.file_name))
});
let total = items.len();
@@ -127,9 +127,9 @@ impl GeminiFileMappingWriteRepository for InMemoryGeminiFileMappingRepository {
.by_file
.write()
.expect("gemini mapping repository lock");
let created_at_unix_secs = guard
let created_at_unix_ms = guard
.get(&record.file_name)
.map(|existing| existing.created_at_unix_secs)
.map(|existing| existing.created_at_unix_ms)
.unwrap_or_else(current_unix_secs);
let mapping = StoredGeminiFileMapping {
id: record.id.clone(),
@@ -139,7 +139,7 @@ impl GeminiFileMappingWriteRepository for InMemoryGeminiFileMappingRepository {
display_name: record.display_name.clone(),
mime_type: record.mime_type.clone(),
source_hash: record.source_hash.clone(),
created_at_unix_secs,
created_at_unix_ms,
expires_at_unix_secs: record.expires_at_unix_secs,
};
guard.insert(record.file_name.clone(), mapping.clone());
@@ -242,7 +242,7 @@ mod tests {
let first = repo.upsert(sample_record("id-1", "files/same")).await?;
let replaced = repo.upsert(sample_record("id-2", "files/same")).await?;
assert_eq!(replaced.created_at_unix_secs, first.created_at_unix_secs);
assert_eq!(replaced.created_at_unix_ms, first.created_at_unix_ms);
assert_eq!(replaced.id, "id-2");
Ok(())
}
@@ -303,7 +303,7 @@ mod tests {
id: &str,
file_name: &str,
mime_type: &str,
created_at_unix_secs: u64,
created_at_unix_ms: u64,
expires_at_unix_secs: u64,
) -> crate::repository::gemini_file_mappings::StoredGeminiFileMapping {
crate::repository::gemini_file_mappings::StoredGeminiFileMapping {
@@ -314,7 +314,7 @@ mod tests {
display_name: Some(format!("display-{id}")),
mime_type: (!mime_type.is_empty()).then(|| mime_type.to_string()),
source_hash: Some(format!("hash-{id}")),
created_at_unix_secs,
created_at_unix_ms,
expires_at_unix_secs,
}
}

View File

@@ -27,8 +27,8 @@ impl SqlxGeminiFileMappingRepository {
display_name: row.try_get("display_name").ok().flatten(),
mime_type: row.try_get("mime_type").ok().flatten(),
source_hash: row.try_get("source_hash").ok().flatten(),
created_at_unix_secs: u64::try_from(
row.try_get::<i64, _>("created_at_unix_secs")
created_at_unix_ms: u64::try_from(
row.try_get::<i64, _>("created_at_unix_ms")
.map_postgres_err()?,
)
.map_err(|_| {
@@ -65,7 +65,7 @@ SELECT
display_name,
mime_type,
source_hash,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM expires_at)::bigint AS expires_at_unix_secs
FROM gemini_file_mappings
WHERE file_name = $1
@@ -204,7 +204,7 @@ RETURNING
display_name,
mime_type,
source_hash,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM expires_at)::bigint AS expires_at_unix_secs
"#,
)
@@ -254,7 +254,7 @@ RETURNING
display_name,
mime_type,
source_hash,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM expires_at)::bigint AS expires_at_unix_secs
"#,
)
@@ -304,7 +304,7 @@ SELECT
display_name,
mime_type,
source_hash,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM expires_at)::bigint AS expires_at_unix_secs
FROM gemini_file_mappings
WHERE 1=1

View File

@@ -38,7 +38,7 @@ pub struct StoredGeminiFileMapping {
pub display_name: Option<String>,
pub mime_type: Option<String>,
pub source_hash: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub expires_at_unix_secs: u64,
}
@@ -47,7 +47,7 @@ impl StoredGeminiFileMapping {
id: String,
file_name: String,
key_id: String,
created_at_unix_secs: i64,
created_at_unix_ms: i64,
expires_at_unix_secs: i64,
) -> Result<Self, crate::DataLayerError> {
if file_name.trim().is_empty() {
@@ -60,9 +60,9 @@ impl StoredGeminiFileMapping {
"gemini_file_mappings.key_id is empty".to_string(),
));
}
let created_at_unix_secs = u64::try_from(created_at_unix_secs).map_err(|_| {
let created_at_unix_ms = u64::try_from(created_at_unix_ms).map_err(|_| {
crate::DataLayerError::UnexpectedValue(format!(
"invalid gemini_file_mappings.created_at: {created_at_unix_secs}"
"invalid gemini_file_mappings.created_at: {created_at_unix_ms}"
))
})?;
let expires_at_unix_secs = u64::try_from(expires_at_unix_secs).map_err(|_| {
@@ -78,7 +78,7 @@ impl StoredGeminiFileMapping {
display_name: None,
mime_type: None,
source_hash: None,
created_at_unix_secs,
created_at_unix_ms,
expires_at_unix_secs,
})
}

View File

@@ -314,9 +314,9 @@ impl GlobalModelReadRepository for InMemoryGlobalModelReadRepository {
.collect::<Vec<_>>();
filtered.sort_by(|left, right| {
right
.created_at_unix_secs
.created_at_unix_ms
.unwrap_or_default()
.cmp(&left.created_at_unix_secs.unwrap_or_default())
.cmp(&left.created_at_unix_ms.unwrap_or_default())
.then_with(|| left.id.cmp(&right.id))
});
Ok(filtered
@@ -368,7 +368,7 @@ impl GlobalModelReadRepository for InMemoryGlobalModelReadRepository {
filtered.sort_by(|left, right| {
left.global_model_name
.cmp(&right.global_model_name)
.then_with(|| right.created_at_unix_secs.cmp(&left.created_at_unix_secs))
.then_with(|| right.created_at_unix_ms.cmp(&left.created_at_unix_ms))
.then_with(|| left.id.cmp(&right.id))
});
Ok(filtered)
@@ -417,9 +417,9 @@ impl GlobalModelReadRepository for InMemoryGlobalModelReadRepository {
.collect::<Vec<_>>();
filtered.sort_by(|left, right| {
right
.created_at_unix_secs
.created_at_unix_ms
.unwrap_or_default()
.cmp(&left.created_at_unix_secs.unwrap_or_default())
.cmp(&left.created_at_unix_ms.unwrap_or_default())
.then_with(|| left.id.cmp(&right.id))
});
Ok(filtered)

View File

@@ -91,7 +91,7 @@ SELECT
m.is_active,
COALESCE(m.is_available, TRUE) AS is_available,
m.config,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM m.updated_at)::bigint AS updated_at_unix_secs,
gm.name AS global_model_name,
gm.display_name AS global_model_display_name,
@@ -115,7 +115,7 @@ SELECT
COALESCE(gm_stats.provider_count, 0) AS provider_count,
COALESCE(gm_stats.active_provider_count, 0) AS active_provider_count,
COALESCE(gm.usage_count, 0)::bigint AS usage_count,
EXTRACT(EPOCH FROM gm.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM gm.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM gm.updated_at)::bigint AS updated_at_unix_secs
FROM global_models gm
LEFT JOIN (
@@ -316,7 +316,7 @@ SELECT
m.is_active,
COALESCE(m.is_available, TRUE) AS is_available,
m.config,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM m.updated_at)::bigint AS updated_at_unix_secs,
gm.name AS global_model_name,
gm.display_name AS global_model_display_name,
@@ -361,7 +361,7 @@ SELECT
m.is_active,
COALESCE(m.is_available, TRUE) AS is_available,
m.config,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM m.updated_at)::bigint AS updated_at_unix_secs,
gm.name AS global_model_name,
gm.display_name AS global_model_display_name,
@@ -402,7 +402,7 @@ SELECT
COALESCE(gm_stats.provider_count, 0) AS provider_count,
COALESCE(gm_stats.active_provider_count, 0) AS active_provider_count,
COALESCE(gm.usage_count, 0)::bigint AS usage_count,
EXTRACT(EPOCH FROM gm.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM gm.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM gm.updated_at)::bigint AS updated_at_unix_secs
FROM global_models gm
LEFT JOIN (
@@ -449,7 +449,7 @@ SELECT
COALESCE(gm_stats.provider_count, 0) AS provider_count,
COALESCE(gm_stats.active_provider_count, 0) AS active_provider_count,
COALESCE(gm.usage_count, 0)::bigint AS usage_count,
EXTRACT(EPOCH FROM gm.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM gm.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM gm.updated_at)::bigint AS updated_at_unix_secs
FROM global_models gm
LEFT JOIN (
@@ -500,7 +500,7 @@ SELECT
m.is_active,
COALESCE(m.is_available, TRUE) AS is_available,
m.config,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM m.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM m.updated_at)::bigint AS updated_at_unix_secs,
gm.name AS global_model_name,
gm.display_name AS global_model_display_name,
@@ -1062,8 +1062,8 @@ fn map_public_catalog_model_row(row: &PgRow) -> Result<StoredPublicCatalogModel,
}
fn map_admin_provider_model_row(row: &PgRow) -> Result<StoredAdminProviderModel, DataLayerError> {
let created_at_unix_secs = row
.try_get::<Option<i64>, _>("created_at_unix_secs")
let created_at_unix_ms = row
.try_get::<Option<i64>, _>("created_at_unix_ms")
.map_postgres_err()?
.map(|value| value.max(0) as u64);
let updated_at_unix_secs = row
@@ -1089,7 +1089,7 @@ fn map_admin_provider_model_row(row: &PgRow) -> Result<StoredAdminProviderModel,
row.try_get("is_active").map_postgres_err()?,
row.try_get("is_available").map_postgres_err()?,
row.try_get("config").map_postgres_err()?,
created_at_unix_secs,
created_at_unix_ms,
updated_at_unix_secs,
row.try_get("global_model_name").map_postgres_err()?,
row.try_get("global_model_display_name")
@@ -1103,8 +1103,8 @@ fn map_admin_provider_model_row(row: &PgRow) -> Result<StoredAdminProviderModel,
}
fn map_admin_global_model_row(row: &PgRow) -> Result<StoredAdminGlobalModel, DataLayerError> {
let created_at_unix_secs = row
.try_get::<Option<i64>, _>("created_at_unix_secs")
let created_at_unix_ms = row
.try_get::<Option<i64>, _>("created_at_unix_ms")
.map_postgres_err()?
.map(|value| value.max(0) as u64);
let updated_at_unix_secs = row
@@ -1136,7 +1136,7 @@ fn map_admin_global_model_row(row: &PgRow) -> Result<StoredAdminGlobalModel, Dat
provider_count,
active_provider_count,
usage_count,
created_at_unix_secs,
created_at_unix_ms,
updated_at_unix_secs,
)
}

View File

@@ -56,8 +56,8 @@ impl ManagementTokenReadRepository for InMemoryManagementTokenRepository {
filtered.sort_by(|left, right| {
right
.token
.created_at_unix_secs
.cmp(&left.token.created_at_unix_secs)
.created_at_unix_ms
.cmp(&left.token.created_at_unix_ms)
.then_with(|| right.token.id.cmp(&left.token.id))
});

View File

@@ -22,7 +22,7 @@ SELECT
mt.last_used_ip,
COALESCE(mt.usage_count, 0) AS usage_count,
mt.is_active,
EXTRACT(EPOCH FROM mt.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM mt.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM mt.updated_at)::bigint AS updated_at_unix_secs,
u.id AS user_row_id,
u.email AS user_email,
@@ -57,7 +57,7 @@ SELECT
mt.last_used_ip,
COALESCE(mt.usage_count, 0) AS usage_count,
mt.is_active,
EXTRACT(EPOCH FROM mt.created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM mt.created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM mt.updated_at)::bigint AS updated_at_unix_secs,
u.id AS user_row_id,
u.email AS user_email,
@@ -112,7 +112,7 @@ RETURNING
last_used_ip,
COALESCE(usage_count, 0) AS usage_count,
is_active,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -149,7 +149,7 @@ RETURNING
last_used_ip,
COALESCE(usage_count, 0) AS usage_count,
is_active,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -170,7 +170,7 @@ RETURNING
last_used_ip,
COALESCE(usage_count, 0) AS usage_count,
is_active,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -192,7 +192,7 @@ RETURNING
last_used_ip,
COALESCE(usage_count, 0) AS usage_count,
is_active,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -392,7 +392,7 @@ fn map_token_row(row: &PgRow) -> Result<StoredManagementToken, DataLayerError> {
row.try_get("is_active").map_postgres_err()?,
)
.with_timestamps(
optional_unix_secs(row.try_get("created_at_unix_secs").map_postgres_err()?),
optional_unix_secs(row.try_get("created_at_unix_ms").map_postgres_err()?),
optional_unix_secs(row.try_get("updated_at_unix_secs").map_postgres_err()?),
))
}

View File

@@ -52,7 +52,7 @@ pub struct StoredManagementToken {
pub last_used_ip: Option<String>,
pub usage_count: u64,
pub is_active: bool,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
pub updated_at_unix_secs: Option<u64>,
}
@@ -85,7 +85,7 @@ impl StoredManagementToken {
last_used_ip: None,
usage_count: 0,
is_active: true,
created_at_unix_secs: None,
created_at_unix_ms: None,
updated_at_unix_secs: None,
})
}
@@ -120,10 +120,10 @@ impl StoredManagementToken {
pub fn with_timestamps(
mut self,
created_at_unix_secs: Option<u64>,
created_at_unix_ms: Option<u64>,
updated_at_unix_secs: Option<u64>,
) -> Self {
self.created_at_unix_secs = created_at_unix_secs;
self.created_at_unix_ms = created_at_unix_ms;
self.updated_at_unix_secs = updated_at_unix_secs;
self
}

View File

@@ -76,7 +76,7 @@ impl OAuthProviderWriteRepository for InMemoryOAuthProviderRepository {
let existing = items.get(&record.provider_type).cloned();
let created_at = existing
.as_ref()
.and_then(|item| item.created_at_unix_secs)
.and_then(|item| item.created_at_unix_ms)
.or(now);
let client_secret_encrypted = match (&record.client_secret_encrypted, existing.as_ref()) {
(EncryptedSecretUpdate::Preserve, Some(item)) => item.client_secret_encrypted.clone(),

View File

@@ -22,7 +22,7 @@ SELECT
attribute_mapping,
extra_config,
is_enabled,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM oauth_providers
ORDER BY provider_type ASC
@@ -43,7 +43,7 @@ SELECT
attribute_mapping,
extra_config,
is_enabled,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM oauth_providers
WHERE provider_type = $1
@@ -156,7 +156,7 @@ RETURNING
attribute_mapping,
extra_config,
is_enabled,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
"#;
@@ -343,7 +343,7 @@ fn map_oauth_provider_row(row: &PgRow) -> Result<StoredOAuthProviderConfig, Data
row.try_get("is_enabled").map_postgres_err()?,
)
.with_timestamps(
optional_unix_secs(row.try_get("created_at_unix_secs").map_postgres_err()?),
optional_unix_secs(row.try_get("created_at_unix_ms").map_postgres_err()?),
optional_unix_secs(row.try_get("updated_at_unix_secs").map_postgres_err()?),
))
}

View File

@@ -15,7 +15,7 @@ pub struct StoredOAuthProviderConfig {
pub attribute_mapping: Option<serde_json::Value>,
pub extra_config: Option<serde_json::Value>,
pub is_enabled: bool,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
pub updated_at_unix_secs: Option<u64>,
}
@@ -67,7 +67,7 @@ impl StoredOAuthProviderConfig {
attribute_mapping: None,
extra_config: None,
is_enabled: false,
created_at_unix_secs: None,
created_at_unix_ms: None,
updated_at_unix_secs: None,
})
}
@@ -97,10 +97,10 @@ impl StoredOAuthProviderConfig {
pub fn with_timestamps(
mut self,
created_at_unix_secs: Option<u64>,
created_at_unix_ms: Option<u64>,
updated_at_unix_secs: Option<u64>,
) -> Self {
self.created_at_unix_secs = created_at_unix_secs;
self.created_at_unix_ms = created_at_unix_ms;
self.updated_at_unix_secs = updated_at_unix_secs;
self
}

View File

@@ -34,7 +34,7 @@ SELECT
request_timeout,
stream_first_byte_timeout,
config,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM providers
WHERE id IN (
@@ -57,7 +57,7 @@ SELECT
config,
format_acceptance_config,
proxy,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM provider_endpoints
WHERE id IN (
@@ -79,7 +79,7 @@ SELECT
config,
format_acceptance_config,
proxy,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM provider_endpoints
WHERE id IN (
@@ -102,7 +102,7 @@ SELECT
config,
format_acceptance_config,
proxy,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM provider_endpoints
WHERE provider_id IN (
@@ -124,7 +124,7 @@ SELECT
config,
format_acceptance_config,
proxy,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM provider_endpoints
WHERE provider_id IN (
@@ -177,7 +177,7 @@ SELECT
EXTRACT(EPOCH FROM oauth_invalid_at)::bigint AS oauth_invalid_at_unix_secs,
oauth_invalid_reason,
status_snapshot,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs,
health_by_format,
circuit_breaker_by_format
@@ -232,7 +232,7 @@ SELECT
EXTRACT(EPOCH FROM oauth_invalid_at)::bigint AS oauth_invalid_at_unix_secs,
oauth_invalid_reason,
status_snapshot,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs,
health_by_format,
circuit_breaker_by_format
@@ -311,7 +311,7 @@ SELECT
request_timeout,
stream_first_byte_timeout,
config,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM providers
WHERE ($1::boolean = false OR is_active = true)
@@ -523,7 +523,7 @@ SELECT
EXTRACT(EPOCH FROM oauth_invalid_at)::bigint AS oauth_invalid_at_unix_secs,
oauth_invalid_reason,
status_snapshot,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs,
health_by_format,
circuit_breaker_by_format
@@ -765,7 +765,7 @@ INSERT INTO providers (
.bind(provider.request_timeout_secs)
.bind(provider.stream_first_byte_timeout_secs)
.bind(&provider.config)
.bind(provider.created_at_unix_secs.map(|value| value as f64))
.bind(provider.created_at_unix_ms.map(|value| value as f64))
.bind(provider.updated_at_unix_secs.map(|value| value as f64))
.execute(&mut *tx)
.await
@@ -1253,7 +1253,7 @@ INSERT INTO provider_api_keys (
.bind(&key.health_by_format)
.bind(&key.circuit_breaker_by_format)
.bind(key.is_active)
.bind(key.created_at_unix_secs.map(|value| value as f64))
.bind(key.created_at_unix_ms.map(|value| value as f64))
.bind(key.updated_at_unix_secs.map(|value| value as f64))
.execute(&self.pool)
.await
@@ -1348,7 +1348,7 @@ INSERT INTO provider_endpoints (
.bind(&endpoint.config)
.bind(&endpoint.format_acceptance_config)
.bind(&endpoint.proxy)
.bind(endpoint.created_at_unix_secs.map(|value| value as f64))
.bind(endpoint.created_at_unix_ms.map(|value| value as f64))
.bind(endpoint.updated_at_unix_secs.map(|value| value as f64))
.execute(&self.pool)
.await
@@ -1414,7 +1414,7 @@ INSERT INTO provider_endpoints (
.bind(&endpoint.config)
.bind(&endpoint.format_acceptance_config)
.bind(&endpoint.proxy)
.bind(endpoint.created_at_unix_secs.map(|value| value as f64))
.bind(endpoint.created_at_unix_ms.map(|value| value as f64))
.bind(endpoint.updated_at_unix_secs.map(|value| value as f64))
.execute(&self.pool)
.await
@@ -1946,11 +1946,11 @@ fn map_provider_row(row: &PgRow) -> Result<StoredProviderCatalogProvider, DataLa
})
})
.transpose()?;
let created_at_unix_secs = row_get::<Option<i64>>(row, "created_at_unix_secs")?
let created_at_unix_ms = row_get::<Option<i64>>(row, "created_at_unix_ms")?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"invalid providers.created_at_unix_secs: {value}"
"invalid providers.created_at_unix_ms: {value}"
))
})
})
@@ -1991,15 +1991,15 @@ fn map_provider_row(row: &PgRow) -> Result<StoredProviderCatalogProvider, DataLa
row_get(row, "stream_first_byte_timeout")?,
row_get(row, "config")?,
)
.with_timestamps(created_at_unix_secs, updated_at_unix_secs))
.with_timestamps(created_at_unix_ms, updated_at_unix_secs))
}
fn map_endpoint_row(row: &PgRow) -> Result<StoredProviderCatalogEndpoint, DataLayerError> {
let created_at_unix_secs = row_get::<Option<i64>>(row, "created_at_unix_secs")?
let created_at_unix_ms = row_get::<Option<i64>>(row, "created_at_unix_ms")?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"invalid provider_endpoints.created_at_unix_secs: {value}"
"invalid provider_endpoints.created_at_unix_ms: {value}"
))
})
})
@@ -2021,7 +2021,7 @@ fn map_endpoint_row(row: &PgRow) -> Result<StoredProviderCatalogEndpoint, DataLa
row_get(row, "endpoint_kind")?,
row_get(row, "is_active")?,
)?
.with_timestamps(created_at_unix_secs, updated_at_unix_secs)
.with_timestamps(created_at_unix_ms, updated_at_unix_secs)
.with_health_score(
row.try_get::<Option<f64>, _>("health_score")
.ok()
@@ -2182,11 +2182,11 @@ fn map_key_row(row: &PgRow) -> Result<StoredProviderCatalogKey, DataLayerError>
})
})
.transpose()?;
let created_at_unix_secs = row_get::<Option<i64>>(row, "created_at_unix_secs")?
let created_at_unix_ms = row_get::<Option<i64>>(row, "created_at_unix_ms")?
.map(|value| {
u64::try_from(value).map_err(|_| {
DataLayerError::UnexpectedValue(format!(
"invalid provider_api_keys.created_at_unix_secs: {value}"
"invalid provider_api_keys.created_at_unix_ms: {value}"
))
})
})
@@ -2260,7 +2260,7 @@ fn map_key_row(row: &PgRow) -> Result<StoredProviderCatalogKey, DataLayerError>
key.oauth_invalid_at_unix_secs = oauth_invalid_at_unix_secs;
key.oauth_invalid_reason = row.try_get("oauth_invalid_reason").ok();
key.status_snapshot = row.try_get("status_snapshot").ok();
key.created_at_unix_secs = created_at_unix_secs;
key.created_at_unix_ms = created_at_unix_ms;
key.updated_at_unix_secs = updated_at_unix_secs;
key
})

View File

@@ -17,7 +17,7 @@ pub struct StoredAdminProviderOAuthDeviceSession {
pub expires_at_unix_secs: u64,
pub status: String,
pub proxy_node_id: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub key_id: Option<String>,
pub email: Option<String>,
pub replaced: bool,

View File

@@ -90,9 +90,9 @@ impl ProxyNodeReadRepository for InMemoryProxyNodeRepository {
.collect::<Vec<_>>();
items.sort_by(|left, right| {
right
.created_at_unix_secs
.created_at_unix_ms
.unwrap_or(0)
.cmp(&left.created_at_unix_secs.unwrap_or(0))
.cmp(&left.created_at_unix_ms.unwrap_or(0))
.then(right.id.cmp(&left.id))
});
items.truncate(limit);
@@ -191,7 +191,7 @@ impl ProxyNodeWriteRepository for InMemoryProxyNodeRepository {
node_id: mutation.node_id.clone(),
event_type: event_type.to_string(),
detail: Some(format!("[stale_ignored] {event_detail}")),
created_at_unix_secs: Self::now_unix_secs(),
created_at_unix_ms: Self::now_unix_secs(),
});
return Ok(Some(node.clone()));
}
@@ -211,7 +211,7 @@ impl ProxyNodeWriteRepository for InMemoryProxyNodeRepository {
node_id: mutation.node_id.clone(),
event_type: event_type.to_string(),
detail: Some(event_detail),
created_at_unix_secs: Some(event_time),
created_at_unix_ms: Some(event_time),
});
Ok(Some(node.clone()))
}
@@ -341,7 +341,7 @@ mod tests {
.expect("list events should succeed");
assert_eq!(events.len(), 2);
assert_eq!(events[0].event_type, "disconnected");
assert_eq!(events[0].created_at_unix_secs, Some(1_800_000_000));
assert_eq!(events[0].created_at_unix_ms, Some(1_800_000_000));
assert_eq!(
events[0].detail.as_deref(),
Some("[tunnel_node_status] conn_count=0")
@@ -365,14 +365,14 @@ mod tests {
node_id: "node-1".to_string(),
event_type: "connected".to_string(),
detail: Some("older".to_string()),
created_at_unix_secs: Some(1_710_000_000),
created_at_unix_ms: Some(1_710_000_000),
},
StoredProxyNodeEvent {
id: 2,
node_id: "node-1".to_string(),
event_type: "disconnected".to_string(),
detail: Some("newer".to_string()),
created_at_unix_secs: Some(1_710_000_100),
created_at_unix_ms: Some(1_710_000_100),
},
],
);

View File

@@ -39,7 +39,7 @@ SELECT
EXTRACT(EPOCH FROM tunnel_connected_at)::bigint AS tunnel_connected_at_unix_secs,
remote_config,
config_version,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM proxy_nodes
WHERE id = $1
@@ -75,7 +75,7 @@ SELECT
EXTRACT(EPOCH FROM tunnel_connected_at)::bigint AS tunnel_connected_at_unix_secs,
remote_config,
config_version,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms,
EXTRACT(EPOCH FROM updated_at)::bigint AS updated_at_unix_secs
FROM proxy_nodes
ORDER BY name ASC, id ASC
@@ -87,7 +87,7 @@ SELECT
node_id,
CAST(event_type AS TEXT) AS event_type,
detail,
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_secs
EXTRACT(EPOCH FROM created_at)::bigint AS created_at_unix_ms
FROM proxy_node_events
WHERE node_id = $1
ORDER BY created_at DESC, id DESC
@@ -183,7 +183,7 @@ impl SqlxProxyNodeRepository {
.map_postgres_err()?,
),
row.try_get("remote_config").map_postgres_err()?,
Self::optional_unix_secs(row.try_get("created_at_unix_secs").map_postgres_err()?),
Self::optional_unix_secs(row.try_get("created_at_unix_ms").map_postgres_err()?),
Self::optional_unix_secs(row.try_get("updated_at_unix_secs").map_postgres_err()?),
))
}
@@ -194,8 +194,8 @@ impl SqlxProxyNodeRepository {
node_id: row.try_get("node_id").map_postgres_err()?,
event_type: row.try_get("event_type").map_postgres_err()?,
detail: row.try_get("detail").map_postgres_err()?,
created_at_unix_secs: Self::optional_unix_secs(
row.try_get("created_at_unix_secs").map_postgres_err()?,
created_at_unix_ms: Self::optional_unix_secs(
row.try_get("created_at_unix_ms").map_postgres_err()?,
),
})
}

View File

@@ -29,7 +29,7 @@ pub struct StoredProxyNode {
pub tunnel_connected_at_unix_secs: Option<u64>,
pub remote_config: Option<serde_json::Value>,
pub config_version: i32,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
pub updated_at_unix_secs: Option<u64>,
}
@@ -101,7 +101,7 @@ impl StoredProxyNode {
tunnel_connected_at_unix_secs: None,
remote_config: None,
config_version,
created_at_unix_secs: None,
created_at_unix_ms: None,
updated_at_unix_secs: None,
})
}
@@ -118,7 +118,7 @@ impl StoredProxyNode {
estimated_max_concurrency: Option<i32>,
tunnel_connected_at_unix_secs: Option<u64>,
remote_config: Option<serde_json::Value>,
created_at_unix_secs: Option<u64>,
created_at_unix_ms: Option<u64>,
updated_at_unix_secs: Option<u64>,
) -> Self {
self.region = region;
@@ -130,7 +130,7 @@ impl StoredProxyNode {
self.estimated_max_concurrency = estimated_max_concurrency;
self.tunnel_connected_at_unix_secs = tunnel_connected_at_unix_secs;
self.remote_config = remote_config;
self.created_at_unix_secs = created_at_unix_secs;
self.created_at_unix_ms = created_at_unix_ms;
self.updated_at_unix_secs = updated_at_unix_secs;
self
}
@@ -177,7 +177,7 @@ pub struct StoredProxyNodeEvent {
pub node_id: String,
pub event_type: String,
pub detail: Option<String>,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
}
pub fn normalize_proxy_metadata(

View File

@@ -90,7 +90,7 @@ mod tests {
match_status: ShadowResultMatchStatus::Match,
status_code: Some(200),
error_message: None,
created_at_unix_secs: updated_at_unix_secs.saturating_sub(10),
created_at_unix_ms: updated_at_unix_secs.saturating_sub(10),
updated_at_unix_secs,
}
}
@@ -149,7 +149,7 @@ mod tests {
match_status: ShadowResultMatchStatus::Mismatch,
status_code: Some(502),
error_message: Some("mismatch".to_string()),
created_at_unix_secs: 100,
created_at_unix_ms: 100,
updated_at_unix_secs: 200,
})
.await

View File

@@ -67,8 +67,8 @@ pub fn merge_shadow_result_sample(
match_status,
status_code: status_code.or(existing.and_then(|row| row.status_code)),
error_message: resolve_error_message(existing, error_message, match_status),
created_at_unix_secs: existing
.map(|row| row.created_at_unix_secs)
created_at_unix_ms: existing
.map(|row| row.created_at_unix_ms)
.unwrap_or(recorded_at_unix_secs),
updated_at_unix_secs: recorded_at_unix_secs,
}
@@ -161,7 +161,7 @@ mod tests {
let merged = merge_shadow_result_sample(Some(&existing), python_sample("digest-1", 200));
assert_eq!(merged.match_status, ShadowResultMatchStatus::Match);
assert_eq!(merged.created_at_unix_secs, 100);
assert_eq!(merged.created_at_unix_ms, 100);
assert_eq!(merged.updated_at_unix_secs, 200);
assert_eq!(merged.request_id.as_deref(), Some("req-1"));
assert_eq!(merged.rust_result_digest.as_deref(), Some("digest-1"));

View File

@@ -22,7 +22,7 @@ SELECT
match_status,
status_code,
error_message,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs
FROM gateway_shadow_results
WHERE trace_id = $1 AND request_fingerprint = $2
@@ -42,7 +42,7 @@ SELECT
match_status,
status_code,
error_message,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs
FROM gateway_shadow_results
ORDER BY updated_at DESC
@@ -100,7 +100,7 @@ RETURNING
match_status,
status_code,
error_message,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs
"#;
@@ -192,7 +192,7 @@ impl SqlxShadowResultRepository {
.bind(match_status_to_database(result.match_status))
.bind(result.status_code.map(i32::from))
.bind(&result.error_message)
.bind(result.created_at_unix_secs as f64)
.bind(result.created_at_unix_ms as f64)
.bind(result.updated_at_unix_secs as f64)
.fetch_one(&mut **tx)
.await
@@ -257,7 +257,7 @@ fn map_shadow_result_row(
match_status,
row.try_get("status_code").map_postgres_err()?,
row.try_get("error_message").map_postgres_err()?,
row.try_get("created_at_unix_secs").map_postgres_err()?,
row.try_get("created_at_unix_ms").map_postgres_err()?,
row.try_get("updated_at_unix_secs").map_postgres_err()?,
)
}

View File

@@ -35,7 +35,7 @@ pub struct StoredShadowResult {
pub match_status: ShadowResultMatchStatus,
pub status_code: Option<u16>,
pub error_message: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub updated_at_unix_secs: u64,
}
@@ -53,7 +53,7 @@ impl StoredShadowResult {
match_status: ShadowResultMatchStatus,
status_code: Option<i32>,
error_message: Option<String>,
created_at_unix_secs: i64,
created_at_unix_ms: i64,
updated_at_unix_secs: i64,
) -> Result<Self, crate::DataLayerError> {
let status_code = status_code
@@ -63,9 +63,9 @@ impl StoredShadowResult {
})
})
.transpose()?;
let created_at_unix_secs = u64::try_from(created_at_unix_secs).map_err(|_| {
let created_at_unix_ms = u64::try_from(created_at_unix_ms).map_err(|_| {
crate::DataLayerError::UnexpectedValue(format!(
"invalid created_at_unix_secs: {created_at_unix_secs}"
"invalid created_at_unix_ms: {created_at_unix_ms}"
))
})?;
let updated_at_unix_secs = u64::try_from(updated_at_unix_secs).map_err(|_| {
@@ -86,7 +86,7 @@ impl StoredShadowResult {
match_status,
status_code,
error_message,
created_at_unix_secs,
created_at_unix_ms,
updated_at_unix_secs,
})
}
@@ -105,7 +105,7 @@ pub struct UpsertShadowResult {
pub match_status: ShadowResultMatchStatus,
pub status_code: Option<u16>,
pub error_message: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub updated_at_unix_secs: u64,
}
@@ -123,7 +123,7 @@ impl UpsertShadowResult {
match_status: self.match_status,
status_code: self.status_code,
error_message: self.error_message,
created_at_unix_secs: self.created_at_unix_secs,
created_at_unix_ms: self.created_at_unix_ms,
updated_at_unix_secs: self.updated_at_unix_secs,
}
}

View File

@@ -79,12 +79,12 @@ impl UsageReadRepository for InMemoryUsageReadRepository {
.values()
.filter(|item| {
if let Some(created_from_unix_secs) = query.created_from_unix_secs {
if item.created_at_unix_secs < created_from_unix_secs {
if item.created_at_unix_ms < created_from_unix_secs {
return false;
}
}
if let Some(created_until_unix_secs) = query.created_until_unix_secs {
if item.created_at_unix_secs >= created_until_unix_secs {
if item.created_at_unix_ms >= created_until_unix_secs {
return false;
}
}
@@ -108,8 +108,8 @@ impl UsageReadRepository for InMemoryUsageReadRepository {
.cloned()
.collect();
items.sort_by(|left, right| {
left.created_at_unix_secs
.cmp(&right.created_at_unix_secs)
left.created_at_unix_ms
.cmp(&right.created_at_unix_ms)
.then_with(|| left.request_id.cmp(&right.request_id))
});
Ok(items)
@@ -133,8 +133,8 @@ impl UsageReadRepository for InMemoryUsageReadRepository {
.collect();
items.sort_by(|left, right| {
right
.created_at_unix_secs
.cmp(&left.created_at_unix_secs)
.created_at_unix_ms
.cmp(&left.created_at_unix_ms)
.then_with(|| left.id.cmp(&right.id))
});
items.truncate(limit);
@@ -209,10 +209,10 @@ impl UsageWriteRepository for InMemoryUsageReadRepository {
usage.validate()?;
let mut by_request_id = self.by_request_id.write().expect("usage repository lock");
let created_at_unix_secs = by_request_id
let created_at_unix_ms = by_request_id
.get(&usage.request_id)
.map(|existing| existing.created_at_unix_secs)
.or(usage.created_at_unix_secs)
.map(|existing| existing.created_at_unix_ms)
.or(usage.created_at_unix_ms)
.unwrap_or(usage.updated_at_unix_secs);
let total_tokens = usage
@@ -320,7 +320,7 @@ impl UsageWriteRepository for InMemoryUsageReadRepository {
request_metadata: usage
.request_metadata
.or_else(|| existing.and_then(|existing| existing.request_metadata.clone())),
created_at_unix_secs,
created_at_unix_ms,
updated_at_unix_secs: usage.updated_at_unix_secs,
finalized_at_unix_secs: usage.finalized_at_unix_secs,
};
@@ -339,7 +339,7 @@ mod tests {
};
use serde_json::json;
fn sample_usage(request_id: &str, created_at_unix_secs: i64) -> StoredRequestUsageAudit {
fn sample_usage(request_id: &str, created_at_unix_ms: i64) -> StoredRequestUsageAudit {
StoredRequestUsageAudit::new(
"usage-1".to_string(),
request_id.to_string(),
@@ -374,9 +374,9 @@ mod tests {
Some(120),
"completed".to_string(),
"settled".to_string(),
created_at_unix_secs,
created_at_unix_secs + 1,
Some(created_at_unix_secs + 2),
created_at_unix_ms,
created_at_unix_ms + 1,
Some(created_at_unix_ms + 2),
)
.expect("usage should build")
}
@@ -450,7 +450,7 @@ mod tests {
client_response_body: None,
request_metadata: None,
finalized_at_unix_secs: None,
created_at_unix_secs: Some(100),
created_at_unix_ms: Some(100),
updated_at_unix_secs: 101,
})
.await

View File

@@ -59,7 +59,7 @@ SELECT
client_response_headers,
client_response_body,
request_metadata,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM COALESCE(finalized_at, created_at)) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finalized_at) AS BIGINT) AS finalized_at_unix_secs
FROM "usage"
@@ -116,7 +116,7 @@ SELECT
client_response_headers,
client_response_body,
request_metadata,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM COALESCE(finalized_at, created_at)) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finalized_at) AS BIGINT) AS finalized_at_unix_secs
FROM "usage"
@@ -203,7 +203,7 @@ SELECT
NULL::jsonb AS client_response_headers,
NULL::jsonb AS client_response_body,
NULL::jsonb AS request_metadata,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM COALESCE(finalized_at, created_at)) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finalized_at) AS BIGINT) AS finalized_at_unix_secs
FROM "usage"
@@ -258,7 +258,7 @@ SELECT
NULL::jsonb AS client_response_headers,
NULL::jsonb AS client_response_body,
NULL::jsonb AS request_metadata,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM COALESCE(finalized_at, created_at)) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finalized_at) AS BIGINT) AS finalized_at_unix_secs
FROM "usage"
@@ -465,7 +465,7 @@ RETURNING
client_response_headers,
client_response_body,
request_metadata,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM COALESCE(finalized_at, created_at)) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM finalized_at) AS BIGINT) AS finalized_at_unix_secs
"#;
@@ -713,7 +713,7 @@ impl SqlxUsageReadRepository {
.bind(&usage.client_response_body)
.bind(&usage.request_metadata)
.bind(usage.finalized_at_unix_secs.map(|value| value as f64))
.bind(usage.created_at_unix_secs.map(|value| value as f64))
.bind(usage.created_at_unix_ms.map(|value| value as f64))
.fetch_one(&mut **tx)
.await
.map_postgres_err()?;
@@ -816,7 +816,7 @@ fn map_usage_row(row: &sqlx::postgres::PgRow) -> Result<StoredRequestUsageAudit,
row.try_get("first_byte_time_ms").map_postgres_err()?,
row.try_get("status").map_postgres_err()?,
row.try_get("billing_status").map_postgres_err()?,
row.try_get("created_at_unix_secs").map_postgres_err()?,
row.try_get("created_at_unix_ms").map_postgres_err()?,
row.try_get("updated_at_unix_secs").map_postgres_err()?,
row.try_get("finalized_at_unix_secs").map_postgres_err()?,
)?;
@@ -953,7 +953,7 @@ mod tests {
client_response_body: None,
request_metadata: None,
finalized_at_unix_secs: None,
created_at_unix_secs: Some(100),
created_at_unix_ms: Some(100),
updated_at_unix_secs: 101,
})
.await;

View File

@@ -180,8 +180,8 @@ impl VideoTaskReadRepository for InMemoryVideoTaskRepository {
.collect::<Vec<_>>();
tasks.sort_by(|left, right| {
right
.created_at_unix_secs
.cmp(&left.created_at_unix_secs)
.created_at_unix_ms
.cmp(&left.created_at_unix_ms)
.then_with(|| right.updated_at_unix_secs.cmp(&left.updated_at_unix_secs))
});
Ok(tasks.into_iter().skip(offset).take(limit).collect())
@@ -289,7 +289,7 @@ impl VideoTaskReadRepository for InMemoryVideoTaskRepository {
.values()
.filter(|task| {
Self::matches_filter(task, filter)
&& task.created_at_unix_secs >= created_since_unix_secs
&& task.created_at_unix_ms >= created_since_unix_secs
})
.count() as u64)
}
@@ -408,7 +408,7 @@ mod tests {
next_poll_at_unix_secs: Some(updated_at_unix_secs),
poll_count: 0,
max_poll_count: 360,
created_at_unix_secs: updated_at_unix_secs.saturating_sub(10),
created_at_unix_ms: updated_at_unix_secs.saturating_sub(10),
submitted_at_unix_secs: Some(updated_at_unix_secs.saturating_sub(10)),
completed_at_unix_secs: None,
updated_at_unix_secs,
@@ -505,7 +505,7 @@ mod tests {
next_poll_at_unix_secs: Some(200),
poll_count: 2,
max_poll_count: 360,
created_at_unix_secs: 150,
created_at_unix_ms: 150,
submitted_at_unix_secs: Some(150),
completed_at_unix_secs: None,
updated_at_unix_secs: 200,
@@ -590,7 +590,7 @@ mod tests {
model: Some("veo-3-fast".to_string()),
user_id: Some("user-2".to_string()),
client_api_format: Some("gemini:video".to_string()),
created_at_unix_secs: 250,
created_at_unix_ms: 250,
updated_at_unix_secs: 250,
..sample_task("task-2", VideoTaskStatus::Completed, 250)
})
@@ -600,7 +600,7 @@ mod tests {
model: Some("veo-3-fast".to_string()),
user_id: Some("user-2".to_string()),
client_api_format: Some("gemini:video".to_string()),
created_at_unix_secs: 260,
created_at_unix_ms: 260,
updated_at_unix_secs: 260,
..sample_task("task-3", VideoTaskStatus::Completed, 260)
})

View File

@@ -40,7 +40,7 @@ const SELECT_VIDEO_TASK_COLUMNS: &str = r#"
CAST(EXTRACT(EPOCH FROM next_poll_at) AS BIGINT) AS next_poll_at_unix_secs,
poll_count,
max_poll_count,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM submitted_at) AS BIGINT) AS submitted_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
@@ -599,7 +599,7 @@ impl SqlxVideoTaskRepository {
.bind(task.error_code)
.bind(task.error_message)
.bind(task.request_metadata)
.bind(task.created_at_unix_secs as f64)
.bind(task.created_at_unix_ms as f64)
.bind(task.submitted_at_unix_secs.map(|value| value as f64))
.bind(task.completed_at_unix_secs.map(|value| value as f64))
.bind(task.updated_at_unix_secs as f64)
@@ -668,7 +668,7 @@ impl SqlxVideoTaskRepository {
.bind(task.error_code)
.bind(task.error_message)
.bind(task.request_metadata)
.bind(task.created_at_unix_secs as f64)
.bind(task.created_at_unix_ms as f64)
.bind(task.submitted_at_unix_secs.map(|value| value as f64))
.bind(task.completed_at_unix_secs.map(|value| value as f64))
.bind(task.updated_at_unix_secs as f64)
@@ -917,7 +917,7 @@ fn map_video_task_row(row: &sqlx::postgres::PgRow) -> Result<StoredVideoTask, Da
row.try_get("next_poll_at_unix_secs").map_postgres_err()?,
row.try_get("poll_count").map_postgres_err()?,
row.try_get("max_poll_count").map_postgres_err()?,
row.try_get("created_at_unix_secs").map_postgres_err()?,
row.try_get("created_at_unix_ms").map_postgres_err()?,
row.try_get("submitted_at_unix_secs").map_postgres_err()?,
row.try_get("completed_at_unix_secs").map_postgres_err()?,
row.try_get("updated_at_unix_secs").map_postgres_err()?,
@@ -1017,7 +1017,7 @@ mod tests {
next_poll_at_unix_secs: Some(10),
poll_count: 0,
max_poll_count: 360,
created_at_unix_secs: 1,
created_at_unix_ms: 1,
submitted_at_unix_secs: Some(1),
completed_at_unix_secs: None,
updated_at_unix_secs: 1,
@@ -1065,7 +1065,7 @@ mod tests {
next_poll_at_unix_secs: Some(20),
poll_count: 1,
max_poll_count: 360,
created_at_unix_secs: 1,
created_at_unix_ms: 1,
submitted_at_unix_secs: Some(1),
completed_at_unix_secs: None,
updated_at_unix_secs: 20,

View File

@@ -146,7 +146,7 @@ impl WalletReadRepository for InMemoryWalletRepository {
total_adjusted: wallet.total_adjusted,
user_name: None,
api_key_name: None,
created_at_unix_secs: None,
created_at_unix_ms: None,
updated_at_unix_secs: Some(wallet.updated_at_unix_secs),
})
.collect::<Vec<_>>();
@@ -299,7 +299,7 @@ impl WalletWriteRepository for InMemoryWalletRepository {
gateway_order_id: Some(input.gateway_order_id),
gateway_response: Some(input.gateway_response),
status: "pending".to_string(),
created_at_unix_secs: 0,
created_at_unix_ms: 0,
paid_at_unix_secs: None,
credited_at_unix_secs: None,
expires_at_unix_secs: Some(input.expires_at_unix_secs),
@@ -343,7 +343,7 @@ impl WalletWriteRepository for InMemoryWalletRepository {
requested_by: None,
approved_by: None,
processed_by: None,
created_at_unix_secs: 0,
created_at_unix_ms: 0,
updated_at_unix_secs: 0,
processed_at_unix_secs: None,
completed_at_unix_secs: None,

View File

@@ -151,7 +151,7 @@ SELECT
CAST(w.total_adjusted AS DOUBLE PRECISION) AS total_adjusted,
users.username AS user_name,
api_keys.name AS api_key_name,
CAST(EXTRACT(EPOCH FROM w.created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM w.created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM w.updated_at) AS BIGINT) AS updated_at_unix_secs
FROM wallets w
LEFT JOIN users ON users.id = w.user_id
@@ -204,7 +204,7 @@ SELECT
api_keys.name AS api_key_name,
operator_users.username AS operator_name,
operator_users.email AS operator_email,
CAST(EXTRACT(EPOCH FROM tx.created_at) AS BIGINT) AS created_at_unix_secs
CAST(EXTRACT(EPOCH FROM tx.created_at) AS BIGINT) AS created_at_unix_ms
FROM wallet_transactions tx
JOIN wallets w ON w.id = tx.wallet_id
LEFT JOIN users wallet_users ON wallet_users.id = w.user_id
@@ -256,7 +256,7 @@ SELECT
w.status AS wallet_status,
wallet_users.username AS wallet_user_name,
api_keys.name AS api_key_name,
CAST(EXTRACT(EPOCH FROM rr.created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM rr.created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM rr.updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM rr.processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM rr.completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -296,7 +296,7 @@ SELECT
tx.description,
operator_users.username AS operator_name,
operator_users.email AS operator_email,
CAST(EXTRACT(EPOCH FROM tx.created_at) AS BIGINT) AS created_at_unix_secs
CAST(EXTRACT(EPOCH FROM tx.created_at) AS BIGINT) AS created_at_unix_ms
FROM wallet_transactions tx
LEFT JOIN users operator_users
ON operator_users.id = tx.operator_id
@@ -384,7 +384,7 @@ SELECT
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -426,7 +426,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -462,7 +462,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -496,7 +496,7 @@ SELECT
WHEN status = 'pending' AND expires_at IS NOT NULL AND expires_at < now() THEN 'expired'
ELSE status
END AS status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -526,7 +526,7 @@ SELECT
WHEN status = 'pending' AND expires_at IS NOT NULL AND expires_at < now() THEN 'expired'
ELSE status
END AS status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -557,7 +557,7 @@ SELECT
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -586,7 +586,7 @@ SELECT
status,
payload,
error_message,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs
FROM payment_callbacks
WHERE ($1::TEXT IS NULL OR payment_method = $1)
@@ -1110,7 +1110,7 @@ RETURNING
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -1307,7 +1307,7 @@ RETURNING
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -1357,7 +1357,7 @@ SELECT
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -1509,7 +1509,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -1541,7 +1541,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -1803,7 +1803,7 @@ RETURNING
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -2020,7 +2020,7 @@ VALUES (
operator_name: None,
operator_email: None,
description: Some(description),
created_at_unix_secs: Some(created_at),
created_at_unix_ms: Some(created_at),
},
)))
})
@@ -2238,7 +2238,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -2293,7 +2293,7 @@ SELECT
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -2434,7 +2434,7 @@ RETURNING
let wallet = map_wallet_row(&wallet_row)?;
let transaction_id = Uuid::new_v4().to_string();
let created_at_unix_secs = Utc::now().timestamp().max(0) as u64;
let created_at_unix_ms = Utc::now().timestamp().max(0) as u64;
sqlx::query(
r#"
INSERT INTO wallet_transactions (
@@ -2520,7 +2520,7 @@ RETURNING
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -2553,7 +2553,7 @@ RETURNING
operator_name: None,
operator_email: None,
description: Some("退款占款".to_string()),
created_at_unix_secs: Some(created_at_unix_secs),
created_at_unix_ms: Some(created_at_unix_ms),
},
)))
})
@@ -2622,7 +2622,7 @@ RETURNING
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -2680,7 +2680,7 @@ SELECT
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -2728,7 +2728,7 @@ RETURNING
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -2847,7 +2847,7 @@ RETURNING
let wallet = map_wallet_row(&wallet_row)?;
let transaction_id = Uuid::new_v4().to_string();
let created_at_unix_secs = Utc::now().timestamp().max(0) as u64;
let created_at_unix_ms = Utc::now().timestamp().max(0) as u64;
sqlx::query(
r#"
INSERT INTO wallet_transactions (
@@ -2948,7 +2948,7 @@ RETURNING
requested_by,
approved_by,
processed_by,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM updated_at) AS BIGINT) AS updated_at_unix_secs,
CAST(EXTRACT(EPOCH FROM processed_at) AS BIGINT) AS processed_at_unix_secs,
CAST(EXTRACT(EPOCH FROM completed_at) AS BIGINT) AS completed_at_unix_secs
@@ -2981,7 +2981,7 @@ RETURNING
operator_name: None,
operator_email: None,
description: Some("退款失败回补".to_string()),
created_at_unix_secs: Some(created_at_unix_secs),
created_at_unix_ms: Some(created_at_unix_ms),
}),
)))
})
@@ -3014,7 +3014,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -3077,7 +3077,7 @@ RETURNING
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -3122,7 +3122,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -3176,7 +3176,7 @@ RETURNING
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -3219,7 +3219,7 @@ SELECT
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -3412,7 +3412,7 @@ RETURNING
gateway_order_id,
gateway_response,
status,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_secs,
CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT) AS created_at_unix_ms,
CAST(EXTRACT(EPOCH FROM paid_at) AS BIGINT) AS paid_at_unix_secs,
CAST(EXTRACT(EPOCH FROM credited_at) AS BIGINT) AS credited_at_unix_secs,
CAST(EXTRACT(EPOCH FROM expires_at) AS BIGINT) AS expires_at_unix_secs
@@ -3574,8 +3574,8 @@ fn map_admin_wallet_list_item_row(
total_adjusted: row_get(row, "total_adjusted")?,
user_name: row_get(row, "user_name")?,
api_key_name: row_get(row, "api_key_name")?,
created_at_unix_secs: parse_optional_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_optional_timestamp(
row_get(row, "created_at_unix_ms")?,
"wallets.created_at",
)?,
updated_at_unix_secs: parse_optional_timestamp(
@@ -3611,8 +3611,8 @@ fn map_admin_wallet_ledger_item_row(
wallet_api_key_id: row_get(row, "api_key_id")?,
api_key_name: row_get(row, "api_key_name")?,
wallet_status: row_get(row, "wallet_status")?,
created_at_unix_secs: parse_optional_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_optional_timestamp(
row_get(row, "created_at_unix_ms")?,
"wallet_transactions.created_at",
)?,
})
@@ -3646,8 +3646,8 @@ fn map_admin_wallet_refund_request_item_row(
wallet_api_key_id: row_get(row, "wallet_api_key_id")?,
api_key_name: row_get(row, "api_key_name")?,
wallet_status: row_get(row, "wallet_status")?,
created_at_unix_secs: parse_optional_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_optional_timestamp(
row_get(row, "created_at_unix_ms")?,
"refund_requests.created_at",
)?,
updated_at_unix_secs: parse_optional_timestamp(
@@ -3686,8 +3686,8 @@ fn map_admin_wallet_transaction_row(
operator_name: row_get(row, "operator_name")?,
operator_email: row_get(row, "operator_email")?,
description: row_get(row, "description")?,
created_at_unix_secs: parse_optional_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_optional_timestamp(
row_get(row, "created_at_unix_ms")?,
"wallet_transactions.created_at",
)?,
})
@@ -3740,8 +3740,8 @@ fn map_admin_wallet_refund_row(row: &PgRow) -> Result<StoredAdminWalletRefund, D
requested_by: row_get(row, "requested_by")?,
approved_by: row_get(row, "approved_by")?,
processed_by: row_get(row, "processed_by")?,
created_at_unix_secs: parse_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_timestamp(
row_get(row, "created_at_unix_ms")?,
"refund_requests.created_at",
)?,
updated_at_unix_secs: parse_timestamp(
@@ -3774,8 +3774,8 @@ fn map_admin_payment_callback_row(
status: row_get(row, "status")?,
payload: row_get(row, "payload")?,
error_message: row_get(row, "error_message")?,
created_at_unix_secs: parse_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_timestamp(
row_get(row, "created_at_unix_ms")?,
"payment_callbacks.created_at",
)?,
processed_at_unix_secs: parse_optional_timestamp(
@@ -3801,8 +3801,8 @@ fn map_admin_payment_order_row(row: &PgRow) -> Result<StoredAdminPaymentOrder, D
gateway_order_id: row_get(row, "gateway_order_id")?,
gateway_response: row_get(row, "gateway_response")?,
status: row_get(row, "status")?,
created_at_unix_secs: parse_timestamp(
row_get(row, "created_at_unix_secs")?,
created_at_unix_ms: parse_timestamp(
row_get(row, "created_at_unix_ms")?,
"payment_orders.created_at",
)?,
paid_at_unix_secs: parse_optional_timestamp(

View File

@@ -118,7 +118,7 @@ pub struct StoredAdminWalletListItem {
pub total_adjusted: f64,
pub user_name: Option<String>,
pub api_key_name: Option<String>,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
pub updated_at_unix_secs: Option<u64>,
}
@@ -161,7 +161,7 @@ pub struct StoredAdminWalletLedgerItem {
pub wallet_api_key_id: Option<String>,
pub api_key_name: Option<String>,
pub wallet_status: String,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize)]
@@ -203,7 +203,7 @@ pub struct StoredAdminWalletRefundRequestItem {
pub wallet_api_key_id: Option<String>,
pub api_key_name: Option<String>,
pub wallet_status: String,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
pub updated_at_unix_secs: Option<u64>,
pub processed_at_unix_secs: Option<u64>,
pub completed_at_unix_secs: Option<u64>,
@@ -234,7 +234,7 @@ pub struct StoredAdminWalletTransaction {
pub operator_name: Option<String>,
pub operator_email: Option<String>,
pub description: Option<String>,
pub created_at_unix_secs: Option<u64>,
pub created_at_unix_ms: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
@@ -254,7 +254,7 @@ pub struct AdminWalletTransactionRecord {
pub link_id: Option<String>,
pub operator_id: Option<String>,
pub description: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
}
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize)]
@@ -306,7 +306,7 @@ pub struct StoredAdminWalletRefund {
pub requested_by: Option<String>,
pub approved_by: Option<String>,
pub processed_by: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub updated_at_unix_secs: u64,
pub processed_at_unix_secs: Option<u64>,
pub completed_at_unix_secs: Option<u64>,
@@ -333,7 +333,7 @@ pub struct AdminWalletRefundRecord {
pub requested_by: Option<String>,
pub approved_by: Option<String>,
pub processed_by: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub updated_at_unix_secs: u64,
pub processed_at_unix_secs: Option<u64>,
pub completed_at_unix_secs: Option<u64>,
@@ -369,7 +369,7 @@ pub struct StoredAdminPaymentOrder {
pub gateway_order_id: Option<String>,
pub gateway_response: Option<serde_json::Value>,
pub status: String,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub paid_at_unix_secs: Option<u64>,
pub credited_at_unix_secs: Option<u64>,
pub expires_at_unix_secs: Option<u64>,
@@ -391,7 +391,7 @@ pub struct AdminWalletPaymentOrderRecord {
pub gateway_order_id: Option<String>,
pub status: String,
pub gateway_response: Option<serde_json::Value>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub paid_at_unix_secs: Option<u64>,
pub credited_at_unix_secs: Option<u64>,
pub expires_at_unix_secs: Option<u64>,
@@ -416,7 +416,7 @@ pub struct StoredAdminPaymentCallback {
pub status: String,
pub payload: Option<serde_json::Value>,
pub error_message: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub processed_at_unix_secs: Option<u64>,
}
@@ -433,7 +433,7 @@ pub struct AdminPaymentCallbackRecord {
pub status: String,
pub payload: Option<serde_json::Value>,
pub error_message: Option<String>,
pub created_at_unix_secs: u64,
pub created_at_unix_ms: u64,
pub processed_at_unix_secs: Option<u64>,
}