1use uuid::Uuid;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum ConnectivityMode {
5 AirGapped,
6 Online,
7 AlwaysOnline,
8}
9
10impl std::fmt::Display for ConnectivityMode {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 f.write_str(match self {
13 Self::AirGapped => "AirGapped",
14 Self::Online => "Online",
15 Self::AlwaysOnline => "AlwaysOnline",
16 })
17 }
18}
19
20impl std::str::FromStr for ConnectivityMode {
21 type Err = crate::Error;
22 fn from_str(s: &str) -> crate::Result<Self> {
23 match s {
24 "AirGapped" => Ok(Self::AirGapped),
25 "Online" => Ok(Self::Online),
26 "AlwaysOnline" => Ok(Self::AlwaysOnline),
27 _ => Err(crate::Error::Corrupt(format!(
28 "unknown ConnectivityMode: {s}"
29 ))),
30 }
31 }
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum TsaTier {
36 Free,
37 Standard,
38 Qualified,
39}
40
41impl std::fmt::Display for TsaTier {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 f.write_str(match self {
44 Self::Free => "Free",
45 Self::Standard => "Standard",
46 Self::Qualified => "Qualified",
47 })
48 }
49}
50
51impl std::str::FromStr for TsaTier {
52 type Err = crate::Error;
53 fn from_str(s: &str) -> crate::Result<Self> {
54 match s {
55 "Free" => Ok(Self::Free),
56 "Standard" => Ok(Self::Standard),
57 "Qualified" => Ok(Self::Qualified),
58 _ => Err(crate::Error::Corrupt(format!("unknown TsaTier: {s}"))),
59 }
60 }
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum TransferPolicy {
65 NotAvailable,
66 VendorApproval,
67}
68
69impl std::fmt::Display for TransferPolicy {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.write_str(match self {
72 Self::NotAvailable => "NotAvailable",
73 Self::VendorApproval => "VendorApproval",
74 })
75 }
76}
77
78impl std::str::FromStr for TransferPolicy {
79 type Err = crate::Error;
80 fn from_str(s: &str) -> crate::Result<Self> {
81 match s {
82 "NotAvailable" => Ok(Self::NotAvailable),
83 "VendorApproval" => Ok(Self::VendorApproval),
84 _ => Err(crate::Error::Corrupt(format!(
85 "unknown TransferPolicy: {s}"
86 ))),
87 }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub enum TermsValidationStatus {
93 Valid,
94 Warnings,
95 Conflicts,
96 PendingReview,
97}
98
99impl std::fmt::Display for TermsValidationStatus {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 f.write_str(match self {
102 Self::Valid => "Valid",
103 Self::Warnings => "Warnings",
104 Self::Conflicts => "Conflicts",
105 Self::PendingReview => "PendingReview",
106 })
107 }
108}
109
110impl std::str::FromStr for TermsValidationStatus {
111 type Err = crate::Error;
112 fn from_str(s: &str) -> crate::Result<Self> {
113 match s {
114 "Valid" => Ok(Self::Valid),
115 "Warnings" => Ok(Self::Warnings),
116 "Conflicts" => Ok(Self::Conflicts),
117 "PendingReview" => Ok(Self::PendingReview),
118 _ => Err(crate::Error::Corrupt(format!(
119 "unknown TermsValidationStatus: {s}"
120 ))),
121 }
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub enum LicenseStatus {
127 Active,
128 Revoked,
129 Superseded,
130}
131
132impl std::fmt::Display for LicenseStatus {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 f.write_str(match self {
135 Self::Active => "Active",
136 Self::Revoked => "Revoked",
137 Self::Superseded => "Superseded",
138 })
139 }
140}
141
142impl std::str::FromStr for LicenseStatus {
143 type Err = crate::Error;
144 fn from_str(s: &str) -> crate::Result<Self> {
145 match s {
146 "Active" => Ok(Self::Active),
147 "Revoked" => Ok(Self::Revoked),
148 "Superseded" => Ok(Self::Superseded),
149 _ => Err(crate::Error::Corrupt(format!("unknown LicenseStatus: {s}"))),
150 }
151 }
152}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq)]
155pub enum PaymentProvider {
156 Stripe,
157 Custom,
158}
159
160impl std::fmt::Display for PaymentProvider {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 f.write_str(match self {
163 Self::Stripe => "Stripe",
164 Self::Custom => "Custom",
165 })
166 }
167}
168
169impl std::str::FromStr for PaymentProvider {
170 type Err = crate::Error;
171 fn from_str(s: &str) -> crate::Result<Self> {
172 match s {
173 "Stripe" => Ok(Self::Stripe),
174 "Custom" => Ok(Self::Custom),
175 _ => Err(crate::Error::Corrupt(format!(
176 "unknown PaymentProvider: {s}"
177 ))),
178 }
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183pub enum PaymentStatus {
184 Pending,
185 Confirmed,
186 Failed,
187}
188
189impl std::fmt::Display for PaymentStatus {
190 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191 f.write_str(match self {
192 Self::Pending => "Pending",
193 Self::Confirmed => "Confirmed",
194 Self::Failed => "Failed",
195 })
196 }
197}
198
199impl std::str::FromStr for PaymentStatus {
200 type Err = crate::Error;
201 fn from_str(s: &str) -> crate::Result<Self> {
202 match s {
203 "Pending" => Ok(Self::Pending),
204 "Confirmed" => Ok(Self::Confirmed),
205 "Failed" => Ok(Self::Failed),
206 _ => Err(crate::Error::Corrupt(format!("unknown PaymentStatus: {s}"))),
207 }
208 }
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq)]
212pub enum ProviderTier {
213 Verified,
214 Pseudonymous,
215 Anonymous,
216}
217
218impl std::fmt::Display for ProviderTier {
219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 f.write_str(match self {
221 Self::Verified => "Verified",
222 Self::Pseudonymous => "Pseudonymous",
223 Self::Anonymous => "Anonymous",
224 })
225 }
226}
227
228impl std::str::FromStr for ProviderTier {
229 type Err = crate::Error;
230 fn from_str(s: &str) -> crate::Result<Self> {
231 match s {
232 "Verified" => Ok(Self::Verified),
233 "Pseudonymous" => Ok(Self::Pseudonymous),
234 "Anonymous" => Ok(Self::Anonymous),
235 _ => Err(crate::Error::Corrupt(format!("unknown ProviderTier: {s}"))),
236 }
237 }
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241pub enum TransferStatus {
242 Pending,
243 Approved,
244 Rejected,
245}
246
247impl std::fmt::Display for TransferStatus {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 f.write_str(match self {
250 Self::Pending => "Pending",
251 Self::Approved => "Approved",
252 Self::Rejected => "Rejected",
253 })
254 }
255}
256
257impl std::str::FromStr for TransferStatus {
258 type Err = crate::Error;
259 fn from_str(s: &str) -> crate::Result<Self> {
260 match s {
261 "Pending" => Ok(Self::Pending),
262 "Approved" => Ok(Self::Approved),
263 "Rejected" => Ok(Self::Rejected),
264 _ => Err(crate::Error::Corrupt(format!(
265 "unknown TransferStatus: {s}"
266 ))),
267 }
268 }
269}
270
271#[derive(Debug, Clone, Copy, PartialEq, Eq)]
272pub enum SessionStatus {
273 Active,
274 Suspect,
275 Quarantined,
276 Expired,
277 Terminated,
278}
279
280impl std::fmt::Display for SessionStatus {
281 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
282 f.write_str(match self {
283 Self::Active => "Active",
284 Self::Suspect => "Suspect",
285 Self::Quarantined => "Quarantined",
286 Self::Expired => "Expired",
287 Self::Terminated => "Terminated",
288 })
289 }
290}
291
292impl std::str::FromStr for SessionStatus {
293 type Err = crate::Error;
294 fn from_str(s: &str) -> crate::Result<Self> {
295 match s {
296 "Active" => Ok(Self::Active),
297 "Suspect" => Ok(Self::Suspect),
298 "Quarantined" => Ok(Self::Quarantined),
299 "Expired" => Ok(Self::Expired),
300 "Terminated" => Ok(Self::Terminated),
301 _ => Err(crate::Error::Corrupt(format!("unknown SessionStatus: {s}"))),
302 }
303 }
304}
305
306#[derive(Debug, Clone, Copy, PartialEq, Eq)]
307pub enum QuarantineTrigger {
308 MissedHeartbeat,
309 SecurityEvent,
310 VendorAction,
311}
312
313impl std::fmt::Display for QuarantineTrigger {
314 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
315 f.write_str(match self {
316 Self::MissedHeartbeat => "MissedHeartbeat",
317 Self::SecurityEvent => "SecurityEvent",
318 Self::VendorAction => "VendorAction",
319 })
320 }
321}
322
323impl std::str::FromStr for QuarantineTrigger {
324 type Err = crate::Error;
325 fn from_str(s: &str) -> crate::Result<Self> {
326 match s {
327 "MissedHeartbeat" => Ok(Self::MissedHeartbeat),
328 "SecurityEvent" => Ok(Self::SecurityEvent),
329 "VendorAction" => Ok(Self::VendorAction),
330 _ => Err(crate::Error::Corrupt(format!(
331 "unknown QuarantineTrigger: {s}"
332 ))),
333 }
334 }
335}
336
337#[derive(Debug, Clone, Copy, PartialEq, Eq)]
338pub enum QuarantineStatus {
339 Active,
340 Resolved,
341}
342
343impl std::fmt::Display for QuarantineStatus {
344 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
345 f.write_str(match self {
346 Self::Active => "Active",
347 Self::Resolved => "Resolved",
348 })
349 }
350}
351
352impl std::str::FromStr for QuarantineStatus {
353 type Err = crate::Error;
354 fn from_str(s: &str) -> crate::Result<Self> {
355 match s {
356 "Active" => Ok(Self::Active),
357 "Resolved" => Ok(Self::Resolved),
358 _ => Err(crate::Error::Corrupt(format!(
359 "unknown QuarantineStatus: {s}"
360 ))),
361 }
362 }
363}
364
365#[derive(Debug, Clone, Copy, PartialEq, Eq)]
366pub enum SecurityEventSeverity {
367 Info,
368 Warning,
369 Critical,
370}
371
372impl std::fmt::Display for SecurityEventSeverity {
373 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
374 f.write_str(match self {
375 Self::Info => "Info",
376 Self::Warning => "Warning",
377 Self::Critical => "Critical",
378 })
379 }
380}
381
382impl std::str::FromStr for SecurityEventSeverity {
383 type Err = crate::Error;
384 fn from_str(s: &str) -> crate::Result<Self> {
385 match s {
386 "Info" => Ok(Self::Info),
387 "Warning" => Ok(Self::Warning),
388 "Critical" => Ok(Self::Critical),
389 _ => Err(crate::Error::Corrupt(format!(
390 "unknown SecurityEventSeverity: {s}"
391 ))),
392 }
393 }
394}
395
396#[derive(Debug, Clone, Copy, PartialEq, Eq)]
397pub enum SecurityEventResponse {
398 Log,
399 Warn,
400 Quarantine,
401 Terminate,
402}
403
404impl std::fmt::Display for SecurityEventResponse {
405 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
406 f.write_str(match self {
407 Self::Log => "Log",
408 Self::Warn => "Warn",
409 Self::Quarantine => "Quarantine",
410 Self::Terminate => "Terminate",
411 })
412 }
413}
414
415impl std::str::FromStr for SecurityEventResponse {
416 type Err = crate::Error;
417 fn from_str(s: &str) -> crate::Result<Self> {
418 match s {
419 "Log" => Ok(Self::Log),
420 "Warn" => Ok(Self::Warn),
421 "Quarantine" => Ok(Self::Quarantine),
422 "Terminate" => Ok(Self::Terminate),
423 _ => Err(crate::Error::Corrupt(format!(
424 "unknown SecurityEventResponse: {s}"
425 ))),
426 }
427 }
428}
429
430#[derive(Debug, Clone, Copy, PartialEq, Eq)]
431pub enum RevocationSource {
432 VendorDashboard,
433 Api,
434}
435
436impl std::fmt::Display for RevocationSource {
437 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
438 f.write_str(match self {
439 Self::VendorDashboard => "VendorDashboard",
440 Self::Api => "API",
441 })
442 }
443}
444
445impl std::str::FromStr for RevocationSource {
446 type Err = crate::Error;
447 fn from_str(s: &str) -> crate::Result<Self> {
448 match s {
449 "VendorDashboard" => Ok(Self::VendorDashboard),
450 "API" => Ok(Self::Api),
451 _ => Err(crate::Error::Corrupt(format!(
452 "unknown RevocationSource: {s}"
453 ))),
454 }
455 }
456}
457
458#[derive(Debug, Clone, Copy, PartialEq, Eq)]
459pub enum GdprBasis {
460 Contract,
461 LegalObligation,
462 LegitimateInterest,
463}
464
465impl std::fmt::Display for GdprBasis {
466 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
467 f.write_str(match self {
468 Self::Contract => "Contract",
469 Self::LegalObligation => "LegalObligation",
470 Self::LegitimateInterest => "LegitimateInterest",
471 })
472 }
473}
474
475impl std::str::FromStr for GdprBasis {
476 type Err = crate::Error;
477 fn from_str(s: &str) -> crate::Result<Self> {
478 match s {
479 "Contract" => Ok(Self::Contract),
480 "LegalObligation" => Ok(Self::LegalObligation),
481 "LegitimateInterest" => Ok(Self::LegitimateInterest),
482 _ => Err(crate::Error::Corrupt(format!("unknown GdprBasis: {s}"))),
483 }
484 }
485}
486
487#[derive(Debug, Clone, Copy, PartialEq, Eq)]
488pub enum UpgradePolicy {
489 AutoApprove,
490 RequireNewPurchase,
491 FreeUpgrade,
492}
493
494impl std::fmt::Display for UpgradePolicy {
495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
496 f.write_str(match self {
497 Self::AutoApprove => "AutoApprove",
498 Self::RequireNewPurchase => "RequireNewPurchase",
499 Self::FreeUpgrade => "FreeUpgrade",
500 })
501 }
502}
503
504impl std::str::FromStr for UpgradePolicy {
505 type Err = crate::Error;
506 fn from_str(s: &str) -> crate::Result<Self> {
507 match s {
508 "AutoApprove" => Ok(Self::AutoApprove),
509 "RequireNewPurchase" => Ok(Self::RequireNewPurchase),
510 "FreeUpgrade" => Ok(Self::FreeUpgrade),
511 _ => Err(crate::Error::Corrupt(format!("unknown UpgradePolicy: {s}"))),
512 }
513 }
514}
515
516#[derive(Debug, Clone, Copy, PartialEq, Eq)]
517pub enum EmailType {
518 GrantConfirmation,
519}
520
521impl std::fmt::Display for EmailType {
522 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523 f.write_str(match self {
524 Self::GrantConfirmation => "GrantConfirmation",
525 })
526 }
527}
528
529impl std::str::FromStr for EmailType {
530 type Err = crate::Error;
531 fn from_str(s: &str) -> crate::Result<Self> {
532 match s {
533 "GrantConfirmation" => Ok(Self::GrantConfirmation),
534 _ => Err(crate::Error::Corrupt(format!("unknown EmailType: {s}"))),
535 }
536 }
537}
538
539#[derive(Debug, Clone, PartialEq)]
540pub struct VendorConfig {
541 pub id: i64,
542 pub public_key: Vec<u8>,
543 pub public_key_fingerprint: String,
544 pub registered_at: i64,
545 pub rotated_from_key: Option<Vec<u8>>,
546 pub rotated_at: Option<i64>,
547}
548
549#[derive(Debug, Clone, PartialEq)]
550pub struct Product {
551 pub id: Uuid,
552 pub name: String,
553 pub description: String,
554 pub connectivity_mode: ConnectivityMode,
555 pub seat_count: i64,
556 pub expiry_policy: String,
557 pub grace_period_days: Option<i64>,
558 pub heartbeat_interval_secs: Option<i64>,
559 pub heartbeat_grace_secs: Option<i64>,
560 pub shutdown_countdown_secs: Option<i64>,
561 pub tsa_tier: TsaTier,
562 pub bundle_version: String,
563 pub transfer_policy: TransferPolicy,
564 pub pricing_amount: i64,
565 pub pricing_currency: String,
566 pub payment_provider: PaymentProvider,
567 pub min_client_version_warning: Option<String>,
568 pub min_client_version_required: Option<String>,
569 pub active: bool,
570 pub created_at: i64,
571 pub updated_at: i64,
572}
573
574#[derive(Debug, Clone, PartialEq)]
575pub struct ProductTermDeclaration {
576 pub product_id: Uuid,
577 pub warranty: String,
578 pub refund: String,
579 pub revocation: String,
580 pub expiry: String,
581 pub support_available: bool,
582 pub support_channels: String,
583 pub response_sla_hours: Option<i64>,
584 pub support_scope: Option<String>,
585 pub support_coverage: Option<String>,
586 pub updates_policy: String,
587}
588
589#[derive(Debug, Clone, PartialEq)]
590pub struct ProductTermsDocument {
591 pub id: Uuid,
592 pub product_id: Uuid,
593 pub typst_source: String,
594 pub rendered_hash: String,
595 pub validation_status: TermsValidationStatus,
596 pub validation_findings: String,
597 pub vendor_acknowledged_at: Option<i64>,
598 pub vendor_acknowledged_findings: Option<String>,
599 pub activated_at: Option<i64>,
600 pub created_at: i64,
601}
602
603#[derive(Debug, Clone, PartialEq)]
604pub struct ProductCustomerField {
605 pub id: Uuid,
606 pub product_id: Uuid,
607 pub field_key: String,
608 pub required: bool,
609 pub gdpr_basis: GdprBasis,
610}
611
612#[derive(Debug, Clone, PartialEq)]
613pub struct UpgradePolicyRow {
614 pub id: Uuid,
615 pub product_id: Uuid,
616 pub from_version: String,
617 pub to_version: String,
618 pub policy: UpgradePolicy,
619}
620
621#[derive(Debug, Clone, PartialEq)]
622pub struct Customer {
623 pub id: Uuid,
624 pub product_id: Uuid,
625 pub full_name: String,
626 pub email: String,
627 pub field_values: String,
628 pub created_at: i64,
629 pub updated_at: i64,
630}
631
632#[derive(Debug, Clone, PartialEq)]
633pub struct ConsentRecord {
634 pub id: Uuid,
635 pub customer_id: Uuid,
636 pub license_id: Uuid,
637 pub terms_document_id: Uuid,
638 pub terms_rendered_hash: String,
639 pub checkboxes_ticked: String,
640 pub accepted_at_ns: i64,
641 pub ip_address: String,
642 pub client_version: String,
643 pub protocol_version: i64,
644 pub terms_findings_shown: String,
645 pub payment_provider: PaymentProvider,
646 pub payment_provider_tier: ProviderTier,
647}
648
649#[derive(Debug, Clone, PartialEq)]
650pub struct License {
651 pub id: Uuid,
652 pub customer_id: Uuid,
653 pub product_id: Uuid,
654 pub bundle_version: String,
655 pub connectivity_mode: ConnectivityMode,
656 pub seat_count: i64,
657 pub expiry_at: Option<i64>,
658 pub status: LicenseStatus,
659 pub superseded_by: Option<Uuid>,
660 pub revoked_at: Option<i64>,
661 pub revocation_reason: Option<String>,
662 pub created_at: i64,
663 pub email_sent_at: Option<i64>,
664}
665
666#[derive(Debug, Clone, PartialEq)]
667pub struct FingerprintSeatBinding {
668 pub id: Uuid,
669 pub license_id: Uuid,
670 pub fingerprint_commitment: Vec<u8>,
671 pub seat_index: i64,
672 pub bound_at: i64,
673 pub last_verified_at: Option<i64>,
674 pub revoked_at: Option<i64>,
675 pub transfer_pending_at: Option<i64>,
676}
677
678#[derive(Debug, Clone, PartialEq)]
679pub struct IssuanceSecret {
680 pub license_id: Uuid,
681 pub secret: Vec<u8>,
682 pub created_at: i64,
683}
684
685#[derive(Debug, Clone, PartialEq)]
686pub struct PaymentTransaction {
687 pub id: Uuid,
688 pub license_id: Uuid,
689 pub provider: PaymentProvider,
690 pub provider_transaction_id: String,
691 pub amount: i64,
692 pub currency: String,
693 pub provider_tier: ProviderTier,
694 pub test_mode: bool,
695 pub status: PaymentStatus,
696 pub created_at: i64,
697 pub confirmed_at: Option<i64>,
698}
699
700#[derive(Debug, Clone, PartialEq)]
701pub struct TransferRequest {
702 pub id: Uuid,
703 pub license_id: Uuid,
704 pub old_fingerprint_commitment: Vec<u8>,
705 pub new_fingerprint_commitment: Vec<u8>,
706 pub requested_at: i64,
707 pub status: TransferStatus,
708 pub vendor_note: Option<String>,
709 pub resolved_at: Option<i64>,
710}
711
712#[derive(Debug, Clone, PartialEq)]
713pub struct ActiveSession {
714 pub id: Uuid,
715 pub binding_id: Uuid,
716 pub ephemeral_pubkey: Vec<u8>,
717 pub issued_at: i64,
718 pub expires_at: i64,
719 pub last_heartbeat_at: Option<i64>,
720 pub seq_no: i64,
721 pub status: SessionStatus,
722}
723
724#[derive(Debug, Clone, PartialEq)]
725pub struct QuarantineCase {
726 pub id: Uuid,
727 pub case_id: Uuid,
728 pub binding_id: Uuid,
729 pub session_id: Option<Uuid>,
730 pub trigger: QuarantineTrigger,
731 pub triggered_at: i64,
732 pub status: QuarantineStatus,
733 pub resolution: Option<String>,
734 pub resolved_at: Option<i64>,
735 pub vendor_note: Option<String>,
736}
737
738#[derive(Debug, Clone, PartialEq)]
739pub struct SecurityEvent {
740 pub id: i64,
741 pub event_id: Uuid,
742 pub license_id: Uuid,
743 pub binding_id: Uuid,
744 pub session_id: Option<Uuid>,
745 pub occurred_at_ns: i64,
746 pub received_at_ns: i64,
747 pub event_type: String,
748 pub severity: SecurityEventSeverity,
749 pub payload: String,
750 pub response: SecurityEventResponse,
751 pub reviewed_by: Option<String>,
752 pub reviewed_at: Option<i64>,
753 pub case_id: Option<Uuid>,
754}
755
756#[derive(Debug, Clone, PartialEq)]
757pub struct RevocationRecord {
758 pub license_id: Uuid,
759 pub revoked_at: i64,
760 pub revoked_by: RevocationSource,
761 pub reason: Option<String>,
762}
763
764#[derive(Debug, Clone, PartialEq)]
765pub struct EmailLogEntry {
766 pub id: Uuid,
767 pub license_id: Uuid,
768 pub email_type: EmailType,
769 pub sent_to: String,
770 pub sent_at: i64,
771 pub success: bool,
772 pub error_message: Option<String>,
773}
774
775#[derive(Debug, Clone, Copy, PartialEq, Eq)]
776pub enum EnrollmentState {
777 OfferPending,
778 ReceiptPending,
779 PaymentHeld,
780 TSAPending,
781 GrantReady,
782 Issued,
783 Abandoned,
784}
785
786impl std::fmt::Display for EnrollmentState {
787 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
788 f.write_str(match self {
789 Self::OfferPending => "OfferPending",
790 Self::ReceiptPending => "ReceiptPending",
791 Self::PaymentHeld => "PaymentHeld",
792 Self::TSAPending => "TSAPending",
793 Self::GrantReady => "GrantReady",
794 Self::Issued => "Issued",
795 Self::Abandoned => "Abandoned",
796 })
797 }
798}
799
800impl std::str::FromStr for EnrollmentState {
801 type Err = crate::Error;
802 fn from_str(s: &str) -> crate::Result<Self> {
803 match s {
804 "OfferPending" => Ok(Self::OfferPending),
805 "ReceiptPending" => Ok(Self::ReceiptPending),
806 "PaymentHeld" => Ok(Self::PaymentHeld),
807 "TSAPending" => Ok(Self::TSAPending),
808 "GrantReady" => Ok(Self::GrantReady),
809 "Issued" => Ok(Self::Issued),
810 "Abandoned" => Ok(Self::Abandoned),
811 _ => Err(crate::Error::Corrupt(format!(
812 "unknown EnrollmentState: {s}"
813 ))),
814 }
815 }
816}
817
818#[derive(Debug, Clone, PartialEq)]
819pub struct EnrollmentSession {
820 pub id: Uuid,
821 pub product_id: Uuid,
822 pub fingerprint_commitment: Vec<u8>,
823 pub customer_pubkey: Vec<u8>,
824 pub client_version: String,
825 pub protocol_version: i64,
826 pub state: EnrollmentState,
827 pub offer_nonce: Option<Vec<u8>>,
828 pub offer_expires_at: Option<i64>,
829 pub terms_document_id: Option<Uuid>,
830 pub request_bytes: Vec<u8>,
831 pub offer_bytes: Option<Vec<u8>>,
832 pub receipt_bytes: Option<Vec<u8>>,
833 pub payment_intent_id: Option<String>,
834 pub payment_captured: bool,
835 pub grant_bytes: Option<Vec<u8>>,
836 pub transfer_request_id: Option<Uuid>,
837 pub license_id: Option<Uuid>,
838 pub abandon_reason: Option<String>,
839 pub created_at: i64,
840 pub updated_at: i64,
841}
842
843#[derive(Default)]
844pub struct EnrollmentSessionUpdate {
845 pub state: Option<EnrollmentState>,
846 pub receipt_bytes: Option<Vec<u8>>,
847 pub payment_intent_id: Option<String>,
848 pub payment_captured: Option<bool>,
849 pub grant_bytes: Option<Vec<u8>>,
850 pub license_id: Option<Option<Uuid>>,
851 pub abandon_reason: Option<String>,
852 pub updated_at: i64,
853}
854
855pub mod abandon_reason {
856 pub const OFFER_EXPIRED: &str = "OfferExpired";
857 pub const PAYMENT_FAILED: &str = "PaymentFailed";
858 pub const TSA_FAILED: &str = "TsaFailed";
859 pub const CAPTURE_FAILED: &str = "CaptureFailed";
860}