Integrations - BevvyTech/BrewskiDocs GitHub Wiki
| Method | Path | Description |
|---|---|---|
GET |
/integrations |
List integration records for a team (manager access only). |
POST |
/integrations/breww/connect |
Store/refresh the Breww API key after validating credentials. |
GET |
/integrations/breww/products |
Search Breww products for the connected team. |
GET |
/integrations/breww/catalog |
Retrieve the full Breww product catalog (50 items per page, auto-paginated). |
GET |
/integrations/breww/container-types |
Fetch container type metadata from Breww (auto-paginated). |
POST |
/integrations/breww/link |
Link a Breww product/container to a Brewski beer. |
DELETE |
/integrations/breww/link |
Remove an existing Breww ↔︎ beer mapping. |
-
Auth: Bearer token; caller must belong to the team and hold
owneroradminrole. -
Query Parameters:
teamId(uuid, required). -
Response 200:
{ "integrations": [ { "id": "9d94...", "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "integration": "breww", "lastState": "connected", "hasConfig": true, "connectedAt": "2025-02-14T10:12:00.000Z", "lastSeenAt": "2025-02-14T10:12:00.000Z", "metadata": { "business": { "id": 10, "name": "Lantern Brewery" } } } ] }- Secrets remain redacted; a connected record exposes a
metadata.businesssummary for UI display.
- Secrets remain redacted; a connected record exposes a
- Errors: 400 invalid query, 401 unauthorized, 403 insufficient role, 404 when integration namespace not recognised.
- Auth: Bearer token; caller must be a team owner/admin.
-
Body:
{ "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "apiKey": "breww_xxxxx" } -
Behaviour:
- Calls
https://breww.com/api/business-details/to validate the key before storing it inteam_integrations.config. - Updates/creates the integration record with
lastState = "connected", tracked timestamps, and cached business metadata.
- Calls
-
Response 200:
{ "integration": { ... } }matching the list representation above. - Errors: 400 invalid payload or Breww rejecting the key, 401, 403 (non-manager), 404 invalid integration slug, 502 upstream Breww failure.
- Auth: Bearer token; caller must be owner/admin on the team and have a connected Breww integration.
-
Query Parameters:
-
teamId(uuid, required) -
q(string, required) — search term; at least two characters. -
page(integer, optional, default 1) — forwarded to Breww (page_sizefixed at 20).
-
-
Response 200:
{ "results": [ { "productId": "101", "productName": "Lantern Pale 30L Keg", "productCode": "LAN-30K", "containerId": "5001", "containerName": "30 L Keg", "containerType": "keg" } ], "pagination": { "count": 1, "next": null, "previous": null } }- Results flatten Breww’s
component_drinksso each product/container pair appears as a discrete option for the UI autocomplete.
- Results flatten Breww’s
- Errors: 400 invalid query or integration not connected, 401, 403 (non-manager), 502 Breww API failure.
- Auth: Bearer token; caller must be owner/admin on the team and have a connected Breww integration.
-
Query Parameters:
-
teamId(uuid, required)
-
-
Behaviour:
- Fetches the Breww
/products/endpoint sequentially, 50 records per page, ordered by name. - Aggregates component containers by
containerNameso the UI can present a single row per beer with its available package formats. - Caps traversal at 200 pages (~10k records) to avoid runaway syncs; truncates and logs a warning if the limit is hit.
- Fetches the Breww
-
Response 200:
{ "products": [ { "productId": "101", "productName": "Lantern Pale", "productCode": "LAN-PALE", "containers": [ { "containerId": "5001", "containerName": "Lantern Pale 30L Keg", "containerType": "keg" }, { "containerId": "9001", "containerName": "Lantern Pale 500ml Bottle", "containerType": "bottle" } ] } ] } - Errors: 400 invalid query or integration not connected, 401, 403 (non-manager), 502 Breww API failure.
- Auth: Bearer token; caller must be owner/admin on the team and have a connected Breww integration.
-
Query Parameters:
-
teamId(uuid, required)
-
-
Behaviour:
- Traverses the Breww
/container-types/endpoint 100 records per page, ordered by name, until pagination ends or 200 pages are fetched. - Normalises each record into Brewski container types (
keg,cask,bottle,can) using Breww’stypeandsmallpack_sub_typemetadata. - Converts litre capacities to integer millilitres for downstream
containersService.createcalls and deduplicates by Breww container id.
- Traverses the Breww
-
Response 200:
{ "containers": [ { "id": "301", "name": "30L Keg", "containerType": "keg", "brewwType": "KEG", "smallpackSubType": null, "volumeMl": 30000 }, { "id": "401", "name": "440ml Can", "containerType": "can", "brewwType": "SMALL", "smallpackSubType": 1, "volumeMl": 440 } ], "sourceCount": 2 } - Errors: 400 invalid query or integration not connected, 401, 403 (non-manager), 502 Breww API failure.
- Auth: Bearer token; caller must be owner/admin on the beer’s team.
-
Body:
{ "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "beerId": "8f62...", "product": { "id": "101", "name": "Lantern Pale 30L Keg", "code": "LAN-30K", "containerId": "5001", "containerName": "30 L Keg", "containerType": "keg" } } -
Behaviour:
- Upserts a
beer_integrationsrecord scoped to (beerId,integration = "breww"). - Stores external ids, container details, and helper metadata (
code,containerType) in JSON for downstream sync jobs. - Rejects beers whose
inventoryModeismanaged; only manual beers can be linked.
- Upserts a
-
Response 200:
{ "integration": { "integration": "breww", "externalBeerId": "101", "externalBeerName": "Lantern Pale 30L Keg", "externalContainerId": "5001", "externalContainerName": "30 L Keg", "metadata": { "code": "LAN-30K", "containerType": "keg" }, "createdAt": "2025-02-14T10:12:00.000Z", "updatedAt": "2025-02-14T10:12:00.000Z" } } -
Errors: 400 invalid payload, missing Breww integration, or beer inventory mode not
manual; 401, 403 (non-manager), 404 beer not found.
- Auth: Bearer token; caller must be owner/admin on the beer’s team.
-
Body:
{ "teamId": "...", "beerId": "..." }. - Response 204: Mapping removed (idempotent; deleting a non-existent link also returns 204).
- Errors: 400 invalid payload, 401, 403 (non-manager), 404 beer not found, 500 unexpected delete failure.