Skip to content

Commit a1e02a0

Browse files
authored
feat: adds tag related endpoints (artaio#23)
1 parent cc7353e commit a1e02a0

File tree

7 files changed

+323
-24
lines changed

7 files changed

+323
-24
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ To run this project, you will need to install the following dependencies on your
99
- [Elixir](https://elixir-lang.org/install.html)
1010
- [Scalar CLI](https://github.com/scalar/scalar?tab=readme-ov-file#cli)
1111

12-
## Fetch dependencies
12+
## Generate the API specification
1313

1414
From the project root, run the following command in your terminal:
1515

1616
```shell
17-
bin/setup
17+
bin/run
1818
```
1919

20-
## Running an interactive shell
20+
## Running a development preview server
2121

2222
From the project root, run the following command in your terminal:
2323

2424
```shell
2525
bin/server
2626
```
2727

28-
28+
This will generate the API specification and start a [Scalar API Client](https://github.com/scalar/scalar/blob/main/packages/api-client/README.md) server to preview the generated documentation.

lib/docs_web/api_spec.ex

Lines changed: 140 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ defmodule DocsWeb.ApiSpec do
2626
AttachmentCreate,
2727
HostedSessionCreate,
2828
ApiKeyCreate,
29+
OrganizationUpdate,
2930
ShipmentCreate,
30-
OrganizationUpdate
31+
TagCreate,
32+
TagUpdate
3133
}
3234

3335
@behaviour OpenApi
@@ -440,7 +442,7 @@ defmodule DocsWeb.ApiSpec do
440442
"/email_subscriptions/{email_subscription_id}" => %PathItem{
441443
get: %Operation{
442444
summary: "Get an Email Subscription",
443-
description: "Retrieve an existing Email Subscription request",
445+
description: "Retrieve an existing Email Subscription resource",
444446
tags: ["email_subscriptions"],
445447
operationId: "emailSubscriptions/get",
446448
parameters: [Authorization.parameter(), Parameters.EmailSubscriptionID.parameter()],
@@ -484,7 +486,7 @@ defmodule DocsWeb.ApiSpec do
484486
},
485487
patch: %Operation{
486488
summary: "Update an Email Subscription",
487-
description: "Update an existing Email Subscription request",
489+
description: "Update an existing Email Subscription resource",
488490
tags: ["email_subscriptions"],
489491
operationId: "emailSubscriptions/update",
490492
parameters: [Authorization.parameter(), Parameters.EmailSubscriptionID.parameter()],
@@ -609,7 +611,7 @@ defmodule DocsWeb.ApiSpec do
609611
},
610612
"/invoice_payments" => %PathItem{
611613
get: %Operation{
612-
summary: "List Invoice Payment records",
614+
summary: "List Invoice Payment",
613615
description:
614616
"Retrieve a paginated collection of Invoice Payments belonging to your Organization",
615617
tags: [
@@ -630,7 +632,7 @@ defmodule DocsWeb.ApiSpec do
630632
},
631633
"/invoice_payments/{invoice_payment_id}" => %PathItem{
632634
get: %Operation{
633-
summary: "Get an Invoice Payment record",
635+
summary: "Get an Invoice Payment",
634636
description: "Retrieve an existing Invoice Payment record",
635637
tags: ["invoice_payments"],
636638
operationId: "invoicePayments/get",
@@ -654,7 +656,7 @@ defmodule DocsWeb.ApiSpec do
654656
},
655657
"/invoices" => %PathItem{
656658
get: %Operation{
657-
summary: "List Invoice records",
659+
summary: "List Invoices",
658660
description:
659661
"Retrieve a paginated collection of Invoices belonging to your Organization",
660662
tags: [
@@ -675,7 +677,7 @@ defmodule DocsWeb.ApiSpec do
675677
},
676678
"/invoices/{invoice_id}" => %PathItem{
677679
get: %Operation{
678-
summary: "Get an Invoice record",
680+
summary: "Get an Invoice",
679681
description: "Retrieve an existing Invoice record",
680682
tags: ["invoices"],
681683
operationId: "invoices/get",
@@ -699,7 +701,7 @@ defmodule DocsWeb.ApiSpec do
699701
},
700702
"/logs" => %PathItem{
701703
get: %Operation{
702-
summary: "List Log records",
704+
summary: "List Logs",
703705
description:
704706
"Retrieve a paginated collection of Log records belonging to your Organization",
705707
tags: [
@@ -720,7 +722,7 @@ defmodule DocsWeb.ApiSpec do
720722
},
721723
"/logs/{log_id}" => %PathItem{
722724
get: %Operation{
723-
summary: "Get a Log record",
725+
summary: "Get a Log",
724726
description: "Retrieve an existing Log record",
725727
tags: ["logs"],
726728
operationId: "logs/get",
@@ -1122,7 +1124,7 @@ defmodule DocsWeb.ApiSpec do
11221124
},
11231125
"/payments" => %PathItem{
11241126
get: %Operation{
1125-
summary: "List Payment records",
1127+
summary: "List Payments",
11261128
description:
11271129
"Retrieve a paginated collection of Payments belonging to your Organization",
11281130
tags: [
@@ -1143,7 +1145,7 @@ defmodule DocsWeb.ApiSpec do
11431145
},
11441146
"/payments/{payment_id}" => %PathItem{
11451147
get: %Operation{
1146-
summary: "Get a Payment record",
1148+
summary: "Get a Payment",
11471149
description: "Retrieve an existing Payment record",
11481150
tags: ["payments"],
11491151
operationId: "payments/get",
@@ -1167,9 +1169,9 @@ defmodule DocsWeb.ApiSpec do
11671169
},
11681170
"/requests" => %PathItem{
11691171
get: %Operation{
1170-
summary: "List Request records",
1172+
summary: "List Quote Requests",
11711173
description:
1172-
"Retrieve a paginated collection of Quote request records belonging to your Organization",
1174+
"Retrieve a paginated collection of Quote Request records belonging to your Organization",
11731175
tags: ["requests"],
11741176
operationId: "requests/list",
11751177
parameters: [
@@ -1191,7 +1193,7 @@ defmodule DocsWeb.ApiSpec do
11911193
post: %Operation{
11921194
summary: "Create a Quote Request",
11931195
description:
1194-
"The first step to booking a shipment on Arta is to create a quote request. This quote request provides Arta with all the necessary transport details for us to price your eventual shipment. \n\n Arta will return eligible quotes for your shipment across Arta's Premium, Selecct, and Parcel quote types. If any quote types are ineligible given your logistic details, those will be noted in the `disqualifications` response. \n\n You must minimally include `objects`, `origin`, and `destination` details in your API call for Arta to successfully price the transport.",
1196+
"The first step to booking a shipment on Arta is to create a Quote Request. This quote request provides Arta with all the necessary transport details for us to price your eventual shipment. \n\n Arta will return eligible quotes for your shipment across Arta's Premium, Selecct, and Parcel quote types. If any quote types are ineligible given your logistic details, those will be noted in the `disqualifications` response. \n\n You must minimally include `objects`, `origin`, and `destination` details in your API call for Arta to successfully price the transport.",
11951197
tags: ["requests"],
11961198
operationId: "requests/create",
11971199
parameters: [Authorization.parameter(), ArtaQuoteTimeout.parameter()],
@@ -1222,7 +1224,7 @@ defmodule DocsWeb.ApiSpec do
12221224
"/requests/{request_id}" => %PathItem{
12231225
get: %Operation{
12241226
summary: "Get a Quote Request",
1225-
description: "Retrieve an existing Shipment Quote Request record by its ID",
1227+
description: "Retrieve an existing Quote Request record by its ID",
12261228
tags: ["requests"],
12271229
operationId: "requests/get",
12281230
parameters: [Authorization.parameter(), Parameters.RequestID.parameter()],
@@ -1429,14 +1431,19 @@ defmodule DocsWeb.ApiSpec do
14291431

14301432
"/shipments" => %PathItem{
14311433
get: %Operation{
1432-
summary: "List Shipment records",
1434+
summary: "List Shipments",
14331435
description:
14341436
"Retrieve a paginated collection of Shipment records belonging to your Organization",
14351437
tags: [
14361438
"shipments"
14371439
],
14381440
operationId: "shipments/list",
1439-
parameters: [Authorization.parameter()],
1441+
parameters: [
1442+
Authorization.parameter(),
1443+
Page.parameter(),
1444+
PageSize.parameter(),
1445+
Search.parameter()
1446+
],
14401447
responses: %{
14411448
200 =>
14421449
Operation.response(
@@ -1493,7 +1500,7 @@ defmodule DocsWeb.ApiSpec do
14931500
},
14941501
"/shipments/{shipment_id}" => %PathItem{
14951502
get: %Operation{
1496-
summary: "Retrieve a Shipment record",
1503+
summary: "Retrieve a Shipment",
14971504
description: "Retrieve an existing Shipment record",
14981505
tags: [
14991506
"shipments"
@@ -1516,6 +1523,121 @@ defmodule DocsWeb.ApiSpec do
15161523
)
15171524
}
15181525
}
1526+
},
1527+
"/tags" => %PathItem{
1528+
get: %Operation{
1529+
summary: "List Tags",
1530+
description:
1531+
"Retrieve a paginated collection of tags belonging to your organization\n\nTags allow you to categorize and organize Shipments, Requests, and other resources for easier tracking and filtering. They can be created, updated, and archived by setting is_active to false. Archived tags remain linked to existing records but cannot be associated with new ones. If needed, tags can be reactivated later.\n\nTags are global for an organization and shared across both Live and Test modes.",
1532+
tags: [
1533+
"tags"
1534+
],
1535+
operationId: "tags/list",
1536+
parameters: [
1537+
Authorization.parameter(),
1538+
Page.parameter(),
1539+
PageSize.parameter(),
1540+
Search.parameter()
1541+
],
1542+
responses: %{
1543+
200 =>
1544+
Operation.response(
1545+
"A collection of Tag records",
1546+
"application/json",
1547+
list(Response.Tag)
1548+
)
1549+
}
1550+
},
1551+
post: %Operation{
1552+
summary: "Create a Tag",
1553+
description: "Create a new tag for your organization.",
1554+
tags: [
1555+
"tags"
1556+
],
1557+
operationId: "tags/create",
1558+
parameters: [Authorization.parameter()],
1559+
requestBody: %RequestBody{
1560+
content: %{
1561+
"application/json" => %MediaType{
1562+
schema: TagCreate
1563+
}
1564+
}
1565+
},
1566+
responses: %{
1567+
200 =>
1568+
Operation.response(
1569+
"The created tag",
1570+
"application/json",
1571+
Response.Tag,
1572+
headers: default_headers()
1573+
),
1574+
403 =>
1575+
Operation.response(
1576+
"Forbidden",
1577+
"application/json",
1578+
nil
1579+
),
1580+
422 =>
1581+
Operation.response(
1582+
"Unprocessible entity",
1583+
"application/json",
1584+
Response.Error
1585+
)
1586+
}
1587+
}
1588+
},
1589+
"/tags/{tag_name}" => %PathItem{
1590+
get: %Operation{
1591+
summary: "Get a Tag",
1592+
description: "Retrieve an existing Tag resource by name",
1593+
tags: ["tags"],
1594+
operationId: "tags/get",
1595+
parameters: [Authorization.parameter(), Parameters.TagName.parameter()],
1596+
responses: %{
1597+
200 =>
1598+
Operation.response(
1599+
"Successful Tag response",
1600+
"application/json",
1601+
Response.EmailSubscription,
1602+
headers: default_headers()
1603+
),
1604+
404 =>
1605+
Operation.response(
1606+
"Object not found",
1607+
"application/json",
1608+
nil
1609+
)
1610+
}
1611+
},
1612+
patch: %Operation{
1613+
summary: "Update a Tag",
1614+
description: "Update an existing Tag resource",
1615+
tags: ["tags"],
1616+
operationId: "tags/update",
1617+
parameters: [Authorization.parameter(), Parameters.TagName.parameter()],
1618+
requestBody: %RequestBody{
1619+
content: %{
1620+
"application/json" => %MediaType{
1621+
schema: TagUpdate
1622+
}
1623+
}
1624+
},
1625+
responses: %{
1626+
200 =>
1627+
Operation.response(
1628+
"The updated tag",
1629+
"application/json",
1630+
Response.Tag,
1631+
headers: default_headers()
1632+
),
1633+
404 =>
1634+
Operation.response(
1635+
"Object not found",
1636+
"application/json",
1637+
nil
1638+
)
1639+
}
1640+
}
15191641
}
15201642
}
15211643
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
defmodule DocsWeb.Parameters.TagName do
2+
alias OpenApiSpex.{Parameter, Schema}
3+
require OpenApiSpex
4+
5+
@spec parameter() :: Parameter.t()
6+
def parameter(),
7+
do: %Parameter{
8+
name: "tag_name",
9+
description: "The name field for a Tag resource",
10+
in: :path,
11+
required: true,
12+
schema: %Schema{
13+
type: "string"
14+
}
15+
}
16+
end

lib/docs_web/schemas/request_body/request_create.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ defmodule DocsWeb.Schemas.RequestBody.RequestCreate do
3636
example: "USD"
3737
},
3838
destination: %Schema{
39-
description: "The destination location for the shipment quote request",
39+
description: "The destination location for the quote request",
4040
type: :object,
4141
required: ["postal_code", "country"],
4242
properties: %{
@@ -273,7 +273,7 @@ defmodule DocsWeb.Schemas.RequestBody.RequestCreate do
273273
}
274274
},
275275
origin: %Schema{
276-
description: "The originating location for the shipment quote request",
276+
description: "The originating location for the quote request",
277277
type: :object,
278278
required: ["postal_code", "country"],
279279
properties: %{
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
defmodule DocsWeb.Schemas.RequestBody.TagCreate do
2+
alias OpenApiSpex.Schema
3+
4+
require OpenApiSpex
5+
6+
OpenApiSpex.schema(%Schema{
7+
title: "TagCreate",
8+
type: :object,
9+
properties: %{
10+
tag: %Schema{
11+
type: :object,
12+
properties: %{
13+
color: %Schema{
14+
type: :string,
15+
description: "The hexadecimal color code for the tag, without the leading `#`.",
16+
pattern: "^[0-9A-F]{6}$",
17+
maxLength: 6,
18+
minLength: 6,
19+
example: "0000FF"
20+
},
21+
description: %Schema{
22+
type: :string,
23+
maxLength: 255,
24+
description: "An optional, brief description for this tag.",
25+
nullable: true
26+
},
27+
is_active: %Schema{
28+
type: "boolean",
29+
description:
30+
"Indicates whether or not the tag is active. Inactive tags may not be associated to new resources"
31+
},
32+
name: %Schema{
33+
type: :string,
34+
description:
35+
"The name for the tag. It may contain lower case letters, dashes, and alphanumeric characters only. The maximum character count is 50.",
36+
pattern: "^[a-z0-9-]{1,50}$",
37+
maxLength: 50,
38+
example: "la-warehouse"
39+
}
40+
}
41+
}
42+
},
43+
required: ["tag"],
44+
additionalProperties: false
45+
})
46+
end

0 commit comments

Comments
 (0)