Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,546 changes: 1,349 additions & 1,197 deletions api/api.gen.go

Large diffs are not rendered by default.

195 changes: 195 additions & 0 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2219,6 +2219,84 @@ paths:
$ref: '#/components/schemas/UnexpectedProblemResponse'
tags:
- Billing
/api/v1/billing/invoices/{invoiceId}/lines/{lineId}/cost:
get:
operationId: getInvoiceLineCost
summary: Get an invoice feature cost
description: Get an invoice feature cost.
parameters:
- name: invoiceId
in: path
required: true
schema:
type: string
pattern: ^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$
example: 01G65Z755AFWAKHE12NY0CQ9FH
- name: lineId
in: path
required: true
schema:
type: string
- $ref: '#/components/parameters/GetInvoiceLineCostParam.windowSize'
- $ref: '#/components/parameters/GetInvoiceLineCostParam.windowTimeZone'
- $ref: '#/components/parameters/GetInvoiceLineCostParam.groupBy'
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceLineCost'
'400':
description: The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
content:
application/problem+json:
schema:
$ref: '#/components/schemas/BadRequestProblemResponse'
'401':
description: The request has not been applied because it lacks valid authentication credentials for the target resource.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/UnauthorizedProblemResponse'
'403':
description: The server understood the request but refuses to authorize it.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ForbiddenProblemResponse'
'404':
description: The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/NotFoundProblemResponse'
'412':
description: One or more conditions given in the request header fields evaluated to false when tested on the server.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/PreconditionFailedProblemResponse'
'500':
description: The server encountered an unexpected condition that prevented it from fulfilling the request.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/InternalServerErrorProblemResponse'
'503':
description: The server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ServiceUnavailableProblemResponse'
default:
description: An unexpected error response.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/UnexpectedProblemResponse'
tags:
- Billing
/api/v1/billing/invoices/{invoiceId}/retry:
post:
operationId: retryInvoiceAction
Expand Down Expand Up @@ -12113,6 +12191,46 @@ components:
$ref: '#/components/schemas/FeatureOrderBy'
explode: false
style: form
GetInvoiceLineCostParam.groupBy:
name: groupBy
in: query
required: false
description: |-
If not specified a single aggregate will be returned for each subject and time window.
`subject` is a reserved group by value.

For example: ?groupBy=subject&groupBy=model
schema:
type: array
items:
type: string
style: form
GetInvoiceLineCostParam.windowSize:
name: windowSize
in: query
required: false
description: |-
If not specified, a single usage aggregate will be returned for the entirety of the specified period for each subject and group.

For example: ?windowSize=DAY
schema:
$ref: '#/components/schemas/WindowSize'
explode: false
style: form
GetInvoiceLineCostParam.windowTimeZone:
name: windowTimeZone
in: query
required: false
description: |-
The value is the name of the time zone as defined in the IANA Time Zone Database (http://www.iana.org/time-zones).
If not specified, the UTC timezone will be used.

For example: ?windowTimeZone=UTC
schema:
type: string
default: UTC
explode: false
style: form
GrantOrderByOrdering.order:
name: order
in: query
Expand Down Expand Up @@ -19139,6 +19257,83 @@ components:
InvoiceLine represents a single item or service sold to the customer.

This is a base class for all line types, and should not be used directly.
InvoiceLineCost:
type: object
required:
- from
- to
- costPerUnit
- totalUsage
- totalCost
- currency
- rows
properties:
from:
type: string
format: date-time
description: The start of the period the value is aggregated over.
example: '2023-01-01T01:01:01.001Z'
to:
type: string
format: date-time
description: The end of the period the value is aggregated over.
example: '2023-01-01T01:01:01.001Z'
costPerUnit:
allOf:
- $ref: '#/components/schemas/Numeric'
description: The cost per unit of the feature for the invoice.
totalUsage:
allOf:
- $ref: '#/components/schemas/Numeric'
description: The total usage of the feature for the invoice.
totalCost:
allOf:
- $ref: '#/components/schemas/Numeric'
description: The total cost of the feature for the invoice.
currency:
allOf:
- $ref: '#/components/schemas/CurrencyCode'
description: Currency of the cost.
rows:
type: array
items:
$ref: '#/components/schemas/InvoiceLineCostRow'
description: The rows of the feature cost for the invoice.
description: InvoiceLineCost is the cost of a feature for an invoice.
InvoiceLineCostRow:
type: object
required:
- windowStart
- windowEnd
- usage
- cost
- groupBy
properties:
windowStart:
type: string
format: date-time
description: The start of the window the value is aggregated over.
example: '2023-01-01T01:01:01.001Z'
windowEnd:
type: string
format: date-time
description: The end of the window the value is aggregated over.
example: '2023-01-01T01:01:01.001Z'
usage:
allOf:
- $ref: '#/components/schemas/Numeric'
description: The usage of the feature for the invoice.
cost:
allOf:
- $ref: '#/components/schemas/Numeric'
description: The cost of the feature for the invoice.
groupBy:
type: object
additionalProperties:
type: string
nullable: true
description: The group by values the value is aggregated over.
description: InvoiceLineCostRow is a row of the feature cost for the invoice.
InvoiceLineDiscounts:
type: object
properties:
Expand Down
141 changes: 141 additions & 0 deletions api/spec/src/billing/cost.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import "@typespec/http";
import "@typespec/rest";
import "@typespec/openapi";
import "@typespec/openapi3";

import "../meters.tsp";
import "../errors.tsp";

using TypeSpec.Http;
using TypeSpec.OpenAPI;

namespace OpenMeter.Billing.Invoice;

/**
* InvoiceCostHandler is a collection of endpoints that allow getting the cost of an invoice.
*/
@tag("Billing")
interface InvoiceCostHandler {
/**
* Get an invoice feature cost.
*/
@get
@route("/api/v1/billing/invoices/{invoiceId}/lines/{lineId}/cost")
@summary("Get an invoice feature cost")
@operationId("getInvoiceLineCost")
getInvoiceLineCost(
@path
invoiceId: ULID,

@path
lineId: string,

...GetInvoiceLineCostParam,
): InvoiceLineCost | OpenMeter.NotFoundError | OpenMeter.CommonErrors;
}

/**
* InvoiceLineCost is the cost of a feature for an invoice.
*/
@friendlyName("InvoiceLineCost")
model InvoiceLineCost {
/**
* The start of the period the value is aggregated over.
*/
from: DateTime;

/**
* The end of the period the value is aggregated over.
*/
to: DateTime;

/**
* The cost per unit of the feature for the invoice.
*/
costPerUnit: Numeric;

/**
* The total usage of the feature for the invoice.
*/
totalUsage: Numeric;

/**
* The total cost of the feature for the invoice.
*/
totalCost: Numeric;

/**
* Currency of the cost.
*/
currency: CurrencyCode;

/**
* The rows of the feature cost for the invoice.
*/
rows: InvoiceLineCostRow[];
}

/**
* InvoiceLineCostRow is a row of the feature cost for the invoice.
*/
@friendlyName("InvoiceLineCostRow")
model InvoiceLineCostRow {
/**
* The start of the window the value is aggregated over.
*/
windowStart: DateTime;

/**
* The end of the window the value is aggregated over.
*/
windowEnd: DateTime;

/**
* The usage of the feature for the invoice.
*/
usage: Numeric;

/**
* The cost of the feature for the invoice.
*/
cost: Numeric;

/**
* The group by values the value is aggregated over.
*/
groupBy: Record<string | null>;
}

/**
* GetInvoiceLineCostParam is the parameter for the getInvoiceLineCost endpoint.
*/
@friendlyName("GetInvoiceLineCostParam")
model GetInvoiceLineCostParam {
/**
* If not specified, a single usage aggregate will be returned for the entirety of the specified period for each subject and group.
*
* For example: ?windowSize=DAY
*/
@query
windowSize?: OpenMeter.WindowSize;

/**
* The value is the name of the time zone as defined in the IANA Time Zone Database (http://www.iana.org/time-zones).
* If not specified, the UTC timezone will be used.
*
* For example: ?windowTimeZone=UTC
*/
@query
@example("America/New_York")
windowTimeZone?: string = "UTC";

/**
* If not specified a single aggregate will be returned for each subject and time window.
* `subject` is a reserved group by value.
*
* For example: ?groupBy=subject&groupBy=model
*/
@query(#{ explode: true })
@example(#["model", "type"])
groupBy?: string[];
}
1 change: 1 addition & 0 deletions api/spec/src/billing/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "./invoices/main.tsp";
import "./profile.tsp";
import "./customeroverride.tsp";
import "./invoices.tsp";
import "./cost.tsp";

using TypeSpec.Http;
using TypeSpec.Rest;
Expand Down
Loading
Loading