aboutsummaryrefslogtreecommitdiff
path: root/toolkits/endpoints.md
diff options
context:
space:
mode:
authorUMTS at Teleco <crt@teleco.ch>2026-02-15 15:53:50 +0100
committerUMTS at Teleco <crt@teleco.ch>2026-02-15 15:53:50 +0100
commitfa680b24d1123f9de27fc752943e43c86c692314 (patch)
treee4875712a0f8298819c490dc42e881218a2175bc /toolkits/endpoints.md
JAYSON DERULO
Diffstat (limited to 'toolkits/endpoints.md')
-rw-r--r--toolkits/endpoints.md137
1 files changed, 137 insertions, 0 deletions
diff --git a/toolkits/endpoints.md b/toolkits/endpoints.md
new file mode 100644
index 0000000..760895e
--- /dev/null
+++ b/toolkits/endpoints.md
@@ -0,0 +1,137 @@
+# Toolkit Endpoints
+
+[back to toolkits](README.md) /// [home](../README.md)
+
+Custom API routes defined by toolkits. These live under `/tk/app/{toolkit}/` or `/tk/lib/{toolkit}/` depending on the toolkit type.
+
+## Route format
+
+```
+POST /tk/app/beepzone/kiosk/scan
+GET /tk/lib/opensigma/status
+```
+
+The path after the toolkit name is matched against endpoint definitions in the toolkit config.
+
+## Endpoint types
+
+### Internal
+
+Runs logic within the server process. Can use `pseudo_querys` to execute database queries based on the request payload. No external service needed.
+
+### HTTP
+
+Proxies the request to an external HTTP service. The server wraps the payload in a context object (user info, DB context etc), sends it to the upstream URL and returns the response.
+
+Can return JSON (wrapped in the standard envelope) or `passthrough` (raw bytes with the upstream content type, useful for file downloads).
+
+### Executable
+
+Runs a shell command on the server. The request context is passed as a JSON string argument. Output is parsed as JSON or wrapped in `{ "output": "..." }` if its not valid JSON.
+
+## Request flow
+
+1. verify the toolkit exists and is enabled (404 if not)
+2. match the endpoint path in config (404 if not found)
+3. check endpoint level permissions for your power level (403 if denied)
+4. validate payload against `client_filter` rules (400 if invalid)
+5. fetch `inject_db_context` values from the database
+6. resolve your toolkit group
+7. build the request context
+8. apply `overwrite_wrapping` transformations
+9. execute based on endpoint type
+
+## Request context
+
+The context object sent to backends looks like this:
+
+```json
+{
+ "user_id": 1,
+ "username": "admin",
+ "power": 100,
+ "core_group_id": 1,
+ "core_group_name": "administrators",
+ "toolkit_group": "managers",
+ "request_id": "abc123",
+ "payload": { ... },
+ "db_context": { "key": "value" }
+}
+```
+
+`toolkit_group` is the users group within this specific toolkit (resolved via `jde_associations` or `toolkit_overrides`).
+
+`db_context` contains values fetched via `inject_db_context` config.
+
+## Client filter
+
+Validates the incoming request payload before anything else happens.
+
+```toml
+[endpoints.0.client_filter]
+allowed_fields = ["barcode", "quantity"]
+required_fields = ["barcode"]
+max_body_bytes = 4096
+```
+
+| Field | Notes |
+|-------------------------|------------------------------------------------------------------|
+| `allowed_fields` | only these fields are accepted, everything else gets stripped |
+| `required_fields` | these must be present or you get 400 |
+| `max_body_bytes` | max payload size |
+| `allowed_content_types` | restrict accepted content types |
+| `field_rules` | per field validation (type, max_length, pattern, allowed_values) |
+
+Per field rules example:
+
+```toml
+[endpoints.0.client_filter.field_rules.barcode]
+type = "string"
+max_length = 50
+pattern = "^[A-Z0-9-]+$"
+```
+
+## Database context injection
+
+`inject_db_context` lets you pull values from the database and include them in the request context.
+
+Simple: pull a value by column name
+```toml
+inject_db_context = ["users.email"]
+```
+
+Filtered: pull specific rows based on payload values
+```toml
+inject_db_context = ["items.name?id=$payload.item_id"]
+```
+
+The `$payload.field` syntax references fields from the clients request body.
+
+## Overwrite wrapping
+
+Modify the context envelope before sending it to the backend.
+
+- prefix with `-` to remove a field: `"-power"` removes the power level from context
+- without prefix: promotes a db_context value to a top level field
+
+## Success response
+
+```json
+{
+ "success": true,
+ "request_id": "abc123",
+ "endpoint": "/tk/app/beepzone/kiosk/scan",
+ "data": { ... }
+}
+```
+
+## Error responses
+
+| Code | When |
+|------|-----------------------------------------------------------|
+| 400 | payload validation failed |
+| 401 | no token or invalid session |
+| 403 | endpoint permission denied |
+| 404 | toolkit not found/disabled, endpoint path doesnt exist |
+| 500 | internal error, DB context fetch failed, executable error |
+| 502 | HTTP upstream returned an error |