Skip to main content

bes_canopy_api/
generated.rs

1// @generated by canopy-api-codegen from crates/public-server/openapi.json.
2// Run `just gen-api` to refresh; do not edit by hand.
3
4/// Version of the OpenAPI document this source was generated from, which is also
5/// this crate's own version.
6pub const OPENAPI_VERSION: &str = "1.0.0";
7
8/// BLAKE3 digest of that document, so a document that changed without the
9/// version moving with it can be told from one that did not.
10pub const OPENAPI_BLAKE3: &str = "3bd62c232a727651fbe22f9a0be57d3f80eb1b48694f68d3f56db903df9276b4";
11
12/// Error types.
13pub mod error {
14    /// Error from a `TryFrom` or `FromStr` implementation.
15    pub struct ConversionError(::std::borrow::Cow<'static, str>);
16    impl ::std::error::Error for ConversionError {}
17    impl ::std::fmt::Display for ConversionError {
18        fn fmt(
19            &self,
20            f: &mut ::std::fmt::Formatter<'_>,
21        ) -> Result<(), ::std::fmt::Error> {
22            ::std::fmt::Display::fmt(&self.0, f)
23        }
24    }
25    impl ::std::fmt::Debug for ConversionError {
26        fn fmt(
27            &self,
28            f: &mut ::std::fmt::Formatter<'_>,
29        ) -> Result<(), ::std::fmt::Error> {
30            ::std::fmt::Debug::fmt(&self.0, f)
31        }
32    }
33    impl From<&'static str> for ConversionError {
34        fn from(value: &'static str) -> Self {
35            Self(value.into())
36        }
37    }
38    impl From<String> for ConversionError {
39        fn from(value: String) -> Self {
40            Self(value.into())
41        }
42    }
43}
44///What one application on the asking machine may act on.
45///
46/// <details><summary>JSON schema</summary>
47///
48/// ```json
49///{
50///  "description": "What one application on the asking machine may act on.",
51///  "type": "object",
52///  "required": [
53///    "certificates",
54///    "domains",
55///    "may_manage_dns",
56///    "may_manage_tls",
57///    "paused",
58///    "registered_names",
59///    "type"
60///  ],
61///  "properties": {
62///    "certificates": {
63///      "description": "The certificates Canopy holds for it.",
64///      "type": "array",
65///      "items": {
66///        "$ref": "#/components/schemas/HeldCertificate"
67///      }
68///    },
69///    "domains": {
70///      "description": "The domains its group controls.",
71///      "type": "array",
72///      "items": {
73///        "type": "string"
74///      }
75///    },
76///    "may_manage_dns": {
77///      "description": "Whether this application may manage its own DNS records.",
78///      "type": "boolean"
79///    },
80///    "may_manage_tls": {
81///      "description": "Whether this application may obtain its own TLS certificates.",
82///      "type": "boolean"
83///    },
84///    "paused": {
85///      "description": "Whether Canopy is currently making no new changes on its behalf.",
86///      "type": "boolean"
87///    },
88///    "registered_names": {
89///      "description": "The names it has registered addresses for.",
90///      "type": "array",
91///      "items": {
92///        "type": "string"
93///      }
94///    },
95///    "type": {
96///      "description": "The type of application these entitlements belong to.\n\nA reporter correlates an entry to a workload it runs by the machine it\nasked as and this type. Canopy's own identifier for the application is\ninternal and never on the wire.",
97///      "$ref": "#/components/schemas/ApplicationType"
98///    }
99///  }
100///}
101/// ```
102/// </details>
103#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
104#[derive(::bon::Builder)]
105#[non_exhaustive]
106pub struct ApplicationEntitlements {
107    ///The certificates Canopy holds for it.
108    pub certificates: ::std::vec::Vec<HeldCertificate>,
109    ///The domains its group controls.
110    pub domains: ::std::vec::Vec<::std::string::String>,
111    ///Whether this application may manage its own DNS records.
112    pub may_manage_dns: bool,
113    ///Whether this application may obtain its own TLS certificates.
114    pub may_manage_tls: bool,
115    ///Whether Canopy is currently making no new changes on its behalf.
116    pub paused: bool,
117    ///The names it has registered addresses for.
118    pub registered_names: ::std::vec::Vec<::std::string::String>,
119    /**The type of application these entitlements belong to.
120
121A reporter correlates an entry to a workload it runs by the machine it
122asked as and this type. Canopy's own identifier for the application is
123internal and never on the wire.*/
124    #[serde(rename = "type")]
125    pub type_: ApplicationType,
126}
127///One application within a push, as the reporter found it.
128///
129/// <details><summary>JSON schema</summary>
130///
131/// ```json
132///{
133///  "description": "One application within a push, as the reporter found it.",
134///  "type": "object",
135///  "required": [
136///    "detail",
137///    "type"
138///  ],
139///  "properties": {
140///    "detail": {
141///      "description": "Everything the reporter has to say about this application beyond its\nchecks, including its `tamanuVersion`.",
142///      "type": "object"
143///    },
144///    "health": {
145///      "description": "This application's checks. Reported bare; Canopy qualifies them with\nthe application's type when cataloguing them.",
146///      "type": [
147///        "array",
148///        "null"
149///      ],
150///      "items": {
151///        "$ref": "#/components/schemas/HealthCheck"
152///      }
153///    },
154///    "type": {
155///      "description": "What this application is: the software and the role it plays together,\nfor example `tamanu-central`. Required, and part of how Canopy\ncorrelates the report to its own record — a different type under a key\nalready in use means the reporter has stopped reporting one application\nand started reporting another.",
156///      "type": "string"
157///    }
158///  }
159///}
160/// ```
161/// </details>
162#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
163#[derive(::bon::Builder)]
164#[non_exhaustive]
165pub struct ApplicationReport {
166    /**Everything the reporter has to say about this application beyond its
167checks, including its `tamanuVersion`.*/
168    pub detail: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
169    /**This application's checks. Reported bare; Canopy qualifies them with
170the application's type when cataloguing them.*/
171    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
172    pub health: ::std::option::Option<::std::vec::Vec<HealthCheck>>,
173    /**What this application is: the software and the role it plays together,
174for example `tamanu-central`. Required, and part of how Canopy
175correlates the report to its own record — a different type under a key
176already in use means the reporter has stopped reporting one application
177and started reporting another.*/
178    #[serde(rename = "type")]
179    pub type_: ::std::string::String,
180}
181///What an application is: the software and the role it plays, as a slug. The set is open — a report carrying a type Canopy does not know creates an application of that type, which simply carries no per-type capabilities.
182///
183/// <details><summary>JSON schema</summary>
184///
185/// ```json
186///{
187///  "description": "What an application is: the software and the role it plays, as a slug. The set is open — a report carrying a type Canopy does not know creates an application of that type, which simply carries no per-type capabilities.",
188///  "examples": [
189///    "tamanu-central"
190///  ],
191///  "type": "string"
192///}
193/// ```
194/// </details>
195#[derive(
196    ::serde::Deserialize,
197    ::serde::Serialize,
198    Clone,
199    Debug,
200    Eq,
201    Hash,
202    Ord,
203    PartialEq,
204    PartialOrd
205)]
206#[serde(transparent)]
207pub struct ApplicationType(pub ::std::string::String);
208impl ::std::ops::Deref for ApplicationType {
209    type Target = ::std::string::String;
210    fn deref(&self) -> &::std::string::String {
211        &self.0
212    }
213}
214impl ::std::convert::From<ApplicationType> for ::std::string::String {
215    fn from(value: ApplicationType) -> Self {
216        value.0
217    }
218}
219impl ::std::convert::From<::std::string::String> for ApplicationType {
220    fn from(value: ::std::string::String) -> Self {
221        Self(value)
222    }
223}
224impl ::std::str::FromStr for ApplicationType {
225    type Err = ::std::convert::Infallible;
226    fn from_str(value: &str) -> ::std::result::Result<Self, Self::Err> {
227        Ok(Self(value.to_string()))
228    }
229}
230impl ::std::fmt::Display for ApplicationType {
231    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
232        self.0.fmt(f)
233    }
234}
235/**A downloadable artifact belonging to a release version: an installer,
236package, or other file published for a given type and platform.*/
237///
238/// <details><summary>JSON schema</summary>
239///
240/// ```json
241///{
242///  "description": "A downloadable artifact belonging to a release version: an installer,\npackage, or other file published for a given type and platform.",
243///  "type": "object",
244///  "required": [
245///    "artifact_type",
246///    "download_url",
247///    "id",
248///    "platform"
249///  ],
250///  "properties": {
251///    "artifact_type": {
252///      "description": "What kind of artifact this is (e.g. an installer or package name).",
253///      "type": "string"
254///    },
255///    "device_id": {
256///      "description": "The device that registered this artifact, if it was registered by a\nreleaser device rather than created by an operator.",
257///      "type": [
258///        "string",
259///        "null"
260///      ],
261///      "format": "uuid"
262///    },
263///    "download_url": {
264///      "description": "URL the artifact can be downloaded from.",
265///      "type": "string"
266///    },
267///    "id": {
268///      "description": "Unique identifier of the artifact.",
269///      "type": "string",
270///      "format": "uuid"
271///    },
272///    "platform": {
273///      "description": "The platform the artifact targets (e.g. an OS or architecture name).",
274///      "type": "string"
275///    },
276///    "version_id": {
277///      "description": "The exact version this artifact belongs to. `null` for range\nartifacts, which apply to every version matching\n`version_range_pattern` instead.",
278///      "type": [
279///        "string",
280///        "null"
281///      ],
282///      "format": "uuid"
283///    },
284///    "version_range_pattern": {
285///      "description": "Semver range this artifact applies to (e.g. `^2.10.0`), for artifacts\nshared across a range of versions rather than pinned to one. `null`\nfor exact-version artifacts.",
286///      "type": [
287///        "string",
288///        "null"
289///      ]
290///    }
291///  }
292///}
293/// ```
294/// </details>
295#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
296#[derive(::bon::Builder)]
297#[non_exhaustive]
298pub struct Artifact {
299    ///What kind of artifact this is (e.g. an installer or package name).
300    pub artifact_type: ::std::string::String,
301    /**The device that registered this artifact, if it was registered by a
302releaser device rather than created by an operator.*/
303    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
304    pub device_id: ::std::option::Option<::uuid::Uuid>,
305    ///URL the artifact can be downloaded from.
306    pub download_url: ::std::string::String,
307    ///Unique identifier of the artifact.
308    pub id: ::uuid::Uuid,
309    ///The platform the artifact targets (e.g. an OS or architecture name).
310    pub platform: ::std::string::String,
311    /**The exact version this artifact belongs to. `null` for range
312artifacts, which apply to every version matching
313`version_range_pattern` instead.*/
314    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
315    pub version_id: ::std::option::Option<::uuid::Uuid>,
316    /**Semver range this artifact applies to (e.g. `^2.10.0`), for artifacts
317shared across a range of versions rather than pinned to one. `null`
318for exact-version artifacts.*/
319    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
320    pub version_range_pattern: ::std::option::Option<::std::string::String>,
321}
322///`BTreeMap`
323///
324/// <details><summary>JSON schema</summary>
325///
326/// ```json
327///{
328///  "type": "object",
329///  "additionalProperties": {
330///    "description": "Describes one configurable parameter that a replica of a restore intent\naccepts.",
331///    "type": "object",
332///    "required": [
333///      "type"
334///    ],
335///    "properties": {
336///      "default": {
337///        "description": "The value used when the parameter is left unset. `None` means an\nunset parameter is sent as JSON `null` rather than a default value."
338///      },
339///      "type": {
340///        "description": "The parameter's data type, which determines how its value is\nvalidated.",
341///        "$ref": "#/components/schemas/ParamType"
342///      }
343///    }
344///  },
345///  "propertyNames": {
346///    "type": "string"
347///  }
348///}
349/// ```
350/// </details>
351#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
352#[serde(transparent)]
353pub struct BTreeMap(
354    pub ::std::collections::HashMap<::std::string::String, BTreeMapValue>,
355);
356impl ::std::ops::Deref for BTreeMap {
357    type Target = ::std::collections::HashMap<::std::string::String, BTreeMapValue>;
358    fn deref(
359        &self,
360    ) -> &::std::collections::HashMap<::std::string::String, BTreeMapValue> {
361        &self.0
362    }
363}
364impl ::std::convert::From<BTreeMap>
365for ::std::collections::HashMap<::std::string::String, BTreeMapValue> {
366    fn from(value: BTreeMap) -> Self {
367        value.0
368    }
369}
370impl ::std::convert::From<
371    ::std::collections::HashMap<::std::string::String, BTreeMapValue>,
372> for BTreeMap {
373    fn from(
374        value: ::std::collections::HashMap<::std::string::String, BTreeMapValue>,
375    ) -> Self {
376        Self(value)
377    }
378}
379/**Describes one configurable parameter that a replica of a restore intent
380accepts.*/
381///
382/// <details><summary>JSON schema</summary>
383///
384/// ```json
385///{
386///  "description": "Describes one configurable parameter that a replica of a restore intent\naccepts.",
387///  "type": "object",
388///  "required": [
389///    "type"
390///  ],
391///  "properties": {
392///    "default": {
393///      "description": "The value used when the parameter is left unset. `None` means an\nunset parameter is sent as JSON `null` rather than a default value."
394///    },
395///    "type": {
396///      "description": "The parameter's data type, which determines how its value is\nvalidated.",
397///      "$ref": "#/components/schemas/ParamType"
398///    }
399///  }
400///}
401/// ```
402/// </details>
403#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
404#[derive(::bon::Builder)]
405#[non_exhaustive]
406pub struct BTreeMapValue {
407    /**The value used when the parameter is left unset. `None` means an
408unset parameter is sent as JSON `null` rather than a default value.*/
409    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
410    pub default: ::std::option::Option<::serde_json::Value>,
411    /**The parameter's data type, which determines how its value is
412validated.*/
413    #[serde(rename = "type")]
414    pub type_: ParamType,
415}
416///Request body for registering the backup types a server can run.
417///
418/// <details><summary>JSON schema</summary>
419///
420/// ```json
421///{
422///  "description": "Request body for registering the backup types a server can run.",
423///  "type": "object",
424///  "required": [
425///    "types"
426///  ],
427///  "properties": {
428///    "types": {
429///      "description": "The backup types this server is able to run. Each type is a plain\nstring (e.g. `tamanu-postgres`); custom type names are accepted.",
430///      "type": "array",
431///      "items": {
432///        "type": "string"
433///      }
434///    }
435///  }
436///}
437/// ```
438/// </details>
439#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
440#[derive(::bon::Builder)]
441#[non_exhaustive]
442pub struct BackupCapabilitiesArgs {
443    /**The backup types this server is able to run. Each type is a plain
444string (e.g. `tamanu-postgres`); custom type names are accepted.*/
445    pub types: ::std::vec::Vec<::std::string::String>,
446}
447/**Request body for minting short-lived S3 credentials for a backup or
448restore run.*/
449///
450/// <details><summary>JSON schema</summary>
451///
452/// ```json
453///{
454///  "description": "Request body for minting short-lived S3 credentials for a backup or\nrestore run.",
455///  "type": "object",
456///  "required": [
457///    "type"
458///  ],
459///  "properties": {
460///    "purpose": {
461///      "description": "What the credentials will be used for. `backup` (the default) grants\nwrite access for uploading backups; `restore` grants strictly read-only\naccess. Either way the credentials are scoped to the group's backup\nstorage only.",
462///      "$ref": "#/components/schemas/BackupPurpose"
463///    },
464///    "run_id": {
465///      "description": "This must be the run-uuid the client minted for this run.\nThe field is optional only so older clients don't break; it WILL be made\nmandatory in future.",
466///      "type": [
467///        "string",
468///        "null"
469///      ],
470///      "format": "uuid"
471///    },
472///    "type": {
473///      "description": "The backup type the credentials are for (e.g. `tamanu-postgres`). For a\n`backup`, the type must be an enabled capability of this server or the\nsubject of a pending \"backup now\" request; for a `restore`, the server's\nrestore window must be open (an operator allows restores for it in\ncanopy). Otherwise the request is rejected with 409.",
474///      "type": "string"
475///    }
476///  }
477///}
478/// ```
479/// </details>
480#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
481#[derive(::bon::Builder)]
482#[non_exhaustive]
483pub struct BackupCredentialsArgs {
484    /**What the credentials will be used for. `backup` (the default) grants
485write access for uploading backups; `restore` grants strictly read-only
486access. Either way the credentials are scoped to the group's backup
487storage only.*/
488    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
489    pub purpose: ::std::option::Option<BackupPurpose>,
490    /**This must be the run-uuid the client minted for this run.
491The field is optional only so older clients don't break; it WILL be made
492mandatory in future.*/
493    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
494    pub run_id: ::std::option::Option<::uuid::Uuid>,
495    /**The backup type the credentials are for (e.g. `tamanu-postgres`). For a
496`backup`, the type must be an enabled capability of this server or the
497subject of a pending "backup now" request; for a `restore`, the server's
498restore window must be open (an operator allows restores for it in
499canopy). Otherwise the request is rejected with 409.*/
500    #[serde(rename = "type")]
501    pub type_: ::std::string::String,
502}
503/**Why a backup credential was issued, or what a reported run was for.
504Determines the access the credential grants: a `backup` credential can
505write new data but not delete existing data, while a `restore`
506credential is read-only.*/
507///
508/// <details><summary>JSON schema</summary>
509///
510/// ```json
511///{
512///  "description": "Why a backup credential was issued, or what a reported run was for.\nDetermines the access the credential grants: a `backup` credential can\nwrite new data but not delete existing data, while a `restore`\ncredential is read-only.",
513///  "type": "string",
514///  "enum": [
515///    "backup",
516///    "restore"
517///  ]
518///}
519/// ```
520/// </details>
521#[derive(
522    ::serde::Deserialize,
523    ::serde::Serialize,
524    Clone,
525    Copy,
526    Debug,
527    Eq,
528    Hash,
529    Ord,
530    PartialEq,
531    PartialOrd
532)]
533pub enum BackupPurpose {
534    #[serde(rename = "backup")]
535    Backup,
536    #[serde(rename = "restore")]
537    Restore,
538}
539impl ::std::fmt::Display for BackupPurpose {
540    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
541        match *self {
542            Self::Backup => f.write_str("backup"),
543            Self::Restore => f.write_str("restore"),
544        }
545    }
546}
547impl ::std::str::FromStr for BackupPurpose {
548    type Err = self::error::ConversionError;
549    fn from_str(
550        value: &str,
551    ) -> ::std::result::Result<Self, self::error::ConversionError> {
552        match value {
553            "backup" => Ok(Self::Backup),
554            "restore" => Ok(Self::Restore),
555            _ => Err("invalid value".into()),
556        }
557    }
558}
559impl ::std::convert::TryFrom<&str> for BackupPurpose {
560    type Error = self::error::ConversionError;
561    fn try_from(
562        value: &str,
563    ) -> ::std::result::Result<Self, self::error::ConversionError> {
564        value.parse()
565    }
566}
567impl ::std::convert::TryFrom<&::std::string::String> for BackupPurpose {
568    type Error = self::error::ConversionError;
569    fn try_from(
570        value: &::std::string::String,
571    ) -> ::std::result::Result<Self, self::error::ConversionError> {
572        value.parse()
573    }
574}
575impl ::std::convert::TryFrom<::std::string::String> for BackupPurpose {
576    type Error = self::error::ConversionError;
577    fn try_from(
578        value: ::std::string::String,
579    ) -> ::std::result::Result<Self, self::error::ConversionError> {
580        value.parse()
581    }
582}
583/**The backup storage target for the calling server's group: where the backup
584repository lives and the passphrase to open it.*/
585///
586/// <details><summary>JSON schema</summary>
587///
588/// ```json
589///{
590///  "description": "The backup storage target for the calling server's group: where the backup\nrepository lives and the passphrase to open it.",
591///  "type": "object",
592///  "required": [
593///    "bucket",
594///    "prefix",
595///    "region",
596///    "repo_password",
597///    "storage"
598///  ],
599///  "properties": {
600///    "bucket": {
601///      "description": "Name of the S3 bucket holding the group's backup repository.",
602///      "type": "string"
603///    },
604///    "prefix": {
605///      "description": "Key prefix within the bucket under which the repository lives. Normally\nempty (the repository is at the bucket root).",
606///      "type": "string"
607///    },
608///    "region": {
609///      "description": "AWS region of the bucket.",
610///      "type": "string"
611///    },
612///    "repo_password": {
613///      "description": "Passphrase for the group's backup repository (a Kopia repository).",
614///      "$ref": "#/definitions/CanopySecret"
615///    },
616///    "storage": {
617///      "description": "Kind of storage backend. Always `\"s3\"`.",
618///      "type": "string"
619///    }
620///  }
621///}
622/// ```
623/// </details>
624#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
625#[derive(::bon::Builder)]
626#[non_exhaustive]
627pub struct BackupTarget {
628    ///Name of the S3 bucket holding the group's backup repository.
629    pub bucket: ::std::string::String,
630    /**Key prefix within the bucket under which the repository lives. Normally
631empty (the repository is at the bucket root).*/
632    pub prefix: ::std::string::String,
633    ///AWS region of the bucket.
634    pub region: ::std::string::String,
635    ///Passphrase for the group's backup repository (a Kopia repository).
636    pub repo_password: crate::Redacted<::std::string::String>,
637    ///Kind of storage backend. Always `"s3"`.
638    pub storage: ::std::string::String,
639}
640///Request to start device enrollment against a machine.
641///
642/// <details><summary>JSON schema</summary>
643///
644/// ```json
645///{
646///  "description": "Request to start device enrollment against a machine.",
647///  "type": "object",
648///  "required": [
649///    "server_id",
650///    "token"
651///  ],
652///  "properties": {
653///    "server_id": {
654///      "description": "ID of the machine to enroll against. Named `server_id` because that is\nthe name fielded agents send; the value has always identified the box.",
655///      "type": "string",
656///      "format": "uuid"
657///    },
658///    "spki": {
659///      "description": "Base64-standard-encoded DER SubjectPublicKeyInfo (SPKI) of the\ndevice's public key. Only required when enrolling over a transport\nwith no client certificate to read the key from (e.g. over\nTailscale); omit it when enrolling over mTLS, where the key is\ntaken from the presented client certificate. The returned challenge\nis bound to this key, so the same value must be supplied again when\ncompleting enrollment.",
660///      "type": [
661///        "string",
662///        "null"
663///      ]
664///    },
665///    "token": {
666///      "description": "The enrollment token issued by an operator for this machine.",
667///      "type": "string"
668///    }
669///  }
670///}
671/// ```
672/// </details>
673#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
674#[derive(::bon::Builder)]
675#[non_exhaustive]
676pub struct BeginArgs {
677    /**ID of the machine to enroll against. Named `server_id` because that is
678the name fielded agents send; the value has always identified the box.*/
679    pub server_id: ::uuid::Uuid,
680    /**Base64-standard-encoded DER SubjectPublicKeyInfo (SPKI) of the
681device's public key. Only required when enrolling over a transport
682with no client certificate to read the key from (e.g. over
683Tailscale); omit it when enrolling over mTLS, where the key is
684taken from the presented client certificate. The returned challenge
685is bound to this key, so the same value must be supplied again when
686completing enrollment.*/
687    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
688    pub spki: ::std::option::Option<::std::string::String>,
689    ///The enrollment token issued by an operator for this machine.
690    pub token: ::std::string::String,
691}
692///A freshly-issued enrollment challenge to sign and return.
693///
694/// <details><summary>JSON schema</summary>
695///
696/// ```json
697///{
698///  "description": "A freshly-issued enrollment challenge to sign and return.",
699///  "type": "object",
700///  "required": [
701///    "channel_binding_required",
702///    "nonce"
703///  ],
704///  "properties": {
705///    "channel_binding_required": {
706///      "description": "True if the server requires channel-binding data (the connection's\nTLS exported keying material) to be folded into the signed\ntranscript. Only relevant when enrolling over mTLS; it never\napplies on a transport without TLS channel binding.",
707///      "type": "boolean"
708///    },
709///    "nonce": {
710///      "description": "Base64-standard-encoded 32-byte challenge nonce. Sign it, together\nwith the machine ID, device public key, and channel-binding data if\nrequired, and submit the signature when completing enrollment.",
711///      "type": "string"
712///    }
713///  }
714///}
715/// ```
716/// </details>
717#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
718#[derive(::bon::Builder)]
719#[non_exhaustive]
720pub struct BeginResponse {
721    /**True if the server requires channel-binding data (the connection's
722TLS exported keying material) to be folded into the signed
723transcript. Only relevant when enrolling over mTLS; it never
724applies on a transport without TLS channel binding.*/
725    pub channel_binding_required: bool,
726    /**Base64-standard-encoded 32-byte challenge nonce. Sign it, together
727with the machine ID, device public key, and channel-binding data if
728required, and submit the signature when completing enrollment.*/
729    pub nonce: ::std::string::String,
730}
731///Where a certificate request stands, and the chain once there is one.
732///
733/// <details><summary>JSON schema</summary>
734///
735/// ```json
736///{
737///  "description": "Where a certificate request stands, and the chain once there is one.",
738///  "type": "object",
739///  "required": [
740///    "key_must_be_replaced",
741///    "name",
742///    "revoked",
743///    "state",
744///    "usable"
745///  ],
746///  "properties": {
747///    "chain": {
748///      "description": "The chain, PEM, once Canopy holds one — including while a renewal is\nunder way, the chain in hand staying valid until the new one lands.",
749///      "type": [
750///        "string",
751///        "null"
752///      ]
753///    },
754///    "key_must_be_replaced": {
755///      "description": "Whether the key must be replaced before asking again, rather than just the\ncertificate.",
756///      "type": "boolean"
757///    },
758///    "last_error": {
759///      "description": "Why the last attempt failed, if one did. Present while Canopy is still\nretrying.",
760///      "type": [
761///        "string",
762///        "null"
763///      ]
764///    },
765///    "name": {
766///      "description": "The name the certificate is (or will be) for, as Canopy normalised it.",
767///      "type": "string"
768///    },
769///    "not_after": {
770///      "description": "When it expires.",
771///      "type": [
772///        "string",
773///        "null"
774///      ]
775///    },
776///    "profile": {
777///      "description": "The profile it was issued under, if the authority named one.",
778///      "type": [
779///        "string",
780///        "null"
781///      ]
782///    },
783///    "revoked": {
784///      "description": "Whether an operator revoked it. Stop serving it and ask again.",
785///      "type": "boolean"
786///    },
787///    "state": {
788///      "description": "`pending`, `issued`, `failed`, or `revoked`.",
789///      "type": "string"
790///    },
791///    "usable": {
792///      "description": "Whether the chain can be served now.",
793///      "type": "boolean"
794///    }
795///  }
796///}
797/// ```
798/// </details>
799#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
800#[derive(::bon::Builder)]
801#[non_exhaustive]
802pub struct CertificateResponse {
803    /**The chain, PEM, once Canopy holds one — including while a renewal is
804under way, the chain in hand staying valid until the new one lands.*/
805    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
806    pub chain: ::std::option::Option<::std::string::String>,
807    /**Whether the key must be replaced before asking again, rather than just the
808certificate.*/
809    pub key_must_be_replaced: bool,
810    /**Why the last attempt failed, if one did. Present while Canopy is still
811retrying.*/
812    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
813    pub last_error: ::std::option::Option<::std::string::String>,
814    ///The name the certificate is (or will be) for, as Canopy normalised it.
815    pub name: ::std::string::String,
816    ///When it expires.
817    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
818    pub not_after: ::std::option::Option<::std::string::String>,
819    ///The profile it was issued under, if the authority named one.
820    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
821    pub profile: ::std::option::Option<::std::string::String>,
822    ///Whether an operator revoked it. Stop serving it and ask again.
823    pub revoked: bool,
824    ///`pending`, `issued`, `failed`, or `revoked`.
825    pub state: ::std::string::String,
826    ///Whether the chain can be served now.
827    pub usable: bool,
828}
829/**Outcome of a single health check reported in a server's status update.
830
831Older reports may send a plain pass/fail flag instead of one of these
832outcomes; when that happens a passing flag is treated as `passed` and a
833failing flag as `failed`.*/
834///
835/// <details><summary>JSON schema</summary>
836///
837/// ```json
838///{
839///  "description": "Outcome of a single health check reported in a server's status update.\n\nOlder reports may send a plain pass/fail flag instead of one of these\noutcomes; when that happens a passing flag is treated as `passed` and a\nfailing flag as `failed`.",
840///  "type": "string",
841///  "enum": [
842///    "passed",
843///    "warning",
844///    "failed",
845///    "broken",
846///    "skipped"
847///  ]
848///}
849/// ```
850/// </details>
851#[derive(
852    ::serde::Deserialize,
853    ::serde::Serialize,
854    Clone,
855    Copy,
856    Debug,
857    Eq,
858    Hash,
859    Ord,
860    PartialEq,
861    PartialOrd
862)]
863pub enum CheckResult {
864    #[serde(rename = "passed")]
865    Passed,
866    #[serde(rename = "warning")]
867    Warning,
868    #[serde(rename = "failed")]
869    Failed,
870    #[serde(rename = "broken")]
871    Broken,
872    #[serde(rename = "skipped")]
873    Skipped,
874}
875impl ::std::fmt::Display for CheckResult {
876    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
877        match *self {
878            Self::Passed => f.write_str("passed"),
879            Self::Warning => f.write_str("warning"),
880            Self::Failed => f.write_str("failed"),
881            Self::Broken => f.write_str("broken"),
882            Self::Skipped => f.write_str("skipped"),
883        }
884    }
885}
886impl ::std::str::FromStr for CheckResult {
887    type Err = self::error::ConversionError;
888    fn from_str(
889        value: &str,
890    ) -> ::std::result::Result<Self, self::error::ConversionError> {
891        match value {
892            "passed" => Ok(Self::Passed),
893            "warning" => Ok(Self::Warning),
894            "failed" => Ok(Self::Failed),
895            "broken" => Ok(Self::Broken),
896            "skipped" => Ok(Self::Skipped),
897            _ => Err("invalid value".into()),
898        }
899    }
900}
901impl ::std::convert::TryFrom<&str> for CheckResult {
902    type Error = self::error::ConversionError;
903    fn try_from(
904        value: &str,
905    ) -> ::std::result::Result<Self, self::error::ConversionError> {
906        value.parse()
907    }
908}
909impl ::std::convert::TryFrom<&::std::string::String> for CheckResult {
910    type Error = self::error::ConversionError;
911    fn try_from(
912        value: &::std::string::String,
913    ) -> ::std::result::Result<Self, self::error::ConversionError> {
914        value.parse()
915    }
916}
917impl ::std::convert::TryFrom<::std::string::String> for CheckResult {
918    type Error = self::error::ConversionError;
919    fn try_from(
920        value: ::std::string::String,
921    ) -> ::std::result::Result<Self, self::error::ConversionError> {
922        value.parse()
923    }
924}
925/**How a server should treat one of its healthchecks, distilled from
926canopy's operator-side configuration (the policy catalog and the
927silences) into a three-level device-facing vocabulary.*/
928///
929/// <details><summary>JSON schema</summary>
930///
931/// ```json
932///{
933///  "description": "How a server should treat one of its healthchecks, distilled from\ncanopy's operator-side configuration (the policy catalog and the\nsilences) into a three-level device-facing vocabulary.",
934///  "type": "string",
935///  "enum": [
936///    "skip",
937///    "warn",
938///    "fail"
939///  ]
940///}
941/// ```
942/// </details>
943#[derive(
944    ::serde::Deserialize,
945    ::serde::Serialize,
946    Clone,
947    Copy,
948    Debug,
949    Eq,
950    Hash,
951    Ord,
952    PartialEq,
953    PartialOrd
954)]
955pub enum CheckSeverity {
956    #[serde(rename = "skip")]
957    Skip,
958    #[serde(rename = "warn")]
959    Warn,
960    #[serde(rename = "fail")]
961    Fail,
962}
963impl ::std::fmt::Display for CheckSeverity {
964    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
965        match *self {
966            Self::Skip => f.write_str("skip"),
967            Self::Warn => f.write_str("warn"),
968            Self::Fail => f.write_str("fail"),
969        }
970    }
971}
972impl ::std::str::FromStr for CheckSeverity {
973    type Err = self::error::ConversionError;
974    fn from_str(
975        value: &str,
976    ) -> ::std::result::Result<Self, self::error::ConversionError> {
977        match value {
978            "skip" => Ok(Self::Skip),
979            "warn" => Ok(Self::Warn),
980            "fail" => Ok(Self::Fail),
981            _ => Err("invalid value".into()),
982        }
983    }
984}
985impl ::std::convert::TryFrom<&str> for CheckSeverity {
986    type Error = self::error::ConversionError;
987    fn try_from(
988        value: &str,
989    ) -> ::std::result::Result<Self, self::error::ConversionError> {
990        value.parse()
991    }
992}
993impl ::std::convert::TryFrom<&::std::string::String> for CheckSeverity {
994    type Error = self::error::ConversionError;
995    fn try_from(
996        value: &::std::string::String,
997    ) -> ::std::result::Result<Self, self::error::ConversionError> {
998        value.parse()
999    }
1000}
1001impl ::std::convert::TryFrom<::std::string::String> for CheckSeverity {
1002    type Error = self::error::ConversionError;
1003    fn try_from(
1004        value: ::std::string::String,
1005    ) -> ::std::result::Result<Self, self::error::ConversionError> {
1006        value.parse()
1007    }
1008}
1009/**Request to complete device enrollment by presenting a signed
1010challenge obtained from the start-enrollment endpoint.*/
1011///
1012/// <details><summary>JSON schema</summary>
1013///
1014/// ```json
1015///{
1016///  "description": "Request to complete device enrollment by presenting a signed\nchallenge obtained from the start-enrollment endpoint.",
1017///  "type": "object",
1018///  "required": [
1019///    "nonce",
1020///    "server_id",
1021///    "signature"
1022///  ],
1023///  "properties": {
1024///    "nonce": {
1025///      "description": "Base64-standard-encoded challenge nonce returned when enrollment\nwas started.",
1026///      "type": "string"
1027///    },
1028///    "server_id": {
1029///      "description": "ID of the machine being enrolled. Must match the value used when\nstarting enrollment.",
1030///      "type": "string",
1031///      "format": "uuid"
1032///    },
1033///    "signature": {
1034///      "description": "Base64-standard-encoded ASN.1 DER ECDSA (P-256, SHA-256) signature\nover the challenge transcript, proving possession of the device's\nprivate key. The transcript is the byte concatenation of: the raw\nchallenge nonce, the raw 16 bytes of the machine ID, the DER SPKI of\nthe device public key, and — only when channel binding was flagged\nas required — the connection's TLS exported keying material.",
1035///      "type": "string"
1036///    },
1037///    "spki": {
1038///      "description": "Base64-standard-encoded DER SPKI of the device's public key. Only\nrequired when enrolling over a transport with no client\ncertificate to read the key from; must match the key used when\nenrollment was started.",
1039///      "type": [
1040///        "string",
1041///        "null"
1042///      ]
1043///    }
1044///  }
1045///}
1046/// ```
1047/// </details>
1048#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1049#[derive(::bon::Builder)]
1050#[non_exhaustive]
1051pub struct CompleteArgs {
1052    /**Base64-standard-encoded challenge nonce returned when enrollment
1053was started.*/
1054    pub nonce: ::std::string::String,
1055    /**ID of the machine being enrolled. Must match the value used when
1056starting enrollment.*/
1057    pub server_id: ::uuid::Uuid,
1058    /**Base64-standard-encoded ASN.1 DER ECDSA (P-256, SHA-256) signature
1059over the challenge transcript, proving possession of the device's
1060private key. The transcript is the byte concatenation of: the raw
1061challenge nonce, the raw 16 bytes of the machine ID, the DER SPKI of
1062the device public key, and — only when channel binding was flagged
1063as required — the connection's TLS exported keying material.*/
1064    pub signature: ::std::string::String,
1065    /**Base64-standard-encoded DER SPKI of the device's public key. Only
1066required when enrolling over a transport with no client
1067certificate to read the key from; must match the key used when
1068enrollment was started.*/
1069    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1070    pub spki: ::std::option::Option<::std::string::String>,
1071}
1072///Result of a successful enrollment.
1073///
1074/// <details><summary>JSON schema</summary>
1075///
1076/// ```json
1077///{
1078///  "description": "Result of a successful enrollment.",
1079///  "type": "object",
1080///  "required": [
1081///    "device_id",
1082///    "server_id"
1083///  ],
1084///  "properties": {
1085///    "device_id": {
1086///      "description": "The device identity created or reused for this enrollment. The\ndevice authenticates as this ID from now on.",
1087///      "type": "string",
1088///      "format": "uuid"
1089///    },
1090///    "server_id": {
1091///      "description": "The machine the device is now enrolled against.",
1092///      "type": "string",
1093///      "format": "uuid"
1094///    }
1095///  }
1096///}
1097/// ```
1098/// </details>
1099#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1100#[derive(::bon::Builder)]
1101#[non_exhaustive]
1102pub struct CompleteResponse {
1103    /**The device identity created or reused for this enrollment. The
1104device authenticates as this ID from now on.*/
1105    pub device_id: ::uuid::Uuid,
1106    ///The machine the device is now enrolled against.
1107    pub server_id: ::uuid::Uuid,
1108}
1109/**Short-lived AWS credentials in the AWS `credential_process` output format,
1110so they can be consumed directly by AWS SDKs and tools. Field names use the
1111exact casing (`Version`, `AccessKeyId`, ...) that format requires.*/
1112///
1113/// <details><summary>JSON schema</summary>
1114///
1115/// ```json
1116///{
1117///  "description": "Short-lived AWS credentials in the AWS `credential_process` output format,\nso they can be consumed directly by AWS SDKs and tools. Field names use the\nexact casing (`Version`, `AccessKeyId`, ...) that format requires.",
1118///  "type": "object",
1119///  "required": [
1120///    "AccessKeyId",
1121///    "Expiration",
1122///    "SecretAccessKey",
1123///    "SessionToken",
1124///    "Version"
1125///  ],
1126///  "properties": {
1127///    "AccessKeyId": {
1128///      "description": "The temporary AWS access key ID.",
1129///      "type": "string"
1130///    },
1131///    "Expiration": {
1132///      "description": "When the credentials expire, as an RFC 3339 / ISO 8601 UTC instant.\nCredentials last at most one hour; request a fresh set per run.",
1133///      "$ref": "#/definitions/CanopyTimestamp"
1134///    },
1135///    "SecretAccessKey": {
1136///      "description": "The temporary AWS secret access key.",
1137///      "$ref": "#/definitions/CanopySecret"
1138///    },
1139///    "SessionToken": {
1140///      "description": "The session token that must accompany the temporary key pair.",
1141///      "$ref": "#/definitions/CanopySecret"
1142///    },
1143///    "Version": {
1144///      "description": "Version of the `credential_process` format. Always the literal `1`.",
1145///      "type": "integer",
1146///      "format": "int32",
1147///      "minimum": 0.0
1148///    }
1149///  }
1150///}
1151/// ```
1152/// </details>
1153#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1154#[derive(::bon::Builder)]
1155#[non_exhaustive]
1156pub struct CredentialProcessOutput {
1157    ///The temporary AWS access key ID.
1158    #[serde(rename = "AccessKeyId")]
1159    pub access_key_id: ::std::string::String,
1160    /**When the credentials expire, as an RFC 3339 / ISO 8601 UTC instant.
1161Credentials last at most one hour; request a fresh set per run.*/
1162    #[serde(rename = "Expiration")]
1163    pub expiration: ::jiff::Timestamp,
1164    ///The temporary AWS secret access key.
1165    #[serde(rename = "SecretAccessKey")]
1166    pub secret_access_key: crate::Redacted<::std::string::String>,
1167    ///The session token that must accompany the temporary key pair.
1168    #[serde(rename = "SessionToken")]
1169    pub session_token: crate::Redacted<::std::string::String>,
1170    ///Version of the `credential_process` format. Always the literal `1`.
1171    #[serde(rename = "Version")]
1172    pub version: i32,
1173}
1174///What a server is entitled to do with names, and what it already holds.
1175///
1176/// <details><summary>JSON schema</summary>
1177///
1178/// ```json
1179///{
1180///  "description": "What a server is entitled to do with names, and what it already holds.",
1181///  "type": "object",
1182///  "required": [
1183///    "certificates",
1184///    "domains",
1185///    "may_manage_dns",
1186///    "may_manage_tls",
1187///    "paused",
1188///    "registered_names"
1189///  ],
1190///  "properties": {
1191///    "applications": {
1192///      "description": "One entry per application on the asking machine.\n\nAn identity belongs to a machine, so an agent asks on behalf of the box\nand gets an answer for every workload on it. The flat fields above\ndescribe a single-application machine, which is every machine today;\non a machine hosting several they are left at their defaults and this\nlist is the answer.",
1193///      "type": "array",
1194///      "items": {
1195///        "$ref": "#/components/schemas/ApplicationEntitlements"
1196///      }
1197///    },
1198///    "certificates": {
1199///      "description": "The certificates Canopy holds for this server.",
1200///      "type": "array",
1201///      "items": {
1202///        "$ref": "#/components/schemas/HeldCertificate"
1203///      }
1204///    },
1205///    "domains": {
1206///      "description": "The domains this server's group controls. Any name at or beneath one of\nthese is a name this server may act on — which is what lets an agent\nrequest a certificate before anything asks for one.",
1207///      "type": "array",
1208///      "items": {
1209///        "type": "string"
1210///      }
1211///    },
1212///    "may_manage_dns": {
1213///      "description": "Whether this server may manage its own DNS records.",
1214///      "type": "boolean"
1215///    },
1216///    "may_manage_tls": {
1217///      "description": "Whether this server may obtain its own TLS certificates.",
1218///      "type": "boolean"
1219///    },
1220///    "paused": {
1221///      "description": "Whether Canopy is currently making no new changes on this server's\nbehalf. While true, requests are refused and an agent should wait.",
1222///      "type": "boolean"
1223///    },
1224///    "registered_names": {
1225///      "description": "The names this server has registered addresses for.",
1226///      "type": "array",
1227///      "items": {
1228///        "type": "string"
1229///      }
1230///    }
1231///  }
1232///}
1233/// ```
1234/// </details>
1235#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1236#[derive(::bon::Builder)]
1237#[non_exhaustive]
1238pub struct Entitlements {
1239    /**One entry per application on the asking machine.
1240
1241An identity belongs to a machine, so an agent asks on behalf of the box
1242and gets an answer for every workload on it. The flat fields above
1243describe a single-application machine, which is every machine today;
1244on a machine hosting several they are left at their defaults and this
1245list is the answer.*/
1246    #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
1247    pub applications: ::std::vec::Vec<ApplicationEntitlements>,
1248    ///The certificates Canopy holds for this server.
1249    pub certificates: ::std::vec::Vec<HeldCertificate>,
1250    /**The domains this server's group controls. Any name at or beneath one of
1251these is a name this server may act on — which is what lets an agent
1252request a certificate before anything asks for one.*/
1253    pub domains: ::std::vec::Vec<::std::string::String>,
1254    ///Whether this server may manage its own DNS records.
1255    pub may_manage_dns: bool,
1256    ///Whether this server may obtain its own TLS certificates.
1257    pub may_manage_tls: bool,
1258    /**Whether Canopy is currently making no new changes on this server's
1259behalf. While true, requests are refused and an agent should wait.*/
1260    pub paused: bool,
1261    ///The names this server has registered addresses for.
1262    pub registered_names: ::std::vec::Vec<::std::string::String>,
1263}
1264///One health-check result within a status push.
1265///
1266/// <details><summary>JSON schema</summary>
1267///
1268/// ```json
1269///{
1270///  "description": "One health-check result within a status push.",
1271///  "type": "object",
1272///  "required": [
1273///    "check"
1274///  ],
1275///  "properties": {
1276///    "check": {
1277///      "description": "Name of the check. Must be a non-empty string, and should stay stable\nacross pushes: results for the same name are correlated over time, so\nsuccessive failures and the eventual recovery land on the same issue.",
1278///      "type": "string"
1279///    },
1280///    "healthy": {
1281///      "description": "Legacy pass/fail form: `true` means `passed`, `false` means `failed`.\nMutually exclusive with `result`.",
1282///      "type": [
1283///        "boolean",
1284///        "null"
1285///      ]
1286///    },
1287///    "result": {
1288///      "oneOf": [
1289///        {
1290///          "type": "null"
1291///        },
1292///        {
1293///          "description": "Outcome of the check: `passed`, `warning`, `failed`, `broken`, or\n`skipped`. Exactly one of `result` / `healthy` must be present per\nentry. `warning` and `failed` open the check's issue as graded by\nits policy; `broken` (the check itself errored, not the system under\ntest) neither confirms nor clears a known failure — the issue stays\nopen, retaining its contribution; `skipped` (a precondition was\nnot met) and `passed` open nothing and close prior issues.",
1294///          "$ref": "#/components/schemas/CheckResult"
1295///        }
1296///      ]
1297///    }
1298///  },
1299///  "additionalProperties": true
1300///}
1301/// ```
1302/// </details>
1303#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1304#[derive(::bon::Builder)]
1305#[non_exhaustive]
1306pub struct HealthCheck {
1307    /**Name of the check. Must be a non-empty string, and should stay stable
1308across pushes: results for the same name are correlated over time, so
1309successive failures and the eventual recovery land on the same issue.*/
1310    pub check: ::std::string::String,
1311    /**Legacy pass/fail form: `true` means `passed`, `false` means `failed`.
1312Mutually exclusive with `result`.*/
1313    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1314    pub healthy: ::std::option::Option<bool>,
1315    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1316    pub result: ::std::option::Option<CheckResult>,
1317    /// Any further keys the schema accepts alongside those above,
1318    /// carried verbatim.
1319    #[serde(flatten)]
1320    #[builder(default)]
1321    pub extra: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
1322}
1323/**A certificate Canopy holds for the asking server, as the server needs to see
1324it: enough to decide whether to renew, and nothing about anyone else.*/
1325///
1326/// <details><summary>JSON schema</summary>
1327///
1328/// ```json
1329///{
1330///  "description": "A certificate Canopy holds for the asking server, as the server needs to see\nit: enough to decide whether to renew, and nothing about anyone else.",
1331///  "type": "object",
1332///  "required": [
1333///    "key_fingerprint",
1334///    "key_must_be_replaced",
1335///    "name",
1336///    "revoked",
1337///    "usable"
1338///  ],
1339///  "properties": {
1340///    "key_fingerprint": {
1341///      "description": "Hex SHA-256 of the certified key's subject public key info, so an agent\ncan tell whether this covers a key it still holds.",
1342///      "type": "string"
1343///    },
1344///    "key_must_be_replaced": {
1345///      "description": "Whether the key itself is condemned, not just the certificate — the key\npair has to be replaced before asking again.",
1346///      "type": "boolean"
1347///    },
1348///    "name": {
1349///      "description": "The name it covers.",
1350///      "type": "string"
1351///    },
1352///    "not_after": {
1353///      "description": "When it expires.",
1354///      "type": [
1355///        "string",
1356///        "null"
1357///      ]
1358///    },
1359///    "profile": {
1360///      "description": "The profile it was issued under, if the authority named one.",
1361///      "type": [
1362///        "string",
1363///        "null"
1364///      ]
1365///    },
1366///    "revoked": {
1367///      "description": "Whether an operator has revoked it. Stop serving it.",
1368///      "type": "boolean"
1369///    },
1370///    "usable": {
1371///      "description": "Whether it can still be served: not revoked, not expired. True even while\na renewal is under way, the chain in hand staying valid until the new one\nlands.",
1372///      "type": "boolean"
1373///    }
1374///  }
1375///}
1376/// ```
1377/// </details>
1378#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1379#[derive(::bon::Builder)]
1380#[non_exhaustive]
1381pub struct HeldCertificate {
1382    /**Hex SHA-256 of the certified key's subject public key info, so an agent
1383can tell whether this covers a key it still holds.*/
1384    pub key_fingerprint: ::std::string::String,
1385    /**Whether the key itself is condemned, not just the certificate — the key
1386pair has to be replaced before asking again.*/
1387    pub key_must_be_replaced: bool,
1388    ///The name it covers.
1389    pub name: ::std::string::String,
1390    ///When it expires.
1391    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1392    pub not_after: ::std::option::Option<::std::string::String>,
1393    ///The profile it was issued under, if the authority named one.
1394    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1395    pub profile: ::std::option::Option<::std::string::String>,
1396    ///Whether an operator has revoked it. Stop serving it.
1397    pub revoked: bool,
1398    /**Whether it can still be served: not revoked, not expired. True even while
1399a renewal is under way, the chain in hand staying valid until the new one
1400lands.*/
1401    pub usable: bool,
1402}
1403/**One restore purpose a consumer advertises support for: the behaviours it
1404opts into and the settings it accepts per replica.*/
1405///
1406/// <details><summary>JSON schema</summary>
1407///
1408/// ```json
1409///{
1410///  "description": "One restore purpose a consumer advertises support for: the behaviours it\nopts into and the settings it accepts per replica.",
1411///  "type": "object",
1412///  "required": [
1413///    "intent"
1414///  ],
1415///  "properties": {
1416///    "description": {
1417///      "description": "Human-readable description of the intent, if provided.",
1418///      "type": [
1419///        "string",
1420///        "null"
1421///      ]
1422///    },
1423///    "intent": {
1424///      "description": "Name of the intent: an arbitrary identifier chosen by the consumer\n(e.g. `verify`); any name may be advertised.",
1425///      "type": "string"
1426///    },
1427///    "params": {
1428///      "description": "Configurable parameters this intent accepts per replica, keyed by\nparameter name.",
1429///      "$ref": "#/components/schemas/BTreeMap"
1430///    },
1431///    "semantics": {
1432///      "description": "Behaviours this intent opts into. Recognised values are `check` (a\nhealth report is expected for each replica), `once` (a given snapshot\nis only ever dispatched to a replica once, rather than repeatedly\nuntil overdue), and `url` (a replica's health report includes a link\nto it). Unrecognised values are stored but have no effect.",
1433///      "type": "array",
1434///      "items": {
1435///        "type": "string"
1436///      }
1437///    }
1438///  }
1439///}
1440/// ```
1441/// </details>
1442#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1443#[derive(::bon::Builder)]
1444#[non_exhaustive]
1445pub struct IntentDescriptor {
1446    ///Human-readable description of the intent, if provided.
1447    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1448    pub description: ::std::option::Option<::std::string::String>,
1449    /**Name of the intent: an arbitrary identifier chosen by the consumer
1450(e.g. `verify`); any name may be advertised.*/
1451    pub intent: ::std::string::String,
1452    /**Configurable parameters this intent accepts per replica, keyed by
1453parameter name.*/
1454    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1455    pub params: ::std::option::Option<BTreeMap>,
1456    /**Behaviours this intent opts into. Recognised values are `check` (a
1457health report is expected for each replica), `once` (a given snapshot
1458is only ever dispatched to a replica once, rather than repeatedly
1459until overdue), and `url` (a replica's health report includes a link
1460to it). Unrecognised values are stored but have no effect.*/
1461    #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
1462    pub semantics: ::std::vec::Vec<::std::string::String>,
1463}
1464///The calling identity, the box it is enrolled as, and what runs on that box.
1465///
1466/// <details><summary>JSON schema</summary>
1467///
1468/// ```json
1469///{
1470///  "description": "The calling identity, the box it is enrolled as, and what runs on that box.",
1471///  "type": "object",
1472///  "required": [
1473///    "applications",
1474///    "device_id",
1475///    "machine_id"
1476///  ],
1477///  "properties": {
1478///    "applications": {
1479///      "description": "The types of application Canopy currently holds for that machine. Empty\nfor a box that has enrolled but not yet reported what runs on it, which\nis awaiting a report rather than an error.\n\nA workload is named by its type, which is what the reporter itself said\nit was. Canopy's own identifier for an application is internal and never\non the wire.",
1480///      "type": "array",
1481///      "items": {
1482///        "$ref": "#/components/schemas/ApplicationType"
1483///      }
1484///    },
1485///    "device_id": {
1486///      "description": "The calling identity's own identifier.",
1487///      "type": "string",
1488///      "format": "uuid"
1489///    },
1490///    "machine_id": {
1491///      "description": "The machine this identity is enrolled as.",
1492///      "type": "string",
1493///      "format": "uuid"
1494///    }
1495///  }
1496///}
1497/// ```
1498/// </details>
1499#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1500#[derive(::bon::Builder)]
1501#[non_exhaustive]
1502pub struct MachineSelfResponse {
1503    /**The types of application Canopy currently holds for that machine. Empty
1504for a box that has enrolled but not yet reported what runs on it, which
1505is awaiting a report rather than an error.
1506
1507A workload is named by its type, which is what the reporter itself said
1508it was. Canopy's own identifier for an application is internal and never
1509on the wire.*/
1510    pub applications: ::std::vec::Vec<ApplicationType>,
1511    ///The calling identity's own identifier.
1512    pub device_id: ::uuid::Uuid,
1513    ///The machine this identity is enrolled as.
1514    pub machine_id: ::uuid::Uuid,
1515}
1516///How the target version's migrations went against the restored replica.
1517///
1518/// <details><summary>JSON schema</summary>
1519///
1520/// ```json
1521///{
1522///  "description": "How the target version's migrations went against the restored replica.",
1523///  "type": "object",
1524///  "required": [
1525///    "data_bytes_after",
1526///    "data_bytes_before",
1527///    "timings",
1528///    "total_elapsed_seconds"
1529///  ],
1530///  "properties": {
1531///    "application_type": {
1532///      "description": "The type of application whose candidate version was tried, echoed from\nthe worklist entry's `application_type`. Omitted by a consumer that\npredates the entry carrying it, in which case Canopy derives the\napplication from the machine and the version.",
1533///      "type": [
1534///        "string",
1535///        "null"
1536///      ]
1537///    },
1538///    "data_bytes_after": {
1539///      "description": "Size of the data after they ran. The growth between the two is what shows\na migration that backfills heavily.",
1540///      "type": "integer",
1541///      "format": "int64"
1542///    },
1543///    "data_bytes_before": {
1544///      "description": "Size of the data before the migrations ran.",
1545///      "type": "integer",
1546///      "format": "int64"
1547///    },
1548///    "failed_migration": {
1549///      "description": "The migration that failed, when one did.",
1550///      "type": [
1551///        "string",
1552///        "null"
1553///      ]
1554///    },
1555///    "target_version": {
1556///      "description": "The version whose migrations were applied, as semver, taken from the\nworklist entry's `target_version`. This is the version the consumer\nactually migrated to; send it in preference to echoing the identifier.",
1557///      "type": [
1558///        "string",
1559///        "null"
1560///      ]
1561///    },
1562///    "target_version_id": {
1563///      "description": "The version whose migrations were applied, as the identifier a consumer\nechoes from the worklist entry's `target_version_id`. Accepted only for\nolder consumers that report the identifier; omit it when `target_version`\nis sent.",
1564///      "type": [
1565///        "string",
1566///        "null"
1567///      ],
1568///      "format": "uuid"
1569///    },
1570///    "timings": {
1571///      "description": "One entry per migration that ran, in the order they ran.",
1572///      "type": "array",
1573///      "items": {
1574///        "$ref": "#/components/schemas/MigrationTimingArgs"
1575///      }
1576///    },
1577///    "total_elapsed_seconds": {
1578///      "description": "Whole seconds the whole migration run took.",
1579///      "type": "integer",
1580///      "format": "int64"
1581///    }
1582///  }
1583///}
1584/// ```
1585/// </details>
1586#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1587#[derive(::bon::Builder)]
1588#[non_exhaustive]
1589pub struct MigrationArgs {
1590    /**The type of application whose candidate version was tried, echoed from
1591the worklist entry's `application_type`. Omitted by a consumer that
1592predates the entry carrying it, in which case Canopy derives the
1593application from the machine and the version.*/
1594    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1595    pub application_type: ::std::option::Option<::std::string::String>,
1596    /**Size of the data after they ran. The growth between the two is what shows
1597a migration that backfills heavily.*/
1598    pub data_bytes_after: i64,
1599    ///Size of the data before the migrations ran.
1600    pub data_bytes_before: i64,
1601    ///The migration that failed, when one did.
1602    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1603    pub failed_migration: ::std::option::Option<::std::string::String>,
1604    /**The version whose migrations were applied, as semver, taken from the
1605worklist entry's `target_version`. This is the version the consumer
1606actually migrated to; send it in preference to echoing the identifier.*/
1607    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1608    pub target_version: ::std::option::Option<::std::string::String>,
1609    /**The version whose migrations were applied, as the identifier a consumer
1610echoes from the worklist entry's `target_version_id`. Accepted only for
1611older consumers that report the identifier; omit it when `target_version`
1612is sent.*/
1613    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1614    pub target_version_id: ::std::option::Option<::uuid::Uuid>,
1615    ///One entry per migration that ran, in the order they ran.
1616    pub timings: ::std::vec::Vec<MigrationTimingArgs>,
1617    ///Whole seconds the whole migration run took.
1618    pub total_elapsed_seconds: i64,
1619}
1620///How long one migration took.
1621///
1622/// <details><summary>JSON schema</summary>
1623///
1624/// ```json
1625///{
1626///  "description": "How long one migration took.",
1627///  "type": "object",
1628///  "required": [
1629///    "elapsed_seconds",
1630///    "name"
1631///  ],
1632///  "properties": {
1633///    "elapsed_seconds": {
1634///      "description": "Whole seconds it took.",
1635///      "type": "integer",
1636///      "format": "int64"
1637///    },
1638///    "name": {
1639///      "description": "The migration's name, as the migration runner reports it.",
1640///      "type": "string"
1641///    }
1642///  }
1643///}
1644/// ```
1645/// </details>
1646#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1647#[derive(::bon::Builder)]
1648#[non_exhaustive]
1649pub struct MigrationTimingArgs {
1650    ///Whole seconds it took.
1651    pub elapsed_seconds: i64,
1652    ///The migration's name, as the migration runner reports it.
1653    pub name: ::std::string::String,
1654}
1655/**The data type of a restore-replica configuration parameter, which
1656determines how its value is validated. `duration` and `bytes` values must
1657be non-negative integers (a count of seconds and of bytes, respectively);
1658`integer` accepts any whole number, positive or negative; `boolean` is a
1659JSON boolean; `text` is a JSON string.*/
1660///
1661/// <details><summary>JSON schema</summary>
1662///
1663/// ```json
1664///{
1665///  "description": "The data type of a restore-replica configuration parameter, which\ndetermines how its value is validated. `duration` and `bytes` values must\nbe non-negative integers (a count of seconds and of bytes, respectively);\n`integer` accepts any whole number, positive or negative; `boolean` is a\nJSON boolean; `text` is a JSON string.",
1666///  "type": "string",
1667///  "enum": [
1668///    "duration",
1669///    "bytes",
1670///    "boolean",
1671///    "integer",
1672///    "text"
1673///  ]
1674///}
1675/// ```
1676/// </details>
1677#[derive(
1678    ::serde::Deserialize,
1679    ::serde::Serialize,
1680    Clone,
1681    Copy,
1682    Debug,
1683    Eq,
1684    Hash,
1685    Ord,
1686    PartialEq,
1687    PartialOrd
1688)]
1689pub enum ParamType {
1690    #[serde(rename = "duration")]
1691    Duration,
1692    #[serde(rename = "bytes")]
1693    Bytes,
1694    #[serde(rename = "boolean")]
1695    Boolean,
1696    #[serde(rename = "integer")]
1697    Integer,
1698    #[serde(rename = "text")]
1699    Text,
1700}
1701impl ::std::fmt::Display for ParamType {
1702    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
1703        match *self {
1704            Self::Duration => f.write_str("duration"),
1705            Self::Bytes => f.write_str("bytes"),
1706            Self::Boolean => f.write_str("boolean"),
1707            Self::Integer => f.write_str("integer"),
1708            Self::Text => f.write_str("text"),
1709        }
1710    }
1711}
1712impl ::std::str::FromStr for ParamType {
1713    type Err = self::error::ConversionError;
1714    fn from_str(
1715        value: &str,
1716    ) -> ::std::result::Result<Self, self::error::ConversionError> {
1717        match value {
1718            "duration" => Ok(Self::Duration),
1719            "bytes" => Ok(Self::Bytes),
1720            "boolean" => Ok(Self::Boolean),
1721            "integer" => Ok(Self::Integer),
1722            "text" => Ok(Self::Text),
1723            _ => Err("invalid value".into()),
1724        }
1725    }
1726}
1727impl ::std::convert::TryFrom<&str> for ParamType {
1728    type Error = self::error::ConversionError;
1729    fn try_from(
1730        value: &str,
1731    ) -> ::std::result::Result<Self, self::error::ConversionError> {
1732        value.parse()
1733    }
1734}
1735impl ::std::convert::TryFrom<&::std::string::String> for ParamType {
1736    type Error = self::error::ConversionError;
1737    fn try_from(
1738        value: &::std::string::String,
1739    ) -> ::std::result::Result<Self, self::error::ConversionError> {
1740        value.parse()
1741    }
1742}
1743impl ::std::convert::TryFrom<::std::string::String> for ParamType {
1744    type Error = self::error::ConversionError;
1745    fn try_from(
1746        value: ::std::string::String,
1747    ) -> ::std::result::Result<Self, self::error::ConversionError> {
1748        value.parse()
1749    }
1750}
1751/**Standard error response body, returned for every non-2xx response.
1752
1753This follows the RFC 7807 "Problem Details" shape: a stable machine-readable
1754`type`, a short `title`, the repeated HTTP `status` code, and an optional
1755`detail` string with specifics of this particular occurrence.*/
1756///
1757/// <details><summary>JSON schema</summary>
1758///
1759/// ```json
1760///{
1761///  "description": "Standard error response body, returned for every non-2xx response.\n\nThis follows the RFC 7807 \"Problem Details\" shape: a stable machine-readable\n`type`, a short `title`, the repeated HTTP `status` code, and an optional\n`detail` string with specifics of this particular occurrence.",
1762///  "type": "object",
1763///  "required": [
1764///    "status",
1765///    "title",
1766///    "type"
1767///  ],
1768///  "properties": {
1769///    "detail": {
1770///      "description": "Human-readable explanation specific to this occurrence of the\nproblem, if any extra detail is available.",
1771///      "type": [
1772///        "string",
1773///        "null"
1774///      ]
1775///    },
1776///    "status": {
1777///      "description": "HTTP status code of the response, repeated here for convenience.",
1778///      "type": "integer",
1779///      "format": "int32",
1780///      "minimum": 0.0,
1781///      "example": 404
1782///    },
1783///    "title": {
1784///      "description": "Short, human-readable summary of the problem type. Does not vary\nbetween occurrences of the same `type`.",
1785///      "type": "string"
1786///    },
1787///    "type": {
1788///      "description": "A URI reference identifying the problem type. Stable across\noccurrences of the same error, so callers can match on it.",
1789///      "type": "string",
1790///      "format": "uri",
1791///      "example": "/errors/resource-not-found"
1792///    }
1793///  }
1794///}
1795/// ```
1796/// </details>
1797#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1798#[derive(::bon::Builder)]
1799#[non_exhaustive]
1800pub struct ProblemDetailsSchema {
1801    /**Human-readable explanation specific to this occurrence of the
1802problem, if any extra detail is available.*/
1803    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1804    pub detail: ::std::option::Option<::std::string::String>,
1805    ///HTTP status code of the response, repeated here for convenience.
1806    pub status: i32,
1807    /**Short, human-readable summary of the problem type. Does not vary
1808between occurrences of the same `type`.*/
1809    pub title: ::std::string::String,
1810    /**A URI reference identifying the problem type. Stable across
1811occurrences of the same error, so callers can match on it.*/
1812    #[serde(rename = "type")]
1813    pub type_: ::std::string::String,
1814}
1815///A progress sample from a run still in flight.
1816///
1817/// <details><summary>JSON schema</summary>
1818///
1819/// ```json
1820///{
1821///  "description": "A progress sample from a run still in flight.",
1822///  "type": "object",
1823///  "required": [
1824///    "run_id",
1825///    "type"
1826///  ],
1827///  "properties": {
1828///    "bytes_cached": {
1829///      "description": "Bytes found already present in the repository, and so not re-uploaded.",
1830///      "type": [
1831///        "integer",
1832///        "null"
1833///      ],
1834///      "format": "int64"
1835///    },
1836///    "bytes_estimated": {
1837///      "description": "Total bytes this run currently expects to handle. May be revised upward.",
1838///      "type": [
1839///        "integer",
1840///        "null"
1841///      ],
1842///      "format": "int64"
1843///    },
1844///    "bytes_hashed": {
1845///      "description": "Bytes processed (hashed, compressed) so far.",
1846///      "type": [
1847///        "integer",
1848///        "null"
1849///      ],
1850///      "format": "int64"
1851///    },
1852///    "bytes_read": {
1853///      "description": "Source bytes read so far.",
1854///      "type": [
1855///        "integer",
1856///        "null"
1857///      ],
1858///      "format": "int64"
1859///    },
1860///    "bytes_uploaded": {
1861///      "description": "Bytes uploaded to the repository so far.",
1862///      "type": [
1863///        "integer",
1864///        "null"
1865///      ],
1866///      "format": "int64"
1867///    },
1868///    "current_path": {
1869///      "description": "What the run is working on right now, for display.",
1870///      "type": [
1871///        "string",
1872///        "null"
1873///      ]
1874///    },
1875///    "errors": {
1876///      "description": "Errors hit so far.",
1877///      "type": [
1878///        "integer",
1879///        "null"
1880///      ],
1881///      "format": "int64"
1882///    },
1883///    "extra": {
1884///      "description": "Any further detail the backup engine emits. Canopy makes no commitment\nabout its shape: it is stored and shown verbatim, never interpreted.",
1885///      "type": "object"
1886///    },
1887///    "files_done": {
1888///      "description": "Files finished so far.",
1889///      "type": [
1890///        "integer",
1891///        "null"
1892///      ],
1893///      "format": "int64"
1894///    },
1895///    "files_estimated": {
1896///      "description": "Total files this run currently expects to handle.",
1897///      "type": [
1898///        "integer",
1899///        "null"
1900///      ],
1901///      "format": "int64"
1902///    },
1903///    "ignored_errors": {
1904///      "description": "Errors hit and deliberately ignored so far.",
1905///      "type": [
1906///        "integer",
1907///        "null"
1908///      ],
1909///      "format": "int64"
1910///    },
1911///    "purpose": {
1912///      "description": "Whether this is a `backup` or a `restore` run.",
1913///      "$ref": "#/components/schemas/BackupPurpose"
1914///    },
1915///    "run_id": {
1916///      "description": "The run-uuid the client minted for this run — the same one it passes to\n`POST /backup-credentials` and reports under at `POST /backup-report`.",
1917///      "type": "string",
1918///      "format": "uuid"
1919///    },
1920///    "s3_received_payload_bytes": {
1921///      "description": "Bytes of decoded object payload received from S3 so far.",
1922///      "type": [
1923///        "integer",
1924///        "null"
1925///      ],
1926///      "format": "int64"
1927///    },
1928///    "s3_received_raw_bytes": {
1929///      "description": "Bytes of raw HTTP traffic received from S3 so far.",
1930///      "type": [
1931///        "integer",
1932///        "null"
1933///      ],
1934///      "format": "int64"
1935///    },
1936///    "s3_sent_payload_bytes": {
1937///      "description": "Bytes of decoded object payload sent to S3 so far.",
1938///      "type": [
1939///        "integer",
1940///        "null"
1941///      ],
1942///      "format": "int64"
1943///    },
1944///    "s3_sent_raw_bytes": {
1945///      "description": "Bytes of raw HTTP traffic sent to S3 so far, including protocol and\nsigning overhead.",
1946///      "type": [
1947///        "integer",
1948///        "null"
1949///      ],
1950///      "format": "int64"
1951///    },
1952///    "snapshot_taken_at": {
1953///      "description": "When this run froze the data it is backing up — the point in time the\nbackup represents, as opposed to when its upload finishes. Send it as soon\nas it is known (before any transfer starts). Recorded once per run: the\nfirst value Canopy sees stands, whether it arrives here or on the report.",
1954///      "oneOf": [
1955///        {
1956///          "type": "null"
1957///        },
1958///        {
1959///          "$ref": "#/definitions/CanopyTimestamp"
1960///        }
1961///      ]
1962///    },
1963///    "type": {
1964///      "description": "The backup type being run (e.g. `tamanu-postgres`).",
1965///      "type": "string"
1966///    }
1967///  }
1968///}
1969/// ```
1970/// </details>
1971#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
1972#[derive(::bon::Builder)]
1973#[non_exhaustive]
1974pub struct ProgressArgs {
1975    ///Bytes found already present in the repository, and so not re-uploaded.
1976    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1977    pub bytes_cached: ::std::option::Option<i64>,
1978    ///Total bytes this run currently expects to handle. May be revised upward.
1979    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1980    pub bytes_estimated: ::std::option::Option<i64>,
1981    ///Bytes processed (hashed, compressed) so far.
1982    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1983    pub bytes_hashed: ::std::option::Option<i64>,
1984    ///Source bytes read so far.
1985    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1986    pub bytes_read: ::std::option::Option<i64>,
1987    ///Bytes uploaded to the repository so far.
1988    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1989    pub bytes_uploaded: ::std::option::Option<i64>,
1990    ///What the run is working on right now, for display.
1991    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1992    pub current_path: ::std::option::Option<::std::string::String>,
1993    ///Errors hit so far.
1994    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
1995    pub errors: ::std::option::Option<i64>,
1996    /**Any further detail the backup engine emits. Canopy makes no commitment
1997about its shape: it is stored and shown verbatim, never interpreted.*/
1998    #[serde(default, skip_serializing_if = "::serde_json::Map::is_empty")]
1999    pub extra: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
2000    ///Files finished so far.
2001    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2002    pub files_done: ::std::option::Option<i64>,
2003    ///Total files this run currently expects to handle.
2004    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2005    pub files_estimated: ::std::option::Option<i64>,
2006    ///Errors hit and deliberately ignored so far.
2007    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2008    pub ignored_errors: ::std::option::Option<i64>,
2009    ///Whether this is a `backup` or a `restore` run.
2010    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2011    pub purpose: ::std::option::Option<BackupPurpose>,
2012    /**The run-uuid the client minted for this run — the same one it passes to
2013`POST /backup-credentials` and reports under at `POST /backup-report`.*/
2014    pub run_id: ::uuid::Uuid,
2015    ///Bytes of decoded object payload received from S3 so far.
2016    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2017    pub s3_received_payload_bytes: ::std::option::Option<i64>,
2018    ///Bytes of raw HTTP traffic received from S3 so far.
2019    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2020    pub s3_received_raw_bytes: ::std::option::Option<i64>,
2021    ///Bytes of decoded object payload sent to S3 so far.
2022    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2023    pub s3_sent_payload_bytes: ::std::option::Option<i64>,
2024    /**Bytes of raw HTTP traffic sent to S3 so far, including protocol and
2025signing overhead.*/
2026    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2027    pub s3_sent_raw_bytes: ::std::option::Option<i64>,
2028    /**When this run froze the data it is backing up — the point in time the
2029backup represents, as opposed to when its upload finishes. Send it as soon
2030as it is known (before any transfer starts). Recorded once per run: the
2031first value Canopy sees stands, whether it arrives here or on the report.*/
2032    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2033    pub snapshot_taken_at: ::std::option::Option<::jiff::Timestamp>,
2034    ///The backup type being run (e.g. `tamanu-postgres`).
2035    #[serde(rename = "type")]
2036    pub type_: ::std::string::String,
2037}
2038///A publicly-listed central server that a client can connect to.
2039///
2040/// <details><summary>JSON schema</summary>
2041///
2042/// ```json
2043///{
2044///  "description": "A publicly-listed central server that a client can connect to.",
2045///  "type": "object",
2046///  "required": [
2047///    "host",
2048///    "name"
2049///  ],
2050///  "properties": {
2051///    "host": {
2052///      "description": "The server's reachable base URL.",
2053///      "$ref": "#/components/schemas/UrlField"
2054///    },
2055///    "name": {
2056///      "description": "Public-facing display name of the server.",
2057///      "type": "string"
2058///    },
2059///    "rank": {
2060///      "oneOf": [
2061///        {
2062///          "type": "null"
2063///        },
2064///        {
2065///          "description": "The server's environment tier (production, clone, demo, test, or\ndev), if set. Used to order the listing and to let clients label\nnon-production entries.",
2066///          "$ref": "#/components/schemas/ServerRank"
2067///        }
2068///      ]
2069///    }
2070///  }
2071///}
2072/// ```
2073/// </details>
2074#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2075#[derive(::bon::Builder)]
2076#[non_exhaustive]
2077pub struct PublicServer {
2078    ///The server's reachable base URL.
2079    pub host: UrlField,
2080    ///Public-facing display name of the server.
2081    pub name: ::std::string::String,
2082    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2083    pub rank: ::std::option::Option<ServerRank>,
2084}
2085/**How the masking manifest went against the restored replica.
2086
2087Reported when the redaction settles, which for a failure is before any
2088switchover: the restore itself succeeded and is reported healthy, and the
2089replica stays on the data it was already serving.*/
2090///
2091/// <details><summary>JSON schema</summary>
2092///
2093/// ```json
2094///{
2095///  "description": "How the masking manifest went against the restored replica.\n\nReported when the redaction settles, which for a failure is before any\nswitchover: the restore itself succeeded and is reported healthy, and the\nreplica stays on the data it was already serving.",
2096///  "type": "object",
2097///  "required": [
2098///    "outcome"
2099///  ],
2100///  "properties": {
2101///    "columns_masked": {
2102///      "description": "How many columns the manifest masked.",
2103///      "type": [
2104///        "integer",
2105///        "null"
2106///      ],
2107///      "format": "int64"
2108///    },
2109///    "columns_skipped": {
2110///      "description": "How many columns the manifest named but could not mask. Non-zero is\nwhat makes an outcome `partial`.",
2111///      "type": [
2112///        "integer",
2113///        "null"
2114///      ],
2115///      "format": "int64"
2116///    },
2117///    "error": {
2118///      "description": "Why the redaction failed, when it did.",
2119///      "type": [
2120///        "string",
2121///        "null"
2122///      ]
2123///    },
2124///    "manifest_version": {
2125///      "description": "The version resolved into the manifest URL. Omit when the URL named no\nversion to resolve.",
2126///      "type": [
2127///        "string",
2128///        "null"
2129///      ]
2130///    },
2131///    "outcome": {
2132///      "description": "How far the manifest got: `complete`, `partial`, or `failed`.",
2133///      "type": "string"
2134///    }
2135///  }
2136///}
2137/// ```
2138/// </details>
2139#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2140#[derive(::bon::Builder)]
2141#[non_exhaustive]
2142pub struct RedactionArgs {
2143    ///How many columns the manifest masked.
2144    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2145    pub columns_masked: ::std::option::Option<i64>,
2146    /**How many columns the manifest named but could not mask. Non-zero is
2147what makes an outcome `partial`.*/
2148    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2149    pub columns_skipped: ::std::option::Option<i64>,
2150    ///Why the redaction failed, when it did.
2151    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2152    pub error: ::std::option::Option<::std::string::String>,
2153    /**The version resolved into the manifest URL. Omit when the URL named no
2154version to resolve.*/
2155    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2156    pub manifest_version: ::std::option::Option<::std::string::String>,
2157    ///How far the manifest got: `complete`, `partial`, or `failed`.
2158    pub outcome: ::std::string::String,
2159}
2160///The name a server should be reachable at, and where.
2161///
2162/// <details><summary>JSON schema</summary>
2163///
2164/// ```json
2165///{
2166///  "description": "The name a server should be reachable at, and where.",
2167///  "type": "object",
2168///  "required": [
2169///    "addresses",
2170///    "name"
2171///  ],
2172///  "properties": {
2173///    "addresses": {
2174///      "description": "Every external address this server is reachable at. IPv4 addresses become\nA records and IPv6 addresses AAAA records, replacing whatever was\nregistered before. An empty list withdraws the name.",
2175///      "type": "array",
2176///      "items": {
2177///        "type": "string"
2178///      }
2179///    },
2180///    "name": {
2181///      "description": "The name to publish records at. Must sit within a domain this server's\ngroup controls.",
2182///      "type": "string"
2183///    }
2184///  }
2185///}
2186/// ```
2187/// </details>
2188#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2189#[derive(::bon::Builder)]
2190#[non_exhaustive]
2191pub struct RegisterNameArgs {
2192    /**Every external address this server is reachable at. IPv4 addresses become
2193A records and IPv6 addresses AAAA records, replacing whatever was
2194registered before. An empty list withdraws the name.*/
2195    pub addresses: ::std::vec::Vec<::std::string::String>,
2196    /**The name to publish records at. Must sit within a domain this server's
2197group controls.*/
2198    pub name: ::std::string::String,
2199}
2200///What Canopy holds for a registered name.
2201///
2202/// <details><summary>JSON schema</summary>
2203///
2204/// ```json
2205///{
2206///  "description": "What Canopy holds for a registered name.",
2207///  "type": "object",
2208///  "required": [
2209///    "addresses",
2210///    "name",
2211///    "published",
2212///    "published_addresses"
2213///  ],
2214///  "properties": {
2215///    "addresses": {
2216///      "description": "The addresses Canopy will publish.",
2217///      "type": "array",
2218///      "items": {
2219///        "type": "string"
2220///      }
2221///    },
2222///    "last_error": {
2223///      "description": "Why the last publish attempt failed, if it did.",
2224///      "type": [
2225///        "string",
2226///        "null"
2227///      ]
2228///    },
2229///    "name": {
2230///      "description": "The name, as Canopy normalised it.",
2231///      "type": "string"
2232///    },
2233///    "published": {
2234///      "description": "Whether the zone has caught up with what was asked for.",
2235///      "type": "boolean"
2236///    },
2237///    "published_addresses": {
2238///      "description": "The addresses Canopy has published so far. Differs from `addresses` until\nthe change has been reconciled into the zone.",
2239///      "type": "array",
2240///      "items": {
2241///        "type": "string"
2242///      }
2243///    }
2244///  }
2245///}
2246/// ```
2247/// </details>
2248#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2249#[derive(::bon::Builder)]
2250#[non_exhaustive]
2251pub struct RegisteredName {
2252    ///The addresses Canopy will publish.
2253    pub addresses: ::std::vec::Vec<::std::string::String>,
2254    ///Why the last publish attempt failed, if it did.
2255    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2256    pub last_error: ::std::option::Option<::std::string::String>,
2257    ///The name, as Canopy normalised it.
2258    pub name: ::std::string::String,
2259    ///Whether the zone has caught up with what was asked for.
2260    pub published: bool,
2261    /**The addresses Canopy has published so far. Differs from `addresses` until
2262the change has been reconciled into the zone.*/
2263    pub published_addresses: ::std::vec::Vec<::std::string::String>,
2264}
2265///Report of a completed backup or restore run.
2266///
2267/// <details><summary>JSON schema</summary>
2268///
2269/// ```json
2270///{
2271///  "description": "Report of a completed backup or restore run.",
2272///  "type": "object",
2273///  "required": [
2274///    "outcome",
2275///    "purpose",
2276///    "run_id",
2277///    "type"
2278///  ],
2279///  "properties": {
2280///    "bytes_uploaded": {
2281///      "description": "Total bytes of backup data uploaded during the run, if known.",
2282///      "type": [
2283///        "integer",
2284///        "null"
2285///      ],
2286///      "format": "int64"
2287///    },
2288///    "error": {
2289///      "description": "Human-readable error detail, when the run failed.",
2290///      "type": [
2291///        "string",
2292///        "null"
2293///      ]
2294///    },
2295///    "outcome": {
2296///      "description": "Whether the run succeeded (`success`) or failed (`failure`).",
2297///      "$ref": "#/components/schemas/RunOutcome"
2298///    },
2299///    "purpose": {
2300///      "description": "Whether the run was a `backup` or a `restore`.",
2301///      "$ref": "#/components/schemas/BackupPurpose"
2302///    },
2303///    "run_id": {
2304///      "description": "Client-generated UUID identifying this run, minted at run start. Each\nrun must use a fresh UUID: reporting the same `run_id` twice is\nrejected with 409.",
2305///      "type": "string",
2306///      "format": "uuid"
2307///    },
2308///    "s3_received_payload_bytes": {
2309///      "description": "Bytes of decoded object payload received from S3 during the run.",
2310///      "type": [
2311///        "integer",
2312///        "null"
2313///      ],
2314///      "format": "int64"
2315///    },
2316///    "s3_received_raw_bytes": {
2317///      "description": "Bytes of raw HTTP traffic received from S3 during the run, including\nprotocol overhead.",
2318///      "type": [
2319///        "integer",
2320///        "null"
2321///      ],
2322///      "format": "int64"
2323///    },
2324///    "s3_sent_payload_bytes": {
2325///      "description": "Bytes of decoded object payload sent to S3 during the run (excluding\nprotocol and signing overhead).",
2326///      "type": [
2327///        "integer",
2328///        "null"
2329///      ],
2330///      "format": "int64"
2331///    },
2332///    "s3_sent_raw_bytes": {
2333///      "description": "Bytes of raw HTTP traffic sent to S3 during the run, including protocol\nand signing overhead. Report on both success and failure; omit when\ntraffic was not measured.",
2334///      "type": [
2335///        "integer",
2336///        "null"
2337///      ],
2338///      "format": "int64"
2339///    },
2340///    "snapshot_id": {
2341///      "description": "Identifier of the repository snapshot the run produced, for a\nsuccessful backup.",
2342///      "type": [
2343///        "string",
2344///        "null"
2345///      ]
2346///    },
2347///    "snapshot_taken_at": {
2348///      "description": "When this run froze the data it backed up — the point in time the backup\nrepresents, as opposed to when its upload finished. Often a filesystem-level\nsnapshot taken before the transfer, in which case it is not recoverable\nfrom the repository and only the device can report it. Recorded once per\nrun: if progress reports already carried it, that value stands.",
2349///      "oneOf": [
2350///        {
2351///          "type": "null"
2352///        },
2353///        {
2354///          "$ref": "#/definitions/CanopyTimestamp"
2355///        }
2356///      ]
2357///    },
2358///    "type": {
2359///      "description": "The backup type that ran (e.g. `tamanu-postgres`).",
2360///      "type": "string"
2361///    }
2362///  }
2363///}
2364/// ```
2365/// </details>
2366#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2367#[derive(::bon::Builder)]
2368#[non_exhaustive]
2369pub struct ReportArgs {
2370    ///Total bytes of backup data uploaded during the run, if known.
2371    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2372    pub bytes_uploaded: ::std::option::Option<i64>,
2373    ///Human-readable error detail, when the run failed.
2374    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2375    pub error: ::std::option::Option<::std::string::String>,
2376    ///Whether the run succeeded (`success`) or failed (`failure`).
2377    pub outcome: RunOutcome,
2378    ///Whether the run was a `backup` or a `restore`.
2379    pub purpose: BackupPurpose,
2380    /**Client-generated UUID identifying this run, minted at run start. Each
2381run must use a fresh UUID: reporting the same `run_id` twice is
2382rejected with 409.*/
2383    pub run_id: ::uuid::Uuid,
2384    ///Bytes of decoded object payload received from S3 during the run.
2385    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2386    pub s3_received_payload_bytes: ::std::option::Option<i64>,
2387    /**Bytes of raw HTTP traffic received from S3 during the run, including
2388protocol overhead.*/
2389    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2390    pub s3_received_raw_bytes: ::std::option::Option<i64>,
2391    /**Bytes of decoded object payload sent to S3 during the run (excluding
2392protocol and signing overhead).*/
2393    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2394    pub s3_sent_payload_bytes: ::std::option::Option<i64>,
2395    /**Bytes of raw HTTP traffic sent to S3 during the run, including protocol
2396and signing overhead. Report on both success and failure; omit when
2397traffic was not measured.*/
2398    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2399    pub s3_sent_raw_bytes: ::std::option::Option<i64>,
2400    /**Identifier of the repository snapshot the run produced, for a
2401successful backup.*/
2402    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2403    pub snapshot_id: ::std::option::Option<::std::string::String>,
2404    /**When this run froze the data it backed up — the point in time the backup
2405represents, as opposed to when its upload finished. Often a filesystem-level
2406snapshot taken before the transfer, in which case it is not recoverable
2407from the repository and only the device can report it. Recorded once per
2408run: if progress reports already carried it, that value stands.*/
2409    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2410    pub snapshot_taken_at: ::std::option::Option<::jiff::Timestamp>,
2411    ///The backup type that ran (e.g. `tamanu-postgres`).
2412    #[serde(rename = "type")]
2413    pub type_: ::std::string::String,
2414}
2415///A request to certify a key for a name.
2416///
2417/// <details><summary>JSON schema</summary>
2418///
2419/// ```json
2420///{
2421///  "description": "A request to certify a key for a name.",
2422///  "type": "object",
2423///  "required": [
2424///    "csr",
2425///    "name"
2426///  ],
2427///  "properties": {
2428///    "csr": {
2429///      "description": "The certificate signing request, DER, base64. Must ask for exactly `name`\nand nothing else — a request carrying any other name is refused rather\nthan trimmed.",
2430///      "type": "string"
2431///    },
2432///    "name": {
2433///      "description": "The name to certify. Must sit within a domain this server's group\ncontrols.",
2434///      "type": "string"
2435///    }
2436///  }
2437///}
2438/// ```
2439/// </details>
2440#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2441#[derive(::bon::Builder)]
2442#[non_exhaustive]
2443pub struct RequestCertificateArgs {
2444    /**The certificate signing request, DER, base64. Must ask for exactly `name`
2445and nothing else — a request carrying any other name is refused rather
2446than trimmed.*/
2447    pub csr: ::std::string::String,
2448    /**The name to certify. Must sit within a domain this server's group
2449controls.*/
2450    pub name: ::std::string::String,
2451}
2452/**Request body for registering the restore intents a consumer device can
2453satisfy.*/
2454///
2455/// <details><summary>JSON schema</summary>
2456///
2457/// ```json
2458///{
2459///  "description": "Request body for registering the restore intents a consumer device can\nsatisfy.",
2460///  "type": "object",
2461///  "required": [
2462///    "intents"
2463///  ],
2464///  "properties": {
2465///    "intents": {
2466///      "description": "The intents this device can satisfy — arbitrary consumer-chosen\nidentifiers (e.g. `verify`) — each with its description, the semantics\nit opts into, and the schema of the parameters it accepts. Replaces the\ndevice's previously advertised set wholesale.",
2467///      "type": "array",
2468///      "items": {
2469///        "$ref": "#/components/schemas/IntentDescriptor"
2470///      }
2471///    }
2472///  }
2473///}
2474/// ```
2475/// </details>
2476#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2477#[derive(::bon::Builder)]
2478#[non_exhaustive]
2479pub struct RestoreCapabilitiesArgs {
2480    /**The intents this device can satisfy — arbitrary consumer-chosen
2481identifiers (e.g. `verify`) — each with its description, the semantics
2482it opts into, and the schema of the parameters it accepts. Replaces the
2483device's previously advertised set wholesale.*/
2484    pub intents: ::std::vec::Vec<IntentDescriptor>,
2485}
2486/**Read-only S3 credentials plus the repository passphrase for one group and
2487backup type: everything needed to open the group's backup repository and
2488read a snapshot out of it.*/
2489///
2490/// <details><summary>JSON schema</summary>
2491///
2492/// ```json
2493///{
2494///  "description": "Read-only S3 credentials plus the repository passphrase for one group and\nbackup type: everything needed to open the group's backup repository and\nread a snapshot out of it.",
2495///  "type": "object",
2496///  "required": [
2497///    "credentials",
2498///    "repo_password"
2499///  ],
2500///  "properties": {
2501///    "credentials": {
2502///      "description": "Temporary read-only AWS credentials in the `credential_process` output\nformat, valid for at most one hour.",
2503///      "$ref": "#/components/schemas/CredentialProcessOutput"
2504///    },
2505///    "repo_password": {
2506///      "description": "Passphrase for the group's backup repository (a Kopia repository).",
2507///      "$ref": "#/definitions/CanopySecret"
2508///    }
2509///  }
2510///}
2511/// ```
2512/// </details>
2513#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2514#[derive(::bon::Builder)]
2515#[non_exhaustive]
2516pub struct RestoreCredentials {
2517    /**Temporary read-only AWS credentials in the `credential_process` output
2518format, valid for at most one hour.*/
2519    pub credentials: CredentialProcessOutput,
2520    ///Passphrase for the group's backup repository (a Kopia repository).
2521    pub repo_password: crate::Redacted<::std::string::String>,
2522}
2523///Request body for minting read-only restore credentials.
2524///
2525/// <details><summary>JSON schema</summary>
2526///
2527/// ```json
2528///{
2529///  "description": "Request body for minting read-only restore credentials.",
2530///  "type": "object",
2531///  "required": [
2532///    "group",
2533///    "type"
2534///  ],
2535///  "properties": {
2536///    "group": {
2537///      "description": "The server group whose backup repository to read.",
2538///      "type": "string",
2539///      "format": "uuid"
2540///    },
2541///    "run_id": {
2542///      "description": "This must be the run-uuid the client minted for this run.\nThe field is optional only so older clients don't break; it WILL be made\nmandatory in future.",
2543///      "type": [
2544///        "string",
2545///        "null"
2546///      ],
2547///      "format": "uuid"
2548///    },
2549///    "type": {
2550///      "description": "The backup type to restore (e.g. `tamanu-postgres`).",
2551///      "type": "string"
2552///    }
2553///  }
2554///}
2555/// ```
2556/// </details>
2557#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2558#[derive(::bon::Builder)]
2559#[non_exhaustive]
2560pub struct RestoreCredentialsArgs {
2561    ///The server group whose backup repository to read.
2562    pub group: ::uuid::Uuid,
2563    /**This must be the run-uuid the client minted for this run.
2564The field is optional only so older clients don't break; it WILL be made
2565mandatory in future.*/
2566    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2567    pub run_id: ::std::option::Option<::uuid::Uuid>,
2568    ///The backup type to restore (e.g. `tamanu-postgres`).
2569    #[serde(rename = "type")]
2570    pub type_: ::std::string::String,
2571}
2572///Outcome of a reported backup or restore run.
2573///
2574/// <details><summary>JSON schema</summary>
2575///
2576/// ```json
2577///{
2578///  "description": "Outcome of a reported backup or restore run.",
2579///  "type": "string",
2580///  "enum": [
2581///    "success",
2582///    "failure"
2583///  ]
2584///}
2585/// ```
2586/// </details>
2587#[derive(
2588    ::serde::Deserialize,
2589    ::serde::Serialize,
2590    Clone,
2591    Copy,
2592    Debug,
2593    Eq,
2594    Hash,
2595    Ord,
2596    PartialEq,
2597    PartialOrd
2598)]
2599pub enum RunOutcome {
2600    #[serde(rename = "success")]
2601    Success,
2602    #[serde(rename = "failure")]
2603    Failure,
2604}
2605impl ::std::fmt::Display for RunOutcome {
2606    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
2607        match *self {
2608            Self::Success => f.write_str("success"),
2609            Self::Failure => f.write_str("failure"),
2610        }
2611    }
2612}
2613impl ::std::str::FromStr for RunOutcome {
2614    type Err = self::error::ConversionError;
2615    fn from_str(
2616        value: &str,
2617    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2618        match value {
2619            "success" => Ok(Self::Success),
2620            "failure" => Ok(Self::Failure),
2621            _ => Err("invalid value".into()),
2622        }
2623    }
2624}
2625impl ::std::convert::TryFrom<&str> for RunOutcome {
2626    type Error = self::error::ConversionError;
2627    fn try_from(
2628        value: &str,
2629    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2630        value.parse()
2631    }
2632}
2633impl ::std::convert::TryFrom<&::std::string::String> for RunOutcome {
2634    type Error = self::error::ConversionError;
2635    fn try_from(
2636        value: &::std::string::String,
2637    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2638        value.parse()
2639    }
2640}
2641impl ::std::convert::TryFrom<::std::string::String> for RunOutcome {
2642    type Error = self::error::ConversionError;
2643    fn try_from(
2644        value: ::std::string::String,
2645    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2646        value.parse()
2647    }
2648}
2649///The calling device's own identity, as assigned at enrollment.
2650///
2651/// <details><summary>JSON schema</summary>
2652///
2653/// ```json
2654///{
2655///  "description": "The calling device's own identity, as assigned at enrollment.",
2656///  "type": "object",
2657///  "required": [
2658///    "device_id",
2659///    "server_id"
2660///  ],
2661///  "properties": {
2662///    "device_id": {
2663///      "description": "The calling device's own identity.",
2664///      "type": "string",
2665///      "format": "uuid"
2666///    },
2667///    "server_id": {
2668///      "description": "The box the calling device is enrolled as. This is the id a device\npushes status against, and the one `GET /machines/self` calls\n`machine_id`.",
2669///      "type": "string",
2670///      "format": "uuid"
2671///    }
2672///  }
2673///}
2674/// ```
2675/// </details>
2676#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2677#[derive(::bon::Builder)]
2678#[non_exhaustive]
2679pub struct SelfResponse {
2680    ///The calling device's own identity.
2681    pub device_id: ::uuid::Uuid,
2682    /**The box the calling device is enrolled as. This is the id a device
2683pushes status against, and the one `GET /machines/self` calls
2684`machine_id`.*/
2685    pub server_id: ::uuid::Uuid,
2686}
2687///The environment tier of a server, from `production` down to `dev`.
2688///
2689/// <details><summary>JSON schema</summary>
2690///
2691/// ```json
2692///{
2693///  "description": "The environment tier of a server, from `production` down to `dev`.",
2694///  "type": "string",
2695///  "enum": [
2696///    "production",
2697///    "clone",
2698///    "demo",
2699///    "test",
2700///    "dev"
2701///  ]
2702///}
2703/// ```
2704/// </details>
2705#[derive(
2706    ::serde::Deserialize,
2707    ::serde::Serialize,
2708    Clone,
2709    Copy,
2710    Debug,
2711    Eq,
2712    Hash,
2713    Ord,
2714    PartialEq,
2715    PartialOrd
2716)]
2717pub enum ServerRank {
2718    #[serde(rename = "production")]
2719    Production,
2720    #[serde(rename = "clone")]
2721    Clone,
2722    #[serde(rename = "demo")]
2723    Demo,
2724    #[serde(rename = "test")]
2725    Test,
2726    #[serde(rename = "dev")]
2727    Dev,
2728}
2729impl ::std::fmt::Display for ServerRank {
2730    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
2731        match *self {
2732            Self::Production => f.write_str("production"),
2733            Self::Clone => f.write_str("clone"),
2734            Self::Demo => f.write_str("demo"),
2735            Self::Test => f.write_str("test"),
2736            Self::Dev => f.write_str("dev"),
2737        }
2738    }
2739}
2740impl ::std::str::FromStr for ServerRank {
2741    type Err = self::error::ConversionError;
2742    fn from_str(
2743        value: &str,
2744    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2745        match value {
2746            "production" => Ok(Self::Production),
2747            "clone" => Ok(Self::Clone),
2748            "demo" => Ok(Self::Demo),
2749            "test" => Ok(Self::Test),
2750            "dev" => Ok(Self::Dev),
2751            _ => Err("invalid value".into()),
2752        }
2753    }
2754}
2755impl ::std::convert::TryFrom<&str> for ServerRank {
2756    type Error = self::error::ConversionError;
2757    fn try_from(
2758        value: &str,
2759    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2760        value.parse()
2761    }
2762}
2763impl ::std::convert::TryFrom<&::std::string::String> for ServerRank {
2764    type Error = self::error::ConversionError;
2765    fn try_from(
2766        value: &::std::string::String,
2767    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2768        value.parse()
2769    }
2770}
2771impl ::std::convert::TryFrom<::std::string::String> for ServerRank {
2772    type Error = self::error::ConversionError;
2773    fn try_from(
2774        value: ::std::string::String,
2775    ) -> ::std::result::Result<Self, self::error::ConversionError> {
2776        value.parse()
2777    }
2778}
2779///A single named SQL snippet from the bestool snippet library.
2780///
2781/// <details><summary>JSON schema</summary>
2782///
2783/// ```json
2784///{
2785///  "description": "A single named SQL snippet from the bestool snippet library.",
2786///  "type": "object",
2787///  "required": [
2788///    "sql"
2789///  ],
2790///  "properties": {
2791///    "description": {
2792///      "description": "Human-readable explanation of what the snippet does, if the author\nprovided one.",
2793///      "type": [
2794///        "string",
2795///        "null"
2796///      ]
2797///    },
2798///    "sql": {
2799///      "description": "The snippet's SQL text.",
2800///      "type": "string"
2801///    }
2802///  }
2803///}
2804/// ```
2805/// </details>
2806#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2807#[derive(::bon::Builder)]
2808#[non_exhaustive]
2809pub struct SnippetResponse {
2810    /**Human-readable explanation of what the snippet does, if the author
2811provided one.*/
2812    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2813    pub description: ::std::option::Option<::std::string::String>,
2814    ///The snippet's SQL text.
2815    pub sql: ::std::string::String,
2816}
2817/**A status push: a server's periodic heartbeat carrying its self-reported
2818health.
2819
2820Besides the reserved `healthy` and `health` keys described here, any
2821additional top-level fields are accepted and stored verbatim as extra
2822status data.*/
2823///
2824/// <details><summary>JSON schema</summary>
2825///
2826/// ```json
2827///{
2828///  "description": "A status push: a server's periodic heartbeat carrying its self-reported\nhealth.\n\nBesides the reserved `healthy` and `health` keys described here, any\nadditional top-level fields are accepted and stored verbatim as extra\nstatus data.",
2829///  "type": "object",
2830///  "required": [
2831///    "health"
2832///  ],
2833///  "properties": {
2834///    "applications": {
2835///      "description": "The applications the reporter found on the machine, each with its own\nhealth checks and detail, keyed by a key the reporter chooses.\n\nThe key must be unique among the applications on that machine and must\nidentify the same application across this reporter's pushes; what it is\nderived from is the reporter's own business. Canopy correlates on the\nmachine, the key and the type together, and never discloses its own\nidentifier for an application.\n\nOnly read alongside `machine`. An application named here that Canopy\ndoes not already hold is created.",
2836///      "type": [
2837///        "object",
2838///        "null"
2839///      ],
2840///      "additionalProperties": {
2841///        "$ref": "#/components/schemas/ApplicationReport"
2842///      },
2843///      "propertyNames": {
2844///        "type": "string"
2845///      }
2846///    },
2847///    "health": {
2848///      "description": "Per-check breakdown. A push without a `health` array is the legacy\nTamanu direct-report format: it is treated as the `tamanu` source\nreporting a single always-passing `tasks` heartbeat check. May be\nempty (`[]`) for a source that genuinely runs no checks — which\nrecovers every check it previously reported. Each entry must\ninclude a non-empty `check` name and exactly one of `result` /\n`healthy`; any additional fields per check (latency, free disk %,\ncertificate expiry, etc.) are passed through verbatim and shown in the\nstatus UI.\n\nEvery check name seen — whatever its result — is added to the\noperator-facing check catalog, where the policy grading its results\ncan be reviewed and adjusted. A check whose effective result is\nfailed or warning opens (or keeps open) its issue; a broken check\nkeeps the same issue open, retaining a known failure's contribution\nwhile warning the check itself is broken; effective passed and\nskipped results open nothing and close prior issues.",
2849///      "type": "array",
2850///      "items": {
2851///        "$ref": "#/components/schemas/HealthCheck"
2852///      }
2853///    },
2854///    "healthy": {
2855///      "description": "Overall self-reported health of the server. **Absent means `true`**,\nso senders that predate this field are never treated as unhealthy by\nomission. Recorded for historical analysis and display, but **not\nconsulted for incident or severity decisions** — those are derived\nfrom the per-check results in `health`, with each check's severity\ncontrolled by an operator-managed catalog.",
2856///      "type": [
2857///        "boolean",
2858///        "null"
2859///      ]
2860///    },
2861///    "machine": {
2862///      "oneOf": [
2863///        {
2864///          "type": "null"
2865///        },
2866///        {
2867///          "description": "The machine's own health checks and detail: what the box is, rather\nthan what runs on it.\n\nSending this puts the push in the current format, and Canopy takes the\nseparation as given. A push without it is a transitional unified push,\nwhich Canopy separates into the two grains itself from `health` and the\nflat body.",
2868///          "$ref": "#/components/schemas/TargetReport"
2869///        }
2870///      ]
2871///    },
2872///    "source": {
2873///      "description": "The name of the source pushing this status: the reporting agent, e.g.\n`alertd`. Multiple sources may report on one server, each with its own\nset of checks; a source's push only opens and recovers its own checks.\n\n**Transitionally optional: this field will become mandatory.** A push\nwithout a `source` is attributed to `alertd`; new reporters must send\ntheir own name. Must be a non-empty string; the names `canopy` and\n`manual` are reserved for canopy itself and are rejected.",
2874///      "type": [
2875///        "string",
2876///        "null"
2877///      ]
2878///    }
2879///  },
2880///  "additionalProperties": true
2881///}
2882/// ```
2883/// </details>
2884#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
2885#[derive(::bon::Builder)]
2886#[non_exhaustive]
2887pub struct StatusPayload {
2888    /**The applications the reporter found on the machine, each with its own
2889health checks and detail, keyed by a key the reporter chooses.
2890
2891The key must be unique among the applications on that machine and must
2892identify the same application across this reporter's pushes; what it is
2893derived from is the reporter's own business. Canopy correlates on the
2894machine, the key and the type together, and never discloses its own
2895identifier for an application.
2896
2897Only read alongside `machine`. An application named here that Canopy
2898does not already hold is created.*/
2899    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2900    pub applications: ::std::option::Option<
2901        ::std::collections::HashMap<::std::string::String, ApplicationReport>,
2902    >,
2903    /**Per-check breakdown. A push without a `health` array is the legacy
2904Tamanu direct-report format: it is treated as the `tamanu` source
2905reporting a single always-passing `tasks` heartbeat check. May be
2906empty (`[]`) for a source that genuinely runs no checks — which
2907recovers every check it previously reported. Each entry must
2908include a non-empty `check` name and exactly one of `result` /
2909`healthy`; any additional fields per check (latency, free disk %,
2910certificate expiry, etc.) are passed through verbatim and shown in the
2911status UI.
2912
2913Every check name seen — whatever its result — is added to the
2914operator-facing check catalog, where the policy grading its results
2915can be reviewed and adjusted. A check whose effective result is
2916failed or warning opens (or keeps open) its issue; a broken check
2917keeps the same issue open, retaining a known failure's contribution
2918while warning the check itself is broken; effective passed and
2919skipped results open nothing and close prior issues.*/
2920    pub health: ::std::vec::Vec<HealthCheck>,
2921    /**Overall self-reported health of the server. **Absent means `true`**,
2922so senders that predate this field are never treated as unhealthy by
2923omission. Recorded for historical analysis and display, but **not
2924consulted for incident or severity decisions** — those are derived
2925from the per-check results in `health`, with each check's severity
2926controlled by an operator-managed catalog.*/
2927    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2928    pub healthy: ::std::option::Option<bool>,
2929    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2930    pub machine: ::std::option::Option<TargetReport>,
2931    /**The name of the source pushing this status: the reporting agent, e.g.
2932`alertd`. Multiple sources may report on one server, each with its own
2933set of checks; a source's push only opens and recovers its own checks.
2934
2935**Transitionally optional: this field will become mandatory.** A push
2936without a `source` is attributed to `alertd`; new reporters must send
2937their own name. Must be a non-empty string; the names `canopy` and
2938`manual` are reserved for canopy itself and are rejected.*/
2939    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
2940    pub source: ::std::option::Option<::std::string::String>,
2941    /// Any further keys the schema accepts alongside those above,
2942    /// carried verbatim.
2943    #[serde(flatten)]
2944    #[builder(default)]
2945    pub extra: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
2946}
2947/**The status-push response: only the return-path instructions the device
2948can act on. The stored status record is deliberately not echoed back —
2949the device already has everything it sent.*/
2950///
2951/// <details><summary>JSON schema</summary>
2952///
2953/// ```json
2954///{
2955///  "description": "The status-push response: only the return-path instructions the device\ncan act on. The stored status record is deliberately not echoed back —\nthe device already has everything it sent.",
2956///  "type": "object",
2957///  "required": [
2958///    "backup_now",
2959///    "check_severities",
2960///    "names",
2961///    "tags"
2962///  ],
2963///  "properties": {
2964///    "applications": {
2965///      "description": "Canopy's answer about each application the push described, keyed by the\nkey the reporter named it with. Present only for a push in the current\nformat.\n\nA key Canopy holds no application for is absent rather than empty,\nwhich is what a source whose pushes are ignored sees: nothing was\ncreated for it to be told about.",
2966///      "type": [
2967///        "object",
2968///        "null"
2969///      ],
2970///      "additionalProperties": {
2971///        "$ref": "#/components/schemas/TargetResponse"
2972///      },
2973///      "propertyNames": {
2974///        "type": "string"
2975///      }
2976///    },
2977///    "backup_now": {
2978///      "description": "Backup types the server should back up now: operator-requested\none-offs plus scheduled backups that are due. Each serializes as a\nplain string (e.g. `\"tamanu-postgres\"`). The device should run each\nlisted type, then report via `POST /backup-report`; an empty list\nmeans nothing to do. Only sent to `alertd` pushes (the agent that\nruns backups); other sources always receive an empty list.",
2979///      "type": "array",
2980///      "items": {
2981///        "type": "string"
2982///      }
2983///    },
2984///    "check_severities": {
2985///      "description": "The effective handling of every healthcheck canopy knows about, keyed\nby check name (as reported in `health[].check`): `skip` (silenced for\nthis server, or classified below warning), `warn` (warning), or `fail`\n(error or critical). Only the static severity baseline is reflected —\noperator-defined conditional rules are evaluated per push and not\nincluded. Checks absent from the map are new to canopy and default to\n`warn`. Clients that predate this field can safely ignore it; the\nsame mapping is served on demand at `GET /status/{server_id}/check-severities`.",
2986///      "type": "object",
2987///      "additionalProperties": {
2988///        "$ref": "#/components/schemas/CheckSeverity"
2989///      },
2990///      "propertyNames": {
2991///        "type": "string"
2992///      }
2993///    },
2994///    "machine": {
2995///      "oneOf": [
2996///        {
2997///          "type": "null"
2998///        },
2999///        {
3000///          "description": "Canopy's answer about the machine. Present only for a push in the\ncurrent format: a transitional unified push is answered by the flat\nfields above and nothing else, so the response a fielded reporter sees\nis the one it already saw.",
3001///          "$ref": "#/components/schemas/TargetResponse"
3002///        }
3003///      ]
3004///    },
3005///    "names": {
3006///      "description": "What this server is entitled to do with names: the domains its group\ncontrols, the grants it holds, whether it is paused, and the names and\ncertificates it already has. A server-wide fact, so returned to every\nsource — an agent already reporting status learns of a new domain or a\nnewly granted permission without asking separately. Identical to what\n`GET /names/entitlements` returns. Clients that predate this field can\nsafely ignore it.",
3007///      "$ref": "#/components/schemas/Entitlements"
3008///    },
3009///    "tags": {
3010///      "description": "The server's effective tags: its own tags overlaid on its group's,\nplus the synthetic read-only `canopy:` tags and effective `billing.*`\nlabels. Identical to what the standalone `GET /tags` endpoint\nreturns — see that endpoint for the full contract. Clients that\npredate this field can safely ignore it.\n\nOn a push in the current format this is the machine's, the push being\nthe machine's; each application's own are under `applications`.",
3011///      "$ref": "#/components/schemas/TagMap"
3012///    }
3013///  }
3014///}
3015/// ```
3016/// </details>
3017#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3018#[derive(::bon::Builder)]
3019#[non_exhaustive]
3020pub struct StatusResponse {
3021    /**Canopy's answer about each application the push described, keyed by the
3022key the reporter named it with. Present only for a push in the current
3023format.
3024
3025A key Canopy holds no application for is absent rather than empty,
3026which is what a source whose pushes are ignored sees: nothing was
3027created for it to be told about.*/
3028    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3029    pub applications: ::std::option::Option<
3030        ::std::collections::HashMap<::std::string::String, TargetResponse>,
3031    >,
3032    /**Backup types the server should back up now: operator-requested
3033one-offs plus scheduled backups that are due. Each serializes as a
3034plain string (e.g. `"tamanu-postgres"`). The device should run each
3035listed type, then report via `POST /backup-report`; an empty list
3036means nothing to do. Only sent to `alertd` pushes (the agent that
3037runs backups); other sources always receive an empty list.*/
3038    pub backup_now: ::std::vec::Vec<::std::string::String>,
3039    /**The effective handling of every healthcheck canopy knows about, keyed
3040by check name (as reported in `health[].check`): `skip` (silenced for
3041this server, or classified below warning), `warn` (warning), or `fail`
3042(error or critical). Only the static severity baseline is reflected —
3043operator-defined conditional rules are evaluated per push and not
3044included. Checks absent from the map are new to canopy and default to
3045`warn`. Clients that predate this field can safely ignore it; the
3046same mapping is served on demand at `GET /status/{server_id}/check-severities`.*/
3047    pub check_severities: ::std::collections::HashMap<
3048        ::std::string::String,
3049        CheckSeverity,
3050    >,
3051    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3052    pub machine: ::std::option::Option<TargetResponse>,
3053    /**What this server is entitled to do with names: the domains its group
3054controls, the grants it holds, whether it is paused, and the names and
3055certificates it already has. A server-wide fact, so returned to every
3056source — an agent already reporting status learns of a new domain or a
3057newly granted permission without asking separately. Identical to what
3058`GET /names/entitlements` returns. Clients that predate this field can
3059safely ignore it.*/
3060    pub names: Entitlements,
3061    /**The server's effective tags: its own tags overlaid on its group's,
3062plus the synthetic read-only `canopy:` tags and effective `billing.*`
3063labels. Identical to what the standalone `GET /tags` endpoint
3064returns — see that endpoint for the full contract. Clients that
3065predate this field can safely ignore it.
3066
3067On a push in the current format this is the machine's, the push being
3068the machine's; each application's own are under `applications`.*/
3069    pub tags: TagMap,
3070}
3071///Free-form key/value tags, as a JSON object whose values are all strings.
3072///
3073/// <details><summary>JSON schema</summary>
3074///
3075/// ```json
3076///{
3077///  "description": "Free-form key/value tags, as a JSON object whose values are all strings.",
3078///  "type": "object",
3079///  "additionalProperties": {
3080///    "type": "string"
3081///  }
3082///}
3083/// ```
3084/// </details>
3085#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3086#[serde(transparent)]
3087pub struct TagMap(
3088    pub ::std::collections::HashMap<::std::string::String, ::std::string::String>,
3089);
3090impl ::std::ops::Deref for TagMap {
3091    type Target = ::std::collections::HashMap<
3092        ::std::string::String,
3093        ::std::string::String,
3094    >;
3095    fn deref(
3096        &self,
3097    ) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> {
3098        &self.0
3099    }
3100}
3101impl ::std::convert::From<TagMap>
3102for ::std::collections::HashMap<::std::string::String, ::std::string::String> {
3103    fn from(value: TagMap) -> Self {
3104        value.0
3105    }
3106}
3107impl ::std::convert::From<
3108    ::std::collections::HashMap<::std::string::String, ::std::string::String>,
3109> for TagMap {
3110    fn from(
3111        value: ::std::collections::HashMap<::std::string::String, ::std::string::String>,
3112    ) -> Self {
3113        Self(value)
3114    }
3115}
3116/**One target's material within a push: its health checks and its detail.
3117
3118A machine and an application are described the same way, so the two grains
3119read alike and a reporter builds one shape for both.*/
3120///
3121/// <details><summary>JSON schema</summary>
3122///
3123/// ```json
3124///{
3125///  "description": "One target's material within a push: its health checks and its detail.\n\nA machine and an application are described the same way, so the two grains\nread alike and a reporter builds one shape for both.",
3126///  "type": "object",
3127///  "required": [
3128///    "detail"
3129///  ],
3130///  "properties": {
3131///    "detail": {
3132///      "description": "Everything the reporter has to say about this target beyond its checks.\nRecorded verbatim against the target it was attached to.",
3133///      "type": "object"
3134///    },
3135///    "health": {
3136///      "description": "This target's checks. Absent and empty mean the same thing — the source\ncurrently has no checks for this target — which recovers every check it\npreviously reported for it.",
3137///      "type": [
3138///        "array",
3139///        "null"
3140///      ],
3141///      "items": {
3142///        "$ref": "#/components/schemas/HealthCheck"
3143///      }
3144///    }
3145///  }
3146///}
3147/// ```
3148/// </details>
3149#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3150#[derive(::bon::Builder)]
3151#[non_exhaustive]
3152pub struct TargetReport {
3153    /**Everything the reporter has to say about this target beyond its checks.
3154Recorded verbatim against the target it was attached to.*/
3155    pub detail: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
3156    /**This target's checks. Absent and empty mean the same thing — the source
3157currently has no checks for this target — which recovers every check it
3158previously reported for it.*/
3159    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3160    pub health: ::std::option::Option<::std::vec::Vec<HealthCheck>>,
3161}
3162///What Canopy answers about one target the push described.
3163///
3164/// <details><summary>JSON schema</summary>
3165///
3166/// ```json
3167///{
3168///  "description": "What Canopy answers about one target the push described.",
3169///  "type": "object",
3170///  "required": [
3171///    "check_severities",
3172///    "tags"
3173///  ],
3174///  "properties": {
3175///    "check_severities": {
3176///      "description": "How every check this reporter can file against this target is graded,\non the same terms as the top-level `check_severities`. Keyed by bare\ncheck name, so a machine check and an application check of the same\nname are each answered under the target they belong to.",
3177///      "type": "object",
3178///      "additionalProperties": {
3179///        "$ref": "#/components/schemas/CheckSeverity"
3180///      },
3181///      "propertyNames": {
3182///        "type": "string"
3183///      }
3184///    },
3185///    "tags": {
3186///      "description": "This target's effective tags, on the same terms as the top-level\n`tags`.",
3187///      "$ref": "#/components/schemas/TagMap"
3188///    }
3189///  }
3190///}
3191/// ```
3192/// </details>
3193#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3194#[derive(::bon::Builder)]
3195#[non_exhaustive]
3196pub struct TargetResponse {
3197    /**How every check this reporter can file against this target is graded,
3198on the same terms as the top-level `check_severities`. Keyed by bare
3199check name, so a machine check and an application check of the same
3200name are each answered under the target they belong to.*/
3201    pub check_severities: ::std::collections::HashMap<
3202        ::std::string::String,
3203        CheckSeverity,
3204    >,
3205    /**This target's effective tags, on the same terms as the top-level
3206`tags`.*/
3207    pub tags: TagMap,
3208}
3209/**A URL, given as a plain string. Any trailing slash is stripped when the
3210value is returned.*/
3211///
3212/// <details><summary>JSON schema</summary>
3213///
3214/// ```json
3215///{
3216///  "description": "A URL, given as a plain string. Any trailing slash is stripped when the\nvalue is returned.",
3217///  "type": "string",
3218///  "format": "uri"
3219///}
3220/// ```
3221/// </details>
3222#[derive(
3223    ::serde::Deserialize,
3224    ::serde::Serialize,
3225    Clone,
3226    Debug,
3227    Eq,
3228    Hash,
3229    Ord,
3230    PartialEq,
3231    PartialOrd
3232)]
3233#[serde(transparent)]
3234pub struct UrlField(pub ::std::string::String);
3235impl ::std::ops::Deref for UrlField {
3236    type Target = ::std::string::String;
3237    fn deref(&self) -> &::std::string::String {
3238        &self.0
3239    }
3240}
3241impl ::std::convert::From<UrlField> for ::std::string::String {
3242    fn from(value: UrlField) -> Self {
3243        value.0
3244    }
3245}
3246impl ::std::convert::From<::std::string::String> for UrlField {
3247    fn from(value: ::std::string::String) -> Self {
3248        Self(value)
3249    }
3250}
3251impl ::std::str::FromStr for UrlField {
3252    type Err = ::std::convert::Infallible;
3253    fn from_str(value: &str) -> ::std::result::Result<Self, Self::Err> {
3254        Ok(Self(value.to_string()))
3255    }
3256}
3257impl ::std::fmt::Display for UrlField {
3258    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
3259        self.0.fmt(f)
3260    }
3261}
3262///Report of a restore attempt and the health of the resulting replica.
3263///
3264/// <details><summary>JSON schema</summary>
3265///
3266/// ```json
3267///{
3268///  "description": "Report of a restore attempt and the health of the resulting replica.",
3269///  "type": "object",
3270///  "required": [
3271///    "group",
3272///    "intent",
3273///    "observed_at",
3274///    "outcome",
3275///    "replica_healthy",
3276///    "replica_id",
3277///    "type"
3278///  ],
3279///  "properties": {
3280///    "error": {
3281///      "description": "Human-readable error detail, when the restore failed.",
3282///      "type": [
3283///        "string",
3284///        "null"
3285///      ]
3286///    },
3287///    "group": {
3288///      "description": "The server group whose backup was restored.",
3289///      "type": "string",
3290///      "format": "uuid"
3291///    },
3292///    "health_details": {
3293///      "description": "Arbitrary structured health data to record alongside the report\n(database statistics, whether indexes needed rebuilding, and so on).\nStored and displayed as-is."
3294///    },
3295///    "intent": {
3296///      "description": "The restore intent this attempt was performed under.",
3297///      "type": "string"
3298///    },
3299///    "machine_id": {
3300///      "description": "The machine whose backup was restored, from the worklist entry's\n`machine_id`.\n\nOptional only so a reporter built against the earlier shape, which knew\nthis as `server_id`, is still accepted; one of the two must be present.",
3301///      "type": [
3302///        "string",
3303///        "null"
3304///      ],
3305///      "format": "uuid"
3306///    },
3307///    "migration": {
3308///      "oneOf": [
3309///        {
3310///          "type": "null"
3311///        },
3312///        {
3313///          "description": "What the migrations did, for a report under a `migrate` intent. Omit for\nevery other intent.",
3314///          "$ref": "#/components/schemas/MigrationArgs"
3315///        }
3316///      ]
3317///    },
3318///    "observed_at": {
3319///      "description": "When the restore result was observed, as an RFC 3339 timestamp.",
3320///      "type": "string"
3321///    },
3322///    "outcome": {
3323///      "description": "Whether the restore succeeded (`success`) or failed (`failure`).",
3324///      "type": "string"
3325///    },
3326///    "postgres_version": {
3327///      "description": "Version of the PostgreSQL server the data was restored into, if\napplicable.",
3328///      "type": [
3329///        "string",
3330///        "null"
3331///      ]
3332///    },
3333///    "redaction": {
3334///      "oneOf": [
3335///        {
3336///          "type": "null"
3337///        },
3338///        {
3339///          "description": "What the masking manifest did, for a replica that redacts. Omit for a\nreplica that doesn't.",
3340///          "$ref": "#/components/schemas/RedactionArgs"
3341///        }
3342///      ]
3343///    },
3344///    "replica_healthy": {
3345///      "description": "Whether the restored database came up healthy and passed readiness\nchecks. A replica only counts as verified when the outcome is\n`success` and this is `true`.",
3346///      "type": "boolean"
3347///    },
3348///    "replica_id": {
3349///      "description": "The declaration this report concerns, taken from the worklist entry's\n`replica_id`. Required: several replicas can share one group, machine,\ntype, and intent, so a report that named no declaration could not be\nattributed to one of them.",
3350///      "type": "string",
3351///      "format": "uuid"
3352///    },
3353///    "run_id": {
3354///      "description": "This must be the run-uuid the client minted for this run.\nThe field is optional only so older clients don't break; it WILL be made\nmandatory in future.",
3355///      "type": [
3356///        "string",
3357///        "null"
3358///      ],
3359///      "format": "uuid"
3360///    },
3361///    "s3_received_payload_bytes": {
3362///      "description": "Bytes of decoded object payload received from S3 during the restore.",
3363///      "type": [
3364///        "integer",
3365///        "null"
3366///      ],
3367///      "format": "int64"
3368///    },
3369///    "s3_received_raw_bytes": {
3370///      "description": "Bytes of raw HTTP traffic received from S3 during the restore,\nincluding protocol overhead.",
3371///      "type": [
3372///        "integer",
3373///        "null"
3374///      ],
3375///      "format": "int64"
3376///    },
3377///    "s3_sent_payload_bytes": {
3378///      "description": "Bytes of decoded object payload sent to S3 during the restore.",
3379///      "type": [
3380///        "integer",
3381///        "null"
3382///      ],
3383///      "format": "int64"
3384///    },
3385///    "s3_sent_raw_bytes": {
3386///      "description": "Bytes of raw HTTP traffic sent to S3 during the restore, including\nprotocol and signing overhead. Omit when traffic was not measured.",
3387///      "type": [
3388///        "integer",
3389///        "null"
3390///      ],
3391///      "format": "int64"
3392///    },
3393///    "server_id": {
3394///      "description": "The same machine under the name this field carried when a server was a\nbox and the software on it at once.\n\nDeprecated in favour of `machine_id`. A report naming only this is\naccepted and read as the machine, since a machine that predates the\nsplit took its application's id. Naming both is an error rather than a\nsilent preference, because a reporter that disagrees with itself about\nwhat it restored has not been understood.",
3395///      "deprecated": true,
3396///      "type": [
3397///        "string",
3398///        "null"
3399///      ],
3400///      "format": "uuid"
3401///    },
3402///    "snapshot_id": {
3403///      "description": "Identifier of the snapshot that was restored. Omit on a failure that\nnever got as far as selecting a snapshot.",
3404///      "type": [
3405///        "string",
3406///        "null"
3407///      ]
3408///    },
3409///    "type": {
3410///      "description": "The backup type that was restored (e.g. `tamanu-postgres`).",
3411///      "type": "string"
3412///    }
3413///  }
3414///}
3415/// ```
3416/// </details>
3417#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3418#[derive(::bon::Builder)]
3419#[non_exhaustive]
3420pub struct VerificationArgs {
3421    ///Human-readable error detail, when the restore failed.
3422    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3423    pub error: ::std::option::Option<::std::string::String>,
3424    ///The server group whose backup was restored.
3425    pub group: ::uuid::Uuid,
3426    /**Arbitrary structured health data to record alongside the report
3427(database statistics, whether indexes needed rebuilding, and so on).
3428Stored and displayed as-is.*/
3429    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3430    pub health_details: ::std::option::Option<::serde_json::Value>,
3431    ///The restore intent this attempt was performed under.
3432    pub intent: ::std::string::String,
3433    /**The machine whose backup was restored, from the worklist entry's
3434`machine_id`.
3435
3436Optional only so a reporter built against the earlier shape, which knew
3437this as `server_id`, is still accepted; one of the two must be present.*/
3438    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3439    pub machine_id: ::std::option::Option<::uuid::Uuid>,
3440    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3441    pub migration: ::std::option::Option<MigrationArgs>,
3442    ///When the restore result was observed, as an RFC 3339 timestamp.
3443    pub observed_at: ::std::string::String,
3444    ///Whether the restore succeeded (`success`) or failed (`failure`).
3445    pub outcome: ::std::string::String,
3446    /**Version of the PostgreSQL server the data was restored into, if
3447applicable.*/
3448    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3449    pub postgres_version: ::std::option::Option<::std::string::String>,
3450    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3451    pub redaction: ::std::option::Option<RedactionArgs>,
3452    /**Whether the restored database came up healthy and passed readiness
3453checks. A replica only counts as verified when the outcome is
3454`success` and this is `true`.*/
3455    pub replica_healthy: bool,
3456    /**The declaration this report concerns, taken from the worklist entry's
3457`replica_id`. Required: several replicas can share one group, machine,
3458type, and intent, so a report that named no declaration could not be
3459attributed to one of them.*/
3460    pub replica_id: ::uuid::Uuid,
3461    /**This must be the run-uuid the client minted for this run.
3462The field is optional only so older clients don't break; it WILL be made
3463mandatory in future.*/
3464    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3465    pub run_id: ::std::option::Option<::uuid::Uuid>,
3466    ///Bytes of decoded object payload received from S3 during the restore.
3467    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3468    pub s3_received_payload_bytes: ::std::option::Option<i64>,
3469    /**Bytes of raw HTTP traffic received from S3 during the restore,
3470including protocol overhead.*/
3471    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3472    pub s3_received_raw_bytes: ::std::option::Option<i64>,
3473    ///Bytes of decoded object payload sent to S3 during the restore.
3474    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3475    pub s3_sent_payload_bytes: ::std::option::Option<i64>,
3476    /**Bytes of raw HTTP traffic sent to S3 during the restore, including
3477protocol and signing overhead. Omit when traffic was not measured.*/
3478    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3479    pub s3_sent_raw_bytes: ::std::option::Option<i64>,
3480    /**The same machine under the name this field carried when a server was a
3481box and the software on it at once.
3482
3483Deprecated in favour of `machine_id`. A report naming only this is
3484accepted and read as the machine, since a machine that predates the
3485split took its application's id. Naming both is an error rather than a
3486silent preference, because a reporter that disagrees with itself about
3487what it restored has not been understood.*/
3488    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3489    pub server_id: ::std::option::Option<::uuid::Uuid>,
3490    /**Identifier of the snapshot that was restored. Omit on a failure that
3491never got as far as selecting a snapshot.*/
3492    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3493    pub snapshot_id: ::std::option::Option<::std::string::String>,
3494    ///The backup type that was restored (e.g. `tamanu-postgres`).
3495    #[serde(rename = "type")]
3496    pub type_: ::std::string::String,
3497}
3498/**A release version of the monitored software, with its publication
3499status and changelog.*/
3500///
3501/// <details><summary>JSON schema</summary>
3502///
3503/// ```json
3504///{
3505///  "description": "A release version of the monitored software, with its publication\nstatus and changelog.",
3506///  "type": "object",
3507///  "required": [
3508///    "changelog",
3509///    "created_at",
3510///    "id",
3511///    "major",
3512///    "minor",
3513///    "patch",
3514///    "status",
3515///    "updated_at"
3516///  ],
3517///  "properties": {
3518///    "changelog": {
3519///      "description": "Changelog text for this version, as Markdown.",
3520///      "type": "string"
3521///    },
3522///    "created_at": {
3523///      "description": "When the version record was created.",
3524///      "$ref": "#/definitions/CanopyTimestamp"
3525///    },
3526///    "device_id": {
3527///      "description": "The releaser device that published this version, if it was published\nby a device rather than created by an operator.",
3528///      "type": [
3529///        "string",
3530///        "null"
3531///      ],
3532///      "format": "uuid"
3533///    },
3534///    "id": {
3535///      "description": "Unique identifier of the version.",
3536///      "type": "string",
3537///      "format": "uuid"
3538///    },
3539///    "major": {
3540///      "description": "Major version number.",
3541///      "type": "integer",
3542///      "format": "int32"
3543///    },
3544///    "minor": {
3545///      "description": "Minor version number.",
3546///      "type": "integer",
3547///      "format": "int32"
3548///    },
3549///    "patch": {
3550///      "description": "Patch version number.",
3551///      "type": "integer",
3552///      "format": "int32"
3553///    },
3554///    "status": {
3555///      "description": "Publication status: `draft`, `published`, or `yanked`.",
3556///      "$ref": "#/components/schemas/VersionStatus"
3557///    },
3558///    "updated_at": {
3559///      "description": "When the version record was last changed.",
3560///      "$ref": "#/definitions/CanopyTimestamp"
3561///    }
3562///  }
3563///}
3564/// ```
3565/// </details>
3566#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3567#[derive(::bon::Builder)]
3568#[non_exhaustive]
3569pub struct Version {
3570    ///Changelog text for this version, as Markdown.
3571    pub changelog: ::std::string::String,
3572    ///When the version record was created.
3573    pub created_at: ::jiff::Timestamp,
3574    /**The releaser device that published this version, if it was published
3575by a device rather than created by an operator.*/
3576    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3577    pub device_id: ::std::option::Option<::uuid::Uuid>,
3578    ///Unique identifier of the version.
3579    pub id: ::uuid::Uuid,
3580    ///Major version number.
3581    pub major: i32,
3582    ///Minor version number.
3583    pub minor: i32,
3584    ///Patch version number.
3585    pub patch: i32,
3586    ///Publication status: `draft`, `published`, or `yanked`.
3587    pub status: VersionStatus,
3588    ///When the version record was last changed.
3589    pub updated_at: ::jiff::Timestamp,
3590}
3591///Publication status of a release version.
3592///
3593/// <details><summary>JSON schema</summary>
3594///
3595/// ```json
3596///{
3597///  "description": "Publication status of a release version.",
3598///  "type": "string",
3599///  "enum": [
3600///    "draft",
3601///    "published",
3602///    "yanked"
3603///  ]
3604///}
3605/// ```
3606/// </details>
3607#[derive(
3608    ::serde::Deserialize,
3609    ::serde::Serialize,
3610    Clone,
3611    Copy,
3612    Debug,
3613    Eq,
3614    Hash,
3615    Ord,
3616    PartialEq,
3617    PartialOrd
3618)]
3619pub enum VersionStatus {
3620    #[serde(rename = "draft")]
3621    Draft,
3622    #[serde(rename = "published")]
3623    Published,
3624    #[serde(rename = "yanked")]
3625    Yanked,
3626}
3627impl ::std::fmt::Display for VersionStatus {
3628    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
3629        match *self {
3630            Self::Draft => f.write_str("draft"),
3631            Self::Published => f.write_str("published"),
3632            Self::Yanked => f.write_str("yanked"),
3633        }
3634    }
3635}
3636impl ::std::str::FromStr for VersionStatus {
3637    type Err = self::error::ConversionError;
3638    fn from_str(
3639        value: &str,
3640    ) -> ::std::result::Result<Self, self::error::ConversionError> {
3641        match value {
3642            "draft" => Ok(Self::Draft),
3643            "published" => Ok(Self::Published),
3644            "yanked" => Ok(Self::Yanked),
3645            _ => Err("invalid value".into()),
3646        }
3647    }
3648}
3649impl ::std::convert::TryFrom<&str> for VersionStatus {
3650    type Error = self::error::ConversionError;
3651    fn try_from(
3652        value: &str,
3653    ) -> ::std::result::Result<Self, self::error::ConversionError> {
3654        value.parse()
3655    }
3656}
3657impl ::std::convert::TryFrom<&::std::string::String> for VersionStatus {
3658    type Error = self::error::ConversionError;
3659    fn try_from(
3660        value: &::std::string::String,
3661    ) -> ::std::result::Result<Self, self::error::ConversionError> {
3662        value.parse()
3663    }
3664}
3665impl ::std::convert::TryFrom<::std::string::String> for VersionStatus {
3666    type Error = self::error::ConversionError;
3667    fn try_from(
3668        value: ::std::string::String,
3669    ) -> ::std::result::Result<Self, self::error::ConversionError> {
3670        value.parse()
3671    }
3672}
3673/**A release version as returned by the version-listing endpoints: the
3674version numbers, publication status, and changelog.*/
3675///
3676/// <details><summary>JSON schema</summary>
3677///
3678/// ```json
3679///{
3680///  "description": "A release version as returned by the version-listing endpoints: the\nversion numbers, publication status, and changelog.",
3681///  "type": "object",
3682///  "required": [
3683///    "changelog",
3684///    "id",
3685///    "major",
3686///    "minor",
3687///    "patch",
3688///    "status"
3689///  ],
3690///  "properties": {
3691///    "changelog": {
3692///      "description": "Changelog text for this version, as Markdown.",
3693///      "type": "string"
3694///    },
3695///    "id": {
3696///      "description": "Unique identifier of the version.",
3697///      "type": "string",
3698///      "format": "uuid"
3699///    },
3700///    "major": {
3701///      "description": "Major version number.",
3702///      "type": "integer",
3703///      "format": "int32"
3704///    },
3705///    "minor": {
3706///      "description": "Minor version number.",
3707///      "type": "integer",
3708///      "format": "int32"
3709///    },
3710///    "patch": {
3711///      "description": "Patch version number.",
3712///      "type": "integer",
3713///      "format": "int32"
3714///    },
3715///    "status": {
3716///      "description": "Publication status: `draft`, `published`, or `yanked`.",
3717///      "$ref": "#/components/schemas/VersionStatus"
3718///    }
3719///  }
3720///}
3721/// ```
3722/// </details>
3723#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3724#[derive(::bon::Builder)]
3725#[non_exhaustive]
3726pub struct ViewVersion {
3727    ///Changelog text for this version, as Markdown.
3728    pub changelog: ::std::string::String,
3729    ///Unique identifier of the version.
3730    pub id: ::uuid::Uuid,
3731    ///Major version number.
3732    pub major: i32,
3733    ///Minor version number.
3734    pub minor: i32,
3735    ///Patch version number.
3736    pub patch: i32,
3737    ///Publication status: `draft`, `published`, or `yanked`.
3738    pub status: VersionStatus,
3739}
3740/**One replica the consumer device should currently maintain: an operator
3741declaration expanded against a single server, carrying the snapshot to
3742restore and the repository coordinates to find it. S3 credentials and the
3743repository passphrase are obtained separately via
3744`POST /restore-credentials`.*/
3745///
3746/// <details><summary>JSON schema</summary>
3747///
3748/// ```json
3749///{
3750///  "description": "One replica the consumer device should currently maintain: an operator\ndeclaration expanded against a single server, carrying the snapshot to\nrestore and the repository coordinates to find it. S3 credentials and the\nrepository passphrase are obtained separately via\n`POST /restore-credentials`.",
3751///  "type": "object",
3752///  "required": [
3753///    "bucket",
3754///    "group_id",
3755///    "intent",
3756///    "machine_id",
3757///    "name",
3758///    "params",
3759///    "prefix",
3760///    "region",
3761///    "replica_id",
3762///    "server_id",
3763///    "storage",
3764///    "type"
3765///  ],
3766///  "properties": {
3767///    "application_type": {
3768///      "description": "For a `migrate` entry, the type of application whose candidate version is\nunder test. Absent on any other entry.\n\nA snapshot is a machine's and a candidate version is an application's, so\na migration test names both: it restores the machine's data and applies\nthat application's next version's migrations to it. The workload is named\nby its type, which is what the reporter itself said it was; Canopy's own\nidentifier for an application is internal and never on the wire.",
3769///      "type": [
3770///        "string",
3771///        "null"
3772///      ]
3773///    },
3774///    "bucket": {
3775///      "description": "Name of the S3 bucket holding the group's backup repository.",
3776///      "type": "string"
3777///    },
3778///    "group_id": {
3779///      "description": "The server group whose backup repository holds the snapshot.",
3780///      "type": "string",
3781///      "format": "uuid"
3782///    },
3783///    "intent": {
3784///      "description": "The restore intent this entry is for; one of the intents this device\nadvertised via `POST /restore-capabilities`.",
3785///      "type": "string"
3786///    },
3787///    "machine_id": {
3788///      "description": "The machine whose backup should be restored. Echo it back in reports.",
3789///      "type": "string",
3790///      "format": "uuid"
3791///    },
3792///    "name": {
3793///      "description": "Operator-assigned label for the declaration.",
3794///      "type": "string"
3795///    },
3796///    "overdue_after_seconds": {
3797///      "description": "Bound, in whole seconds, after which the replica counts as overdue;\n`null` means no bound. Interpreted per the intent's semantics: for a\nrun-once (`once`) intent, how long the latest snapshot may go without a\nhealthy verification report; for a standing replica, how stale its last\nhealthy report may be.",
3798///      "type": [
3799///        "integer",
3800///        "null"
3801///      ],
3802///      "format": "int64"
3803///    },
3804///    "params": {
3805///      "description": "Resolved parameter values for this replica: one key per parameter the\nintent advertises. Parameters the operator left unset carry the\nintent's declared default, or JSON `null` when there is none.",
3806///      "type": "object"
3807///    },
3808///    "prefix": {
3809///      "description": "Key prefix within the bucket under which the repository lives. Normally\nempty (the repository is at the bucket root).",
3810///      "type": "string"
3811///    },
3812///    "region": {
3813///      "description": "AWS region of the bucket.",
3814///      "type": "string"
3815///    },
3816///    "replica_id": {
3817///      "description": "Identifier of the declaration this entry was expanded from. Echo it\nback in `POST /restore-verification` reports.",
3818///      "type": "string",
3819///      "format": "uuid"
3820///    },
3821///    "server_id": {
3822///      "description": "The same machine under the name this field carried when a server was a\nbox and the software on it at once.\n\nDeprecated in favour of `machine_id`, and emitted so a consumer built\nagainst the earlier shape keeps working across the transition. Every\nmachine that predates the split took its application's id, so for those\nthe two values are equal; a machine created since has no server to be.",
3823///      "deprecated": true,
3824///      "type": "string",
3825///      "format": "uuid"
3826///    },
3827///    "snapshot_at": {
3828///      "description": "When that snapshot was reported, as an RFC 3339 timestamp; `null` if\nunknown.",
3829///      "type": [
3830///        "string",
3831///        "null"
3832///      ]
3833///    },
3834///    "snapshot_id": {
3835///      "description": "Identifier of the snapshot to restore — the latest successful backup\nfor this server and type. `null` when no successful backup is known\nyet.",
3836///      "type": [
3837///        "string",
3838///        "null"
3839///      ]
3840///    },
3841///    "storage": {
3842///      "description": "Kind of storage backend. Always `\"s3\"`.",
3843///      "type": "string"
3844///    },
3845///    "target_version": {
3846///      "description": "For a `migrate` intent, the version whose schema migrations to apply\nafter restoring. Obtain them from that version's published artefacts, the\nsame way a server being upgraded does. `null` for every other intent.",
3847///      "type": [
3848///        "string",
3849///        "null"
3850///      ]
3851///    },
3852///    "target_version_id": {
3853///      "description": "Identifier of that version. Echo it back in the migration-test report.",
3854///      "type": [
3855///        "string",
3856///        "null"
3857///      ],
3858///      "format": "uuid"
3859///    },
3860///    "type": {
3861///      "description": "The backup type to restore (e.g. `tamanu-postgres`).",
3862///      "type": "string"
3863///    }
3864///  }
3865///}
3866/// ```
3867/// </details>
3868#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
3869#[derive(::bon::Builder)]
3870#[non_exhaustive]
3871pub struct WorklistEntry {
3872    /**For a `migrate` entry, the type of application whose candidate version is
3873under test. Absent on any other entry.
3874
3875A snapshot is a machine's and a candidate version is an application's, so
3876a migration test names both: it restores the machine's data and applies
3877that application's next version's migrations to it. The workload is named
3878by its type, which is what the reporter itself said it was; Canopy's own
3879identifier for an application is internal and never on the wire.*/
3880    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3881    pub application_type: ::std::option::Option<::std::string::String>,
3882    ///Name of the S3 bucket holding the group's backup repository.
3883    pub bucket: ::std::string::String,
3884    ///The server group whose backup repository holds the snapshot.
3885    pub group_id: ::uuid::Uuid,
3886    /**The restore intent this entry is for; one of the intents this device
3887advertised via `POST /restore-capabilities`.*/
3888    pub intent: ::std::string::String,
3889    ///The machine whose backup should be restored. Echo it back in reports.
3890    pub machine_id: ::uuid::Uuid,
3891    ///Operator-assigned label for the declaration.
3892    pub name: ::std::string::String,
3893    /**Bound, in whole seconds, after which the replica counts as overdue;
3894`null` means no bound. Interpreted per the intent's semantics: for a
3895run-once (`once`) intent, how long the latest snapshot may go without a
3896healthy verification report; for a standing replica, how stale its last
3897healthy report may be.*/
3898    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3899    pub overdue_after_seconds: ::std::option::Option<i64>,
3900    /**Resolved parameter values for this replica: one key per parameter the
3901intent advertises. Parameters the operator left unset carry the
3902intent's declared default, or JSON `null` when there is none.*/
3903    pub params: ::serde_json::Map<::std::string::String, ::serde_json::Value>,
3904    /**Key prefix within the bucket under which the repository lives. Normally
3905empty (the repository is at the bucket root).*/
3906    pub prefix: ::std::string::String,
3907    ///AWS region of the bucket.
3908    pub region: ::std::string::String,
3909    /**Identifier of the declaration this entry was expanded from. Echo it
3910back in `POST /restore-verification` reports.*/
3911    pub replica_id: ::uuid::Uuid,
3912    /**The same machine under the name this field carried when a server was a
3913box and the software on it at once.
3914
3915Deprecated in favour of `machine_id`, and emitted so a consumer built
3916against the earlier shape keeps working across the transition. Every
3917machine that predates the split took its application's id, so for those
3918the two values are equal; a machine created since has no server to be.*/
3919    pub server_id: ::uuid::Uuid,
3920    /**When that snapshot was reported, as an RFC 3339 timestamp; `null` if
3921unknown.*/
3922    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3923    pub snapshot_at: ::std::option::Option<::std::string::String>,
3924    /**Identifier of the snapshot to restore — the latest successful backup
3925for this server and type. `null` when no successful backup is known
3926yet.*/
3927    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3928    pub snapshot_id: ::std::option::Option<::std::string::String>,
3929    ///Kind of storage backend. Always `"s3"`.
3930    pub storage: ::std::string::String,
3931    /**For a `migrate` intent, the version whose schema migrations to apply
3932after restoring. Obtain them from that version's published artefacts, the
3933same way a server being upgraded does. `null` for every other intent.*/
3934    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3935    pub target_version: ::std::option::Option<::std::string::String>,
3936    ///Identifier of that version. Echo it back in the migration-test report.
3937    #[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
3938    pub target_version_id: ::std::option::Option<::uuid::Uuid>,
3939    ///The backup type to restore (e.g. `tamanu-postgres`).
3940    #[serde(rename = "type")]
3941    pub type_: ::std::string::String,
3942}
3943
3944/// One method per operation in canopy's OpenAPI document.
3945impl<T: crate::CanopyTransport> crate::CanopyClient<T> {
3946	/// List publicly-listed central applications.
3947	///
3948	/// The `/applications` name for [`list`], answering identically.
3949	///
3950	/// `GET /applications`
3951	pub async fn applications(&self) -> crate::Result<::std::vec::Vec<PublicServer>> {
3952		self.call_json(::http::Method::GET, "/applications", None::<&()>).await
3953	}
3954	/// Get the calling identity and the box it is enrolled as.
3955	///
3956	/// The `/applications` name for [`self_identity`], answering identically.
3957	///
3958	/// `GET /applications/self`
3959	pub async fn applications_self(&self) -> crate::Result<SelfResponse> {
3960		self.call_json(::http::Method::GET, "/applications/self", None::<&()>).await
3961	}
3962	/// Register a downloadable artifact for a version or version range.
3963	///
3964	/// Requires a device certificate with the releaser role (or admin). The
3965	/// path identifies the version the artifact belongs to — either an exact
3966	/// version (e.g. `2.10.5`) or a semver range pattern (e.g. `2.10.x`,
3967	/// `^2.10.0`) — followed by the artifact's type and target platform. The
3968	/// request body is the plain-text URL clients should download the
3969	/// artifact from.
3970	///
3971	/// When an exact version is given and it doesn't exist yet, it is created
3972	/// automatically as an unpublished draft so the artifact has a version to
3973	/// attach to; publishing that version later (via the version-creation
3974	/// endpoint) is a separate step. When a range pattern is given instead,
3975	/// the artifact isn't tied to one version — it matches whichever
3976	/// published version currently satisfies the range at lookup time.
3977	///
3978	/// Returns the created artifact record. Returns 400 if the version or
3979	/// range syntax can't be parsed.
3980	///
3981	/// `POST /artifacts/{version}/{artifact_type}/{platform}`
3982	pub async fn artifacts(&self, version: &str, artifact_type: &str, platform: &str) -> crate::Result<Artifact> {
3983		self.call_json(::http::Method::POST, &format!("/artifacts/{}/{}/{}", version, artifact_type, platform), None::<&()>).await
3984	}
3985	/// Register the backup types this server can run.
3986	///
3987	/// Declares the set of backup types the calling device is able to execute on
3988	/// its server. Types not seen before are added to the server's capability set,
3989	/// starting out enabled or disabled according to the fleet-wide default for
3990	/// that type (disabled if the type has no default configured). Types already
3991	/// registered keep whatever enabled/disabled state an operator has set for
3992	/// them, so re-registering on every startup is safe and expected.
3993	///
3994	/// Only types that are registered here (and enabled) can later be issued
3995	/// credentials via `POST /backup-credentials`, outside of explicit
3996	/// operator-requested runs.
3997	///
3998	/// Errors: 412 when the calling device is not bound to a live server; 409 when
3999	/// the server is not in a group.
4000	///
4001	/// `POST /backup-capabilities`
4002	pub async fn backup_capabilities(&self, body: &BackupCapabilitiesArgs) -> crate::Result<()> {
4003		self.call_empty(::http::Method::POST, "/backup-capabilities", Some(body)).await
4004	}
4005	/// Mint short-lived S3 credentials for a backup or restore run.
4006	///
4007	/// Issues temporary AWS credentials scoped to the backup storage of the
4008	/// calling server's group, in the `credential_process` output format. With
4009	/// `purpose: backup` the credentials can upload and manage backup data but
4010	/// cannot destroy existing backups; with `purpose: restore` they are strictly
4011	/// read-only. They expire after at most one hour, so request a fresh set for
4012	/// each run rather than caching them. Every issuance is recorded for audit.
4013	///
4014	/// The storage coordinates the credentials apply to (bucket, prefix, region)
4015	/// come from `GET /backup-target`.
4016	///
4017	/// Errors: 409 when the server is not in a group, when the group's backup
4018	/// configuration is not ready, when a `backup` type is neither an enabled
4019	/// capability of this server nor the subject of a pending "backup now" request,
4020	/// or when a `restore` is requested but the server's restore window is not
4021	/// open; 412 when the device is not bound to a live server; 502 when the
4022	/// credential issuer is unavailable or not configured.
4023	///
4024	/// `POST /backup-credentials`
4025	pub async fn backup_credentials(&self, body: &BackupCredentialsArgs) -> crate::Result<CredentialProcessOutput> {
4026		self.call_json(::http::Method::POST, "/backup-credentials", Some(body)).await
4027	}
4028	/// Report progress for a run that is still in flight.
4029	///
4030	/// Optional throughout: a run that never reports progress is recorded and
4031	/// displayed exactly as it is today. Reporting it lets Canopy show how far a
4032	/// long-running backup has got, at what rate, and when it last heard from the
4033	/// device — which for a multi-hour backup is the difference between "running"
4034	/// and "running, and moving".
4035	///
4036	/// **Every counter is cumulative from the start of the run**, not an interval
4037	/// delta. Send totals-so-far each time. A dropped or repeated report then costs
4038	/// only resolution, never the accuracy of a total, and the last report Canopy
4039	/// received can stand in for a figure the final report omits. Omit any counter
4040	/// you do not measure rather than sending zero.
4041	///
4042	/// Canopy timestamps each report on receipt, so no clock agreement is needed —
4043	/// except for `snapshot_taken_at`, which is necessarily the device's own claim
4044	/// about its filesystem.
4045	///
4046	/// Unlike `POST /backup-credentials`, this does not require the group's backup
4047	/// configuration to be ready or the type to be an enabled capability: it
4048	/// describes a run already under way, and refusing it would blind Canopy exactly
4049	/// when something is misconfigured.
4050	///
4051	/// A refused report is never a reason to abandon a run — this is telemetry.
4052	/// Reporting progress for a run that has already been reported complete is
4053	/// accepted rather than refused, so a report racing the completion is not an
4054	/// error.
4055	///
4056	/// Errors: 412 when the calling device is not bound to a live server; 409 when
4057	/// the server is not in a group; 429 when reporting faster than Canopy accepts.
4058	///
4059	/// `POST /backup-progress`
4060	pub async fn backup_progress(&self, body: &ProgressArgs) -> crate::Result<()> {
4061		self.call_empty(::http::Method::POST, "/backup-progress", Some(body)).await
4062	}
4063	/// Report the outcome of a backup or restore run.
4064	///
4065	/// Records the run against the calling server and its group. Send one report
4066	/// per run, on success and on failure alike. Reporting also clears any pending
4067	/// operator-requested run for the same type and purpose — regardless of
4068	/// outcome, since an operator request is for one attempt — so the server's
4069	/// status responses stop asking for it (see the `backup_now` field of the
4070	/// status-push response).
4071	///
4072	/// Errors: 409 when the server is not in a group, or when the `run_id` has
4073	/// already been reported; 412 when the device is not bound to a live server.
4074	///
4075	/// `POST /backup-report`
4076	pub async fn backup_report(&self, body: &ReportArgs) -> crate::Result<()> {
4077		self.call_empty(::http::Method::POST, "/backup-report", Some(body)).await
4078	}
4079	/// Fetch the backup storage target for this server's group.
4080	///
4081	/// Returns the bucket, prefix, region, and repository passphrase the device
4082	/// needs to connect to its group's backup repository. Call it on every run
4083	/// rather than caching the result, as the target can change. S3 credentials
4084	/// are obtained separately via `POST /backup-credentials`.
4085	///
4086	/// Errors: 409 when the server is not in a group or the group's backup
4087	/// configuration is not ready; 412 when the device is not bound to a live
4088	/// server; 502 when the passphrase store is unavailable or not configured.
4089	///
4090	/// `GET /backup-target`
4091	pub async fn backup_target(&self) -> crate::Result<BackupTarget> {
4092		self.call_json(::http::Method::GET, "/backup-target", None::<&()>).await
4093	}
4094	/// List all current bestool SQL snippets.
4095	///
4096	/// Returns the library of named SQL snippets that devices running bestool
4097	/// fetch and run, keyed by snippet name. Only the current version of each
4098	/// snippet is included: if a snippet has been superseded by a newer one
4099	/// under the same name, only the newer version is returned, and
4100	/// soft-deleted snippets are omitted entirely. This endpoint does not
4101	/// require device authentication.
4102	///
4103	/// `GET /bestool/snippets`
4104	pub async fn bestool_snippets(&self) -> crate::Result<::std::collections::HashMap<::std::string::String, SnippetResponse>> {
4105		self.call_json(::http::Method::GET, "/bestool/snippets", None::<&()>).await
4106	}
4107	/// Ask for a certificate, and collect it once there is one.
4108	///
4109	/// The same call does both, and is safe to repeat: a name and key Canopy already
4110	/// holds a certificate for is answered from what it holds rather than ordering
4111	/// again, so a server that lost its local copy costs the authority nothing. A
4112	/// request naming a different key opens a new order.
4113	///
4114	/// Proving control of a name through DNS takes far longer than any client waits
4115	/// mid-handshake, so a first request records the order and answers `pending`;
4116	/// call again to collect. A server is expected to hold a certificate before it
4117	/// needs one rather than to obtain one while a client waits.
4118	///
4119	/// `POST /certificates/request`
4120	pub async fn certificates_request(&self, body: &RequestCertificateArgs) -> crate::Result<CertificateResponse> {
4121		self.call_json(::http::Method::POST, "/certificates/request", Some(body)).await
4122	}
4123	/// Report the calling machine's own identity.
4124	///
4125	/// Resolves the caller from its certificate and returns the box it is enrolled
4126	/// as, together with the applications Canopy holds for that box. A machine
4127	/// authenticates entirely from its certificate, so it never needs these ids to
4128	/// make calls; this endpoint lets one that has lost track of them recover them.
4129	///
4130	/// An identity belongs to at most one machine, so the answer is never
4131	/// ambiguous — unlike `GET /servers/self`, which asks which *application* the
4132	/// caller is and cannot answer for a box running more than one.
4133	///
4134	/// - **401**: no client certificate, or one that matches no known identity.
4135	/// - **412**: the identity is registered but is not enrolled as a machine.
4136	///
4137	/// `GET /machines/self`
4138	pub async fn machines_self(&self) -> crate::Result<MachineSelfResponse> {
4139		self.call_json(::http::Method::GET, "/machines/self", None::<&()>).await
4140	}
4141	/// What this server may act on, and what it already holds.
4142	///
4143	/// Answers the boundary rather than making an agent discover it by being
4144	/// refused: the domains its group controls, the grants it holds, whether it is
4145	/// paused, and the names and certificates it already has. Enough to request a
4146	/// certificate before anything asks for one, and to renew before expiry.
4147	///
4148	/// A server with no grants, or whose group controls no domain, gets an empty
4149	/// answer rather than an error — asking what one may do is not a privileged act.
4150	/// The same content rides on the response to a status push.
4151	///
4152	/// `GET /names/entitlements`
4153	pub async fn names_entitlements(&self) -> crate::Result<Entitlements> {
4154		self.call_json(::http::Method::GET, "/names/entitlements", None::<&()>).await
4155	}
4156	/// Register the addresses a name should resolve to.
4157	///
4158	/// Replaces whatever addresses were registered for the name; an empty list
4159	/// withdraws it. Canopy publishes what it is told — it does not verify that an
4160	/// address is really this server's, the grant being the trust boundary.
4161	///
4162	/// Publishing happens in the background, so the response says what Canopy will
4163	/// publish and what it has published so far rather than waiting for the zone.
4164	///
4165	/// `POST /names/register`
4166	pub async fn names_register(&self, body: &RegisterNameArgs) -> crate::Result<RegisteredName> {
4167		self.call_json(::http::Method::POST, "/names/register", Some(body)).await
4168	}
4169	/// Register the restore intents this device can satisfy.
4170	///
4171	/// Declares the restore intents the calling device supports, replacing any
4172	/// previously advertised set. Only worklist entries whose intent is currently
4173	/// advertised are dispatched to this device via `GET /restore-worklist`, so
4174	/// register on startup and whenever the supported set changes.
4175	///
4176	/// `POST /restore-capabilities`
4177	pub async fn restore_capabilities(&self, body: &RestoreCapabilitiesArgs) -> crate::Result<()> {
4178		self.call_empty(::http::Method::POST, "/restore-capabilities", Some(body)).await
4179	}
4180	/// Mint read-only credentials for a group's backup repository.
4181	///
4182	/// Issues temporary AWS credentials — always strictly read-only, scoped to the
4183	/// group's backup storage — together with the repository passphrase, so the
4184	/// device can read the snapshot named in a worklist entry. Credentials expire
4185	/// after at most one hour; request a fresh set per restore rather than caching
4186	/// them. Every issuance is recorded for audit.
4187	///
4188	/// The device must hold an enabled restore declaration covering the requested
4189	/// group and type (i.e. the pair must appear in its worklist configuration);
4190	/// otherwise the request is rejected with 403.
4191	///
4192	/// Errors: 403 when no enabled declaration authorizes this group and type;
4193	/// 409 when the group has no ready backup configuration; 502 when the
4194	/// credential issuer or the passphrase store is unavailable or not configured.
4195	///
4196	/// `POST /restore-credentials`
4197	pub async fn restore_credentials(&self, body: &RestoreCredentialsArgs) -> crate::Result<RestoreCredentials> {
4198		self.call_json(::http::Method::POST, "/restore-credentials", Some(body)).await
4199	}
4200	/// Report the outcome of a restore attempt and the replica's health.
4201	///
4202	/// Records a verification report for a restore the device performed from its
4203	/// worklist. Send one report per attempt, on success and on failure alike. A
4204	/// report with a `success` outcome and `replica_healthy: true` marks the
4205	/// snapshot as verified; for run-once intents this is what removes the entry
4206	/// from `GET /restore-worklist` until a newer snapshot appears.
4207	///
4208	/// Authorization matches `POST /restore-credentials`: the device must hold an
4209	/// enabled restore declaration covering the reported group and type,
4210	/// otherwise the request is rejected with 403.
4211	///
4212	/// The report names the declaration it is about, and that declaration must
4213	/// still exist and belong to the calling consumer. A replica nothing declares
4214	/// any more is not one Canopy tracks, so a report naming a retired declaration
4215	/// is refused rather than recorded against a replica that could never recover.
4216	///
4217	/// `POST /restore-verification`
4218	pub async fn restore_verification(&self, body: &VerificationArgs) -> crate::Result<()> {
4219		self.call_empty(::http::Method::POST, "/restore-verification", Some(body)).await
4220	}
4221	/// Fetch the full set of replicas this device should maintain.
4222	///
4223	/// Returns the device's complete desired state, computed fresh on every call:
4224	/// each enabled restore declaration whose intent this device currently
4225	/// advertises, expanded into one entry per server it covers. A group-wide
4226	/// declaration expands to every live server in its group; a server-scoped
4227	/// declaration yields a single entry and takes precedence over a group-wide
4228	/// one covering the same server, type, and intent. Entries for groups whose
4229	/// backup configuration is not ready are omitted, and entries for run-once
4230	/// intents disappear once the latest snapshot has a healthy verification
4231	/// report, reappearing when a newer snapshot exists.
4232	///
4233	/// An empty array means there is nothing to do. Poll this endpoint and
4234	/// reconcile: create or refresh the replicas listed, and tear down any the
4235	/// device is maintaining that no longer appear.
4236	///
4237	/// `GET /restore-worklist`
4238	pub async fn restore_worklist(&self) -> crate::Result<::std::vec::Vec<WorklistEntry>> {
4239		self.call_json(::http::Method::GET, "/restore-worklist", None::<&()>).await
4240	}
4241	/// List publicly-listed central applications.
4242	///
4243	/// Returns every central server that has both a public display name and a
4244	/// reachable host configured, ordered by environment tier (production
4245	/// first, then clone, demo, test, dev) and then by name. Used by clients
4246	/// to let a user pick which server to connect to.
4247	///
4248	/// `GET /servers`
4249	pub async fn servers(&self) -> crate::Result<::std::vec::Vec<PublicServer>> {
4250		self.call_json(::http::Method::GET, "/servers", None::<&()>).await
4251	}
4252	/// Start device enrollment against a machine.
4253	///
4254	/// Validates the enrollment token against the given machine and, if valid,
4255	/// issues a short-lived (5 minute) signed challenge bound to the machine
4256	/// ID, the token, and the caller's public key. The device must sign this
4257	/// challenge and submit it to the completion endpoint to finish
4258	/// enrollment; the token itself is validated here but not yet consumed.
4259	///
4260	/// This endpoint is rate-limited per source IP and per target machine; a
4261	/// tripped limit returns 429. Any other failure — an unknown or archived
4262	/// machine, or an invalid or expired token — is surfaced as a generic 403,
4263	/// deliberately not distinguishing which check failed.
4264	///
4265	/// `POST /servers/register/begin`
4266	pub async fn servers_register_begin(&self, body: &BeginArgs) -> crate::Result<BeginResponse> {
4267		self.call_json(::http::Method::POST, "/servers/register/begin", Some(body)).await
4268	}
4269	/// Complete device enrollment by presenting a signed challenge.
4270	///
4271	/// Verifies the signature over the challenge transcript using the public
4272	/// key supplied here, then binds the device to the machine: an existing
4273	/// device re-enrolling with the same key is reused as-is; a device
4274	/// re-enrolling with a different key replaces the machine's previous
4275	/// device (revoking that device's access); otherwise a new device
4276	/// identity is created. On success the device is granted the machine
4277	/// role, the enrollment token is consumed, and the machine is marked as
4278	/// registered.
4279	///
4280	/// Enrollment is refused if the presented public key is already bound to
4281	/// a different live machine. Like the start-enrollment endpoint, this one
4282	/// is rate-limited per source IP and per target machine (429 on a tripped
4283	/// limit) and reports every other kind of failure as a generic 403.
4284	///
4285	/// `POST /servers/register/complete`
4286	pub async fn servers_register_complete(&self, body: &CompleteArgs) -> crate::Result<CompleteResponse> {
4287		self.call_json(::http::Method::POST, "/servers/register/complete", Some(body)).await
4288	}
4289	/// Report the calling device's own identity.
4290	///
4291	/// Deprecated in favour of `GET /machines/self`, which says what runs on the box
4292	/// as well as which box it is.
4293	///
4294	/// Resolves the caller from its device certificate and returns the box it is
4295	/// enrolled as together with its own device ID — the same pair returned when the
4296	/// device completed enrollment. A device authenticates entirely from its
4297	/// certificate, so it never needs these IDs to make calls; this endpoint lets
4298	/// one that has lost track of them recover them.
4299	///
4300	/// The id answered is the box's, not any workload's: an identity belongs to a
4301	/// box, so the answer stays the same however many applications run on it.
4302	///
4303	/// - **401**: the request has no client certificate, or the certificate
4304	///   doesn't match a known device.
4305	/// - **409**: retained for callers that handle it; no longer raised, since an
4306	///   identity is enrolled as at most one box.
4307	/// - **412**: the device is registered but has not yet been attached to a
4308	///   box.
4309	///
4310	/// `GET /servers/self`
4311	pub async fn servers_self(&self) -> crate::Result<SelfResponse> {
4312		self.call_json(::http::Method::GET, "/servers/self", None::<&()>).await
4313	}
4314	/// Submit a status heartbeat for a machine.
4315	///
4316	/// `server_id` in the path is the id the agent was enrolled with, which
4317	/// identifies the machine it runs on. Canopy works out which application on
4318	/// that machine the push describes from the push itself.
4319	///
4320	/// Records a periodic status push against that machine: overall
4321	/// self-reported health, a per-check breakdown, and any free-form extra
4322	/// data. Machine-subject checks and detail file against the machine and the
4323	/// rest against its application. Each failed or warning check opens (or keeps
4324	/// open) an issue at that check's operator-configured severity, and each
4325	/// passed check closes any issue it previously opened; the application's
4326	/// tracked software version is also updated from the payload.
4327	///
4328	/// The calling device must be the one enrolled for this exact machine (or
4329	/// hold the admin role). The response carries only return-path
4330	/// instructions: a `backup_now` list of backup types the server should
4331	/// back up immediately — devices should treat a non-empty list as a
4332	/// prompt to run those backups and report them afterwards — a
4333	/// `check_severities` map describing how canopy classifies each known
4334	/// healthcheck for this server (`skip`/`warn`/`fail`), and the server's
4335	/// effective `tags` (as served by `GET /tags`). The stored status record
4336	/// is not echoed back.
4337	///
4338	/// `POST /status/{server_id}`
4339	pub async fn status(&self, server_id: &str, body: &StatusPayload) -> crate::Result<StatusResponse> {
4340		self.call_json(::http::Method::POST, &format!("/status/{}", server_id), Some(body)).await
4341	}
4342	/// Fetch the effective healthcheck severity mapping for a server.
4343	///
4344	/// Returns, for every healthcheck the `alertd` source reports, how that
4345	/// check is handled for this server: `skip` (the check is silenced for
4346	/// this server — at server or group scope — or its policy ceiling means it
4347	/// never alerts), `warn` (graded at most a warning), or `fail` (failures
4348	/// count as failures). Keys are check names as reported in
4349	/// `health[].check` on status pushes. Only the static policy ceiling is
4350	/// reflected; operator-defined conditional rules are evaluated per push
4351	/// and not included here. The same mapping also rides along every
4352	/// status-push response as `check_severities`, scoped to the pushing
4353	/// source.
4354	///
4355	/// `server_id` in the path is the id the agent was enrolled with, which
4356	/// identifies the machine it runs on.
4357	///
4358	/// The calling device must be the one enrolled for this exact machine (or
4359	/// hold the admin role).
4360	///
4361	/// `GET /status/{server_id}/check-severities`
4362	pub async fn status_check_severities(&self, server_id: &str) -> crate::Result<::std::collections::HashMap<::std::string::String, CheckSeverity>> {
4363		self.call_json(::http::Method::GET, &format!("/status/{}/check-severities", server_id), None::<&()>).await
4364	}
4365	/// Get the tags for the calling device's own server.
4366	///
4367	/// Returns the effective set of tags for the server the calling device is
4368	/// registered as: any tags set on the server itself, overlaid onto any tags
4369	/// inherited from its server group (a tag set on the server takes precedence
4370	/// over a group tag with the same key). If the server isn't in a group,
4371	/// this returns just its own tags.
4372	///
4373	/// The result also includes a few read-only, synthetic tags describing the
4374	/// server, under the reserved `canopy:` key prefix: `canopy:kind`,
4375	/// `canopy:rank` (if the server has one set), and `canopy:group-id` /
4376	/// `canopy:group-name` (if the server belongs to a group). Operators cannot
4377	/// set tags under that prefix, so these never collide with tags you set
4378	/// yourself.
4379	///
4380	/// When the server belongs to a group, the effective `billing.*` labels are
4381	/// also included, matching the labels canopy attributes to cloud resources:
4382	/// `billing.product`, `billing.deployment`, and `billing.stage` (the last
4383	/// derived from *this* server's own rank, and omitted when the server has no
4384	/// rank). The stage is per-server, not the group's highest rank, so a `clone`
4385	/// server reports `billing.stage=clone` rather than the group's `prod`.
4386	///
4387	/// These are only defaults: a stored `billing.*` tag is honoured over the
4388	/// computed value — the server's own tag first, then the group's. So an
4389	/// operator can pin any billing label on a specific server or the whole group.
4390	///
4391	/// - **401**: the request has no client certificate, or the certificate
4392	///   doesn't match a known device.
4393	/// - **409**: the calling device is attached to more than one server, which
4394	///   should not normally happen; contact support if you see this.
4395	/// - **412**: the device is registered but has not yet been attached to a
4396	///   server.
4397	///
4398	/// `GET /tags`
4399	pub async fn tags(&self) -> crate::Result<TagMap> {
4400		self.call_json(::http::Method::GET, "/tags", None::<&()>).await
4401	}
4402	/// List published, ready-to-serve versions.
4403	///
4404	/// Returns every version currently in the published state, excluding any
4405	/// version a recorded known-issue range still covers (whether that issue
4406	/// is still open or has since been fixed in a later patch). Ordered
4407	/// newest first.
4408	///
4409	/// `GET /versions`
4410	pub async fn get_versions(&self) -> crate::Result<::std::vec::Vec<Version>> {
4411		self.call_json(::http::Method::GET, "/versions", None::<&()>).await
4412	}
4413	/// Check for available updates from a given version.
4414	///
4415	/// The path parameter is the caller's currently-installed exact version.
4416	/// For each later minor release line within the same major version,
4417	/// returns the latest published version that hasn't been excluded by a
4418	/// recorded known-issue range — falling back to an older ready patch
4419	/// within that same minor line rather than dropping the line entirely, if
4420	/// the newest patch isn't ready. Clients use this to discover and offer
4421	/// available updates.
4422	///
4423	/// `GET /versions/update-for/{version}`
4424	pub async fn versions_update_for(&self, version: &str) -> crate::Result<::std::vec::Vec<ViewVersion>> {
4425		self.call_json(::http::Method::GET, &format!("/versions/update-for/{}", version), None::<&()>).await
4426	}
4427	/// Yank a version.
4428	///
4429	/// Requires a device certificate with the admin role. Marks the given
4430	/// exact version as yanked, hiding it from listings, update checks, and
4431	/// artifact lookups without deleting its history.
4432	///
4433	/// `DELETE /versions/{version}`
4434	pub async fn delete_versions(&self, version: &str) -> crate::Result<()> {
4435		self.call_empty(::http::Method::DELETE, &format!("/versions/{}", version), None::<&()>).await
4436	}
4437	/// Publish a version with its changelog.
4438	///
4439	/// Requires a device certificate with the releaser role (or admin). The
4440	/// path parameter is the exact version being published (e.g. `2.10.5`);
4441	/// the request body is the changelog for that version, as up to 1 MiB of
4442	/// markdown text.
4443	///
4444	/// If the version already exists in the draft state — for example
4445	/// because an artifact was registered against it before its changelog
4446	/// was written — the draft is published in place, with this changelog
4447	/// replacing whatever it had before. Otherwise a new version is created
4448	/// directly in the published state. Publishing a version that already
4449	/// exists and is not a draft (already published, or yanked) fails.
4450	///
4451	/// Returns the resulting version record.
4452	///
4453	/// `POST /versions/{version}`
4454	pub async fn post_versions(&self, version: &str) -> crate::Result<Version> {
4455		self.call_json(::http::Method::POST, &format!("/versions/{}", version), None::<&()>).await
4456	}
4457	/// List the artifacts available for a version or version range.
4458	///
4459	/// The path parameter accepts either an exact version or a semver range
4460	/// pattern (e.g. `2.10.x`, `^2.10.0`). It resolves to the latest
4461	/// published, ready version satisfying the input, then returns that
4462	/// version's artifacts — both ones registered against the exact version
4463	/// and ones registered against a range pattern that covers it. Returns
4464	/// 404 if no published, ready version matches.
4465	///
4466	/// `GET /versions/{version}/artifacts`
4467	pub async fn versions_artifacts(&self, version: &str) -> crate::Result<::std::vec::Vec<Artifact>> {
4468		self.call_json(::http::Method::GET, &format!("/versions/{}/artifacts", version), None::<&()>).await
4469	}
4470}