pub trait Tracker: Send + Sync {
// Required methods
fn file<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
cred: &'life2 Credential,
draft: &'life3 TicketDraft,
) -> Pin<Box<dyn Future<Output = Result<Filed, TrackerError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn status<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
cred: &'life2 Credential,
external_id: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<TicketStatus, TrackerError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
// Provided method
fn comment<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
_cred: &'life2 Credential,
_external_id: &'life3 str,
_comment: &'life4 TicketComment,
) -> Pin<Box<dyn Future<Output = Result<(), TrackerError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait { ... }
}Expand description
Files tickets into a tracker and reports their status.
Why the credential is a per-call parameter, and not adapter
construction state. Every other adapter in this workspace is built
once with its vendor’s own key — the Resend Mailer holds the Resend
API key, the Stripe Payments holds the Stripe secret, because on this
harness the vendor account belongs to the platform. A tracker is the
opposite: one hosted Worker serves many customer companies, each filing
into its own tracker under its own token. Those per-tenant
credentials live encrypted in cratefield-secrets, are decrypted for
exactly one call, and are dropped — so the credential arrives with the
call, and an adapter holds nothing between calls that a tenant change
could leak. This is the one deliberate deviation from the
Resend/Stripe adapter shape.
dest is a parameter for the same reason: which tracker to file into
is tenant configuration, not deployment configuration.
Required Methods§
Sourcefn file<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
cred: &'life2 Credential,
draft: &'life3 TicketDraft,
) -> Pin<Box<dyn Future<Output = Result<Filed, TrackerError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn file<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
cred: &'life2 Credential,
draft: &'life3 TicketDraft,
) -> Pin<Box<dyn Future<Output = Result<Filed, TrackerError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Files draft into dest, authenticating as the company cred
speaks for. Idempotent on draft.idempotency_key where the tracker
allows it.
§Errors
TrackerError::NotConfigured when no adapter is wired,
TrackerError::Unauthorized when the tracker refuses the
credential, TrackerError::Rejected when the tracker refuses
the call, and TrackerError::Transient with the provider’s
delay, where it gave one, when the call can be retried.
Sourcefn status<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
cred: &'life2 Credential,
external_id: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<TicketStatus, TrackerError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn status<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
cred: &'life2 Credential,
external_id: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<TicketStatus, TrackerError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Provided Methods§
Sourcefn comment<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
_cred: &'life2 Credential,
_external_id: &'life3 str,
_comment: &'life4 TicketComment,
) -> Pin<Box<dyn Future<Output = Result<(), TrackerError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn comment<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
dest: &'life1 Destination,
_cred: &'life2 Credential,
_external_id: &'life3 str,
_comment: &'life4 TicketComment,
) -> Pin<Box<dyn Future<Output = Result<(), TrackerError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Adds comment to the existing ticket external_id in dest —
e.g. linking a duplicate report to the ticket it duplicates, so the
tracker holds one ticket per defect rather than one per report.
The default impl refuses: a tracker that cannot take notes says so
by name — the way the webhook tracker adapter refuses status —
rather than silently dropping the note. Adapters whose tracker has
a comment API override this.
§Errors
The same four as Tracker::file, plus the default
TrackerError::Rejected when the adapter does not serve notes.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".