Add OpenAPI v1 documentation for Bookings API
- Introduced Writerside topics for multiple endpoints in the Bookings module, including user, admin, and public time booking routes. - Added `Bookings_OpenAPIv1.json` specification defining API paths, schemas, and security configurations. - Included endpoint details for operations like booking retrieval, updates, deletion, syncing, and timebookings.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic id="Bookings_API_Reference"
|
||||
title="Bookings API Reference"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd">
|
||||
|
||||
<p>Bookings API OpenAPI 1.0.0 (separate from XLVask)</p>
|
||||
</topic>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/admin/bookings/completeWashWithoutWashCertificate POST" id="Admin_Bookings_CompleteWithoutWashCertificate_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/admin/bookings/completeWashWithoutWashCertificate"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/admin/bookings/delete POST" id="Admin_Bookings_Delete_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/admin/bookings/delete"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/admin/bookings/department/count GET" id="Admin_Bookings_Department_Count_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/admin/bookings/department/count"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/admin/bookings/sync POST" id="Admin_Bookings_Sync_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/admin/bookings/sync"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/bookings/download_pdf GET" id="Bookings_Download_PDF_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/bookings/download_pdf"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/bookings GET" id="Bookings_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/bookings"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/bookings PUT" id="Bookings_PUT">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="PUT" endpoint="/bookings"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/department/timebookings/entries/public GET" id="Department_Timebookings_Entries_Public_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/department/timebookings/entries/public"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/department/timebookings/entries/public POST" id="Department_Timebookings_Entries_Public_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/department/timebookings/entries/public"/>
|
||||
</topic>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/department/timebookings/opening-hours/public GET" id="Department_Timebookings_OpeningHours_Public_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/department/timebookings/opening-hours/public"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/department/timebookings/types/public GET" id="Department_Timebookings_Types_Public_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/department/timebookings/types/public"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/superuser/bookings/sync/all POST" id="Superuser_Bookings_Sync_All_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/superuser/bookings/sync/all"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/user/bookings/delete POST" id="User_Bookings_Delete_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/user/bookings/delete"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/user/bookings GET" id="User_Bookings_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="GET" endpoint="/user/bookings"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/user/bookings/washcertificate/download POST" id="User_Bookings_Washcertificate_Download_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../../services/nginx/app/modules/bookings/Bookings_OpenAPIv1.json" method="POST" endpoint="/user/bookings/washcertificate/download"/>
|
||||
</topic>
|
||||
@@ -0,0 +1,496 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Bookings API",
|
||||
"version": "1.0.0",
|
||||
"description": "OpenAPI specification for booking-related endpoints. This spec is standalone and not related to XLVask."
|
||||
},
|
||||
"servers": [
|
||||
{ "url": "https://api.truckwash.dk:4433" }
|
||||
],
|
||||
"tags": [
|
||||
{ "name": "Bookings" },
|
||||
{ "name": "User Bookings" },
|
||||
{ "name": "Admin Bookings" },
|
||||
{ "name": "Public Time Bookings" }
|
||||
],
|
||||
"paths": {
|
||||
"/bookings": {
|
||||
"get": {
|
||||
"tags": ["Bookings"],
|
||||
"summary": "List bookings or fetch a single booking by id",
|
||||
"description": "Requires permission `list_bookings`. If query parameter `id` is set, returns a single booking; otherwise returns a paginated list. If the caller has permission `issue_wash_certificates`, the meta will include `wash_certificate_token`.",
|
||||
"parameters": [
|
||||
{ "$ref": "#/components/parameters/id" },
|
||||
{ "$ref": "#/components/parameters/page" },
|
||||
{ "$ref": "#/components/parameters/limit" },
|
||||
{ "$ref": "#/components/parameters/search" },
|
||||
{ "$ref": "#/components/parameters/filters" },
|
||||
{ "$ref": "#/components/parameters/order" }
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/EnvelopeBookingsOrBooking" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": { "description": "Invalid request or session" },
|
||||
"403": { "description": "Forbidden" },
|
||||
"404": { "description": "Booking not found" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
},
|
||||
"put": {
|
||||
"tags": ["Bookings"],
|
||||
"summary": "Update a booking (reference number)",
|
||||
"description": "Requires permission `list_own_bookings`. Updates only the `reference_number` for a booking the user has access to.",
|
||||
"parameters": [
|
||||
{ "$ref": "#/components/parameters/id" },
|
||||
{
|
||||
"name": "reference_number",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": { "type": "string", "maxLength": 255 }
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Updated booking",
|
||||
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeBooking" } } }
|
||||
},
|
||||
"400": { "description": "Invalid request or session" },
|
||||
"403": { "description": "Forbidden" },
|
||||
"404": { "description": "Booking not found" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/user/bookings": {
|
||||
"get": {
|
||||
"tags": ["User Bookings"],
|
||||
"summary": "List bookings for the authenticated user",
|
||||
"description": "Requires permission `list_own_bookings`. Returns a paginated list of the user's own bookings.",
|
||||
"parameters": [
|
||||
{ "$ref": "#/components/parameters/page" },
|
||||
{ "$ref": "#/components/parameters/limit" },
|
||||
{ "$ref": "#/components/parameters/search" },
|
||||
{ "$ref": "#/components/parameters/filters" },
|
||||
{ "$ref": "#/components/parameters/order" }
|
||||
],
|
||||
"responses": {
|
||||
"200": { "description": "Success", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeBookingsList" } } } },
|
||||
"400": { "description": "Invalid request or session" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/admin/bookings/sync": {
|
||||
"post": {
|
||||
"tags": ["Admin Bookings"],
|
||||
"summary": "Sync or upsert a booking from external system",
|
||||
"description": "Requires permission `sync_bookings` unless `auth_key` equals the configured value. Accepts all booking fields as query/body form parameters and upserts the booking.",
|
||||
"requestBody": {
|
||||
"required": false,
|
||||
"content": {
|
||||
"application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/SyncBookingRequest" } },
|
||||
"application/json": { "schema": { "$ref": "#/components/schemas/SyncBookingRequest" } }
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": { "description": "Success", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeMessage" } } } }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"/admin/bookings/department/count": {
|
||||
"get": {
|
||||
"tags": ["Admin Bookings"],
|
||||
"summary": "Get unfulfilled bookings count for a department (today)",
|
||||
"description": "Requires permission `list_department_bookings_count`. Returns an integer count. Response meta may include `cached: true` when the value was served from cache.",
|
||||
"parameters": [
|
||||
{ "$ref": "#/components/parameters/department_id" }
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Count",
|
||||
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeInteger" } } }
|
||||
},
|
||||
"400": { "description": "Invalid request or session" },
|
||||
"404": { "description": "Department not found" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/user/bookings/washcertificate/download": {
|
||||
"post": {
|
||||
"tags": ["User Bookings"],
|
||||
"summary": "Get download link for a booking's wash certificate",
|
||||
"description": "Requires permission `download_own_wash_certificate`. Returns a presigned download link if certificate exists and user has access.",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Link", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeDownloadLink" } } } },
|
||||
"400": { "description": "Not allowed or invalid status" },
|
||||
"404": { "description": "Booking or certificate not found" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/bookings/download_pdf": {
|
||||
"get": {
|
||||
"tags": ["User Bookings"],
|
||||
"summary": "Get download link for a booking's wash certificate PDF",
|
||||
"description": "Requires permission `download_own_wash_certificate`. Checks both legacy and current storage buckets.",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Link", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeDownloadLink" } } } },
|
||||
"400": { "description": "Not allowed or invalid session" },
|
||||
"404": { "description": "Booking or certificate not found" },
|
||||
"500": { "description": "Storage inconsistency" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/admin/bookings/delete": {
|
||||
"post": {
|
||||
"tags": ["Admin Bookings"],
|
||||
"summary": "Delete a booking",
|
||||
"description": "Requires permission `delete_booking`. Deletes the booking if the user has access.",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeMessage" } } } },
|
||||
"400": { "description": "Not allowed or invalid session" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/superuser/bookings/sync/all": {
|
||||
"post": {
|
||||
"tags": ["Admin Bookings"],
|
||||
"summary": "Sync all bookings from external system",
|
||||
"description": "Requires permission `sync_all_bookings`.",
|
||||
"responses": {
|
||||
"200": { "description": "Triggered", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeMessage" } } } },
|
||||
"400": { "description": "Invalid session" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/admin/bookings/completeWashWithoutWashCertificate": {
|
||||
"post": {
|
||||
"tags": ["Admin Bookings"],
|
||||
"summary": "Complete wash without generating a certificate",
|
||||
"description": "Requires permission `complete_wash_without_wash_certificate`.",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeMessage" } } } },
|
||||
"400": { "description": "Not allowed or invalid session" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/user/bookings/delete": {
|
||||
"post": {
|
||||
"tags": ["User Bookings"],
|
||||
"summary": "Delete own booking",
|
||||
"description": "Requires permission `delete_own_booking`. Deletes the user's own booking if accessible.",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeMessage" } } } },
|
||||
"400": { "description": "Not allowed or invalid session" }
|
||||
},
|
||||
"security": [{ "BearerAuth": [] }]
|
||||
}
|
||||
},
|
||||
|
||||
"/department/timebookings/opening-hours/public": {
|
||||
"get": {
|
||||
"tags": ["Public Time Bookings"],
|
||||
"summary": "Get public opening hours for a department",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Opening hours", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeOpeningHours" } } } },
|
||||
"400": { "description": "Missing or invalid id" },
|
||||
"404": { "description": "Department or opening hours not found, or module disabled" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"/department/timebookings/types/public": {
|
||||
"get": {
|
||||
"tags": ["Public Time Bookings"],
|
||||
"summary": "List public booking types for a department",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Types", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeBookingTypesList" } } } },
|
||||
"400": { "description": "Missing or invalid id" },
|
||||
"404": { "description": "Department or types not found, or module disabled" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"/department/timebookings/entries/public": {
|
||||
"get": {
|
||||
"tags": ["Public Time Bookings"],
|
||||
"summary": "List public booking entries for a department",
|
||||
"parameters": [ { "$ref": "#/components/parameters/id" }, { "$ref": "#/components/parameters/page" }, { "$ref": "#/components/parameters/limit" }, { "$ref": "#/components/parameters/search" }, { "$ref": "#/components/parameters/filters" }, { "$ref": "#/components/parameters/order" } ],
|
||||
"responses": {
|
||||
"200": { "description": "Entries", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeTimeBookingEntriesList" } } } },
|
||||
"400": { "description": "Missing or invalid id" },
|
||||
"404": { "description": "Department not found or module disabled" }
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["Public Time Bookings"],
|
||||
"summary": "Create a public booking entry",
|
||||
"description": "Creates a time booking entry for a department and type at a specific start time. The duration is derived from the type.",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/PublicEntryCreate" } },
|
||||
"application/json": { "schema": { "$ref": "#/components/schemas/PublicEntryCreate" } }
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": { "description": "Created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnvelopeTimeBookingEntry" } } } },
|
||||
"400": { "description": "Validation error" },
|
||||
"404": { "description": "Department/type not found or module disabled" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"BearerAuth": {
|
||||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"id": { "name": "id", "in": "query", "required": false, "schema": { "type": "integer", "format": "int32" } },
|
||||
"department_id": { "name": "department_id", "in": "query", "required": true, "schema": { "type": "integer", "format": "int32" } },
|
||||
"page": { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1 } },
|
||||
"limit": { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1 } },
|
||||
"search": { "name": "search", "in": "query", "required": false, "schema": { "type": "string" } },
|
||||
"filters": { "name": "filters", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated filters: key:value pairs (supports multiple keys)." },
|
||||
"order": { "name": "order", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Sort order, e.g. `id:ASC` or `created_at:DESC`." }
|
||||
},
|
||||
"schemas": {
|
||||
"Envelope": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": { "type": "boolean" },
|
||||
"data": {},
|
||||
"meta": { "type": "object", "additionalProperties": true },
|
||||
"includes": { "type": "object", "additionalProperties": true }
|
||||
},
|
||||
"required": ["success", "data", "meta", "includes"]
|
||||
},
|
||||
"EnvelopeMessage": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "type": "object", "properties": { "message": { "type": "string" } }, "required": ["message"] } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeInteger": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "type": "integer" } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeDownloadLink": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "$ref": "#/components/schemas/DownloadLink" } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeBookingsList": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Booking" } } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeBooking": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Booking" } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeBookingsOrBooking": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "oneOf": [ { "$ref": "#/components/schemas/Booking" }, { "type": "array", "items": { "$ref": "#/components/schemas/Booking" } } ] } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeOpeningHours": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "$ref": "#/components/schemas/OpeningHours" } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeBookingTypesList": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/BookingType" } } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeTimeBookingEntriesList": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/TimeBookingPublicEntry" } } } }
|
||||
]
|
||||
},
|
||||
"EnvelopeTimeBookingEntry": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/components/schemas/Envelope" },
|
||||
{ "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TimeBookingEntry" } } }
|
||||
]
|
||||
},
|
||||
|
||||
"Booking": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "integer" },
|
||||
"customer_number": { "type": "integer" },
|
||||
"wash_type": { "type": "string" },
|
||||
"contact_email": { "type": "string" },
|
||||
"reference_number": { "type": "string", "nullable": true },
|
||||
"regNrTraekker": { "type": "string", "nullable": true },
|
||||
"regNrTrailer": { "type": "string", "nullable": true },
|
||||
"washCertificateEmail": { "type": "string", "nullable": true },
|
||||
"date": { "type": "string" },
|
||||
"department": { "type": "integer" },
|
||||
"pickup_bool": { "type": "boolean" },
|
||||
"notes": { "type": "string", "nullable": true },
|
||||
"washCertificateStatus": { "type": "string", "enum": ["pending", "completed", "cancelled"], "nullable": true },
|
||||
"washCertificateUrl": { "type": "string", "nullable": true },
|
||||
"wash_certificate_pdf": { "type": "string", "nullable": true },
|
||||
"status": { "type": "string", "enum": ["pending", "completed", "cancelled"] },
|
||||
"data": { "type": "object", "nullable": true, "additionalProperties": true },
|
||||
"parsed_services": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"string": { "type": "string" },
|
||||
"array": { "type": "array", "items": { "type": "integer" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["id", "customer_number", "wash_type", "date", "department", "pickup_bool", "status"]
|
||||
},
|
||||
|
||||
"DownloadLink": {
|
||||
"type": "object",
|
||||
"properties": { "link": { "type": "string", "format": "uri" } },
|
||||
"required": ["link"]
|
||||
},
|
||||
|
||||
"OpeningHours": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monday_start": { "type": ["string", "null"] },
|
||||
"monday_end": { "type": ["string", "null"] },
|
||||
"tuesday_start": { "type": ["string", "null"] },
|
||||
"tuesday_end": { "type": ["string", "null"] },
|
||||
"wednesday_start": { "type": ["string", "null"] },
|
||||
"wednesday_end": { "type": ["string", "null"] },
|
||||
"thursday_start": { "type": ["string", "null"] },
|
||||
"thursday_end": { "type": ["string", "null"] },
|
||||
"friday_start": { "type": ["string", "null"] },
|
||||
"friday_end": { "type": ["string", "null"] },
|
||||
"saturday_start": { "type": ["string", "null"] },
|
||||
"saturday_end": { "type": ["string", "null"] },
|
||||
"sunday_start": { "type": ["string", "null"] },
|
||||
"sunday_end": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
|
||||
"BookingType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "integer" },
|
||||
"department": { "type": "integer" },
|
||||
"product": { "type": "integer" },
|
||||
"name": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"duration": { "type": "integer", "description": "Duration in minutes" }
|
||||
},
|
||||
"required": ["id", "department", "product", "name", "description", "duration"]
|
||||
},
|
||||
|
||||
"TimeBookingPublicEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start": { "type": "string" },
|
||||
"duration": { "type": "integer" }
|
||||
},
|
||||
"required": ["start", "duration"]
|
||||
},
|
||||
|
||||
"TimeBookingEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "integer" },
|
||||
"department": { "type": "integer" },
|
||||
"type": { "type": "integer" },
|
||||
"start": { "type": "string" },
|
||||
"end": { "type": "string" },
|
||||
"note": { "type": ["string", "null"] },
|
||||
"reg": { "type": ["string", "null"] },
|
||||
"phone": { "type": "integer" },
|
||||
"phone_country_code": { "type": "integer" }
|
||||
},
|
||||
"required": ["id", "department", "type", "start", "end", "phone", "phone_country_code"]
|
||||
},
|
||||
|
||||
"PublicEntryCreate": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"department": { "type": "integer" },
|
||||
"type": { "type": "integer" },
|
||||
"start": { "type": "string", "example": "2025-05-01 10:00:00" },
|
||||
"phone_country_code": { "type": "integer", "nullable": true },
|
||||
"phone": { "type": "integer", "nullable": true },
|
||||
"note": { "type": "string", "nullable": true },
|
||||
"reg": { "type": "string", "nullable": true },
|
||||
"addons": { "type": "array", "nullable": true, "items": { "type": "integer" } }
|
||||
},
|
||||
"required": ["department", "type", "start"]
|
||||
},
|
||||
|
||||
"SyncBookingRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth_key": { "type": "string", "description": "Special key which allows syncing without the `sync_bookings` permission when valid" },
|
||||
"id": { "type": "integer" },
|
||||
"customer_number": { "type": "integer" },
|
||||
"wash_type": { "type": "string" },
|
||||
"contact_email": { "type": "string" },
|
||||
"reference_number": { "type": "string" },
|
||||
"regNrTraekker": { "type": "string" },
|
||||
"regNrTrailer": { "type": "string" },
|
||||
"washCertificateEmail": { "type": "string" },
|
||||
"date": { "type": "string" },
|
||||
"department": { "type": "integer" },
|
||||
"pickup_bool": { "type": "integer" },
|
||||
"notes": { "type": "string" },
|
||||
"washCertificateStatus": { "type": "string" },
|
||||
"washCertificateUrl": { "type": "string" },
|
||||
"status": { "type": "string" }
|
||||
},
|
||||
"required": ["id", "customer_number", "wash_type", "contact_email", "reference_number", "regNrTraekker", "regNrTrailer", "washCertificateEmail", "date", "department", "pickup_bool", "notes", "washCertificateStatus", "washCertificateUrl", "status"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user