Documentation
¶
Overview ¶
Package tesedi is a Go client library for the Tesedi partner API.
The API is authenticated via a static API key that is exchanged for a short-lived bearer token at the auth endpoint. The client caches the token internally and refreshes it proactively before expiry.
All public methods accept a context.Context for cancellation and timeout control. Non-2xx responses surface as typed errors that wrap the upstream status code and body.
Index ¶
- Variables
- type APIError
- type Asset
- type AssetPage
- type Client
- func (c *Client) GetContract(ctx context.Context, contractID string) (*Contract, error)
- func (c *Client) GetContractAssets(ctx context.Context, contractID string, opts *ListOptions) (*AssetPage, error)
- func (c *Client) GetContractByNumber(ctx context.Context, number string) (*Contract, error)
- func (c *Client) SearchContracts(ctx context.Context, query string, opts *ListOptions) (*ContractPage, error)
- type Contract
- type ContractPage
- type Date
- type ListOptions
- type Logger
- type Option
- type PageMeta
- type ServiceLevel
Constants ¶
This section is empty.
Variables ¶
var ( // ErrContractNotFound is returned by GetContractByNumber when the search // yields no exact match for the requested contract number. ErrContractNotFound = errors.New("tesedi: contract not found") // ErrAmbiguousContractNumber is returned by GetContractByNumber when the // search yields more than one exact match. This indicates upstream data // inconsistency. ErrAmbiguousContractNumber = errors.New("tesedi: ambiguous contract number") ErrUnauthorized = errors.New("tesedi: unauthorized") // ErrNotFound matches HTTP 404 responses via errors.Is. ErrNotFound = errors.New("tesedi: not found") )
Sentinel errors. Match with errors.Is.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
APIError carries the HTTP status code and raw response body for an unsuccessful API call.
type Asset ¶
type Asset struct {
AssetName string `json:"assetName"`
ProductSKU string `json:"productSku"`
SerialNumber string `json:"serialNumber"`
ServiceGroupSKU string `json:"serviceGroupSku"`
ServiceGroup string `json:"serviceGroup"`
ServiceLevels []ServiceLevel `json:"serviceLevels"`
RetailPrice *float64 `json:"retailPrice"`
StartDate Date `json:"startDate"`
EndDate Date `json:"endDate"`
}
Asset represents an asset covered by a contract.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a Tesedi API client. It is safe for concurrent use by multiple goroutines.
func New ¶
New creates a Tesedi API client.
baseURL is the API root, e.g. "https://example.tesedi.com/api". authURL is the token-exchange endpoint, e.g. "https://example.tesedi.com/auth". apiKey is the static key sent on the auth request as the "apiKey" header.
All three arguments are required; this constructor does not validate them — instead, the first call needing them surfaces any errors.
func (*Client) GetContract ¶
GetContract fetches a contract by its contractId.
The upstream API does not populate the Vendor field on this response — it is only present on list/search responses. Use GetContractByNumber or SearchContracts when Vendor is required.
func (*Client) GetContractAssets ¶
func (c *Client) GetContractAssets(ctx context.Context, contractID string, opts *ListOptions) (*AssetPage, error)
GetContractAssets returns a page of assets covered by the given contract. Pagination is cursor-based; pass ListOptions.Cursor to resume.
func (*Client) GetContractByNumber ¶
GetContractByNumber resolves a contract by its contractNumber.
The upstream API does not support exact lookup by contractNumber, so this method issues a search and validates that exactly one returned row has a contractNumber equal to the requested value. Returns ErrContractNotFound if no exact match exists, or ErrAmbiguousContractNumber if more than one row matches.
func (*Client) SearchContracts ¶
func (c *Client) SearchContracts(ctx context.Context, query string, opts *ListOptions) (*ContractPage, error)
SearchContracts returns a page of contracts matching the query. An empty query lists all contracts visible to the partner. Pagination is cursor-based; pass ListOptions.Cursor to resume.
Note: the Tesedi /contracts endpoint silently ignores unknown query params, so SearchContracts only sets parameters known to be honored upstream.
type Contract ¶
type Contract struct {
ContractID string `json:"contractId"`
ContractNumber string `json:"contractNumber"`
Status string `json:"status"`
GroupID string `json:"groupId"`
SAR string `json:"sar"`
Vendor string `json:"vendor,omitempty"`
Distributor string `json:"distributor"`
Reseller string `json:"reseller"`
EndCustomerName string `json:"endCustomerName"`
EndCustomerID string `json:"endCustomerId"`
StartDate Date `json:"startDate"`
EndDate Date `json:"endDate"`
ResellerPrice float64 `json:"resellerPrice"`
RetailPrice float64 `json:"retailPrice"`
Currency string `json:"currency"`
}
Contract represents a Tesedi service contract.
The Vendor field is populated by list/search responses but omitted by GetContract — that is an upstream API asymmetry, not a bug in this client.
type ContractPage ¶
ContractPage is a single page of contracts.
type Date ¶ added in v0.2.0
Date is a calendar date as it appears on Tesedi contracts and assets. It wraps time.Time and parses Tesedi's "YYYY-MM-DD" wire format.
JSON methods are defined directly on Date because the embedded time.Time's MarshalJSON/UnmarshalJSON expect RFC3339 — leaving them promoted would silently break round-tripping with Tesedi's date-only format.
func (Date) MarshalJSON ¶ added in v0.2.0
MarshalJSON emits Tesedi's "YYYY-MM-DD" wire format. A zero Date emits the empty string so it round-trips cleanly with UnmarshalJSON.
func (*Date) UnmarshalJSON ¶ added in v0.2.0
UnmarshalJSON parses Tesedi's "YYYY-MM-DD" wire format. Empty string and JSON null both decode to a zero Date.
type ListOptions ¶
type ListOptions struct {
Limit int // 0 = upstream default
Cursor string // resume from this cursor
SortBy string // server-defined fields
SortOrder string // "asc" | "desc"
}
ListOptions configures pagination and sorting for list endpoints. The zero value is valid and yields the upstream defaults.
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithHTTPClient ¶
WithHTTPClient sets a custom HTTP client. The default is a new client with a 30s timeout. nil is ignored.
func WithLogger ¶
WithLogger sets a logger for transient retry events. nil disables logging.
func WithRateLimit ¶
WithRateLimit caps requests per minute and per hour. A non-positive value disables that limit. Both limits are evaluated; a request blocks (respecting context) when either bucket is empty.
func WithRetry ¶
WithRetry configures retry behavior for transient failures (network errors, HTTP 5xx, HTTP 429). maxAttempts is the total number of attempts including the first; pass 1 to disable retries. baseBackoff is the initial delay between attempts; subsequent delays double up to a 30s cap with ±25% jitter. HTTP 429 honors the Retry-After header when present.
type PageMeta ¶
type PageMeta struct {
HasNextPage bool `json:"hasNextPage"`
NextCursor string `json:"nextCursor"`
}
PageMeta carries cursor-based pagination metadata.
type ServiceLevel ¶
type ServiceLevel struct {
ServiceLevelSKU string `json:"serviceLevelSku"`
ServiceLevel string `json:"serviceLevel"`
RetailPrice float64 `json:"retailPrice"`
}
ServiceLevel describes one component of an asset's service group.