Skip to main content

vti_common/idempotency/
class.rs

1//! [`IdempotencyClass`] — the op-class enum that drives cache TTL.
2
3use serde::{Deserialize, Serialize};
4
5/// Op class for an idempotent route, set explicitly at registration
6/// time (plan **D6**: clarity over cleverness; no heuristic on HTTP
7/// method).
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum IdempotencyClass {
10    /// Standard create / update / read. Cached for 24 h —
11    /// long retry window for offline-then-online clients.
12    NonDestructive,
13
14    /// Delete / revoke / destructive mutation. Cached for **60 s only**
15    /// so a network-flake retry returns the same outcome but a later
16    /// intentional re-creation under the same UUID isn't silently
17    /// no-op'd against a freshly-deleted target.
18    Destructive,
19}
20
21impl IdempotencyClass {
22    /// Cache lifetime in seconds. Pinned in code rather than config
23    /// to keep the semantic boundary between the two classes obvious
24    /// — operators don't tune it.
25    pub fn ttl_seconds(self) -> u64 {
26        match self {
27            Self::NonDestructive => 24 * 60 * 60,
28            Self::Destructive => 60,
29        }
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn non_destructive_caches_for_24_hours() {
39        assert_eq!(IdempotencyClass::NonDestructive.ttl_seconds(), 86_400);
40    }
41
42    #[test]
43    fn destructive_caches_for_60_seconds() {
44        assert_eq!(IdempotencyClass::Destructive.ttl_seconds(), 60);
45    }
46}