Trip Categories
Categories classify transport trips hierarchically. A root category can have child categories, forming a tree (e.g., Material → Sand, Kies, Beton).
Category Fields
| Field | Type | Description |
|---|---|---|
id | UUID | Category ID |
parent_id | UUID? | Parent category; null = root |
name | string | Display name |
description | string? | Optional description |
color | string? | Hex color for UI badges |
is_active | bool | Inactive categories are hidden in selects |
sort_order | int | Display order within same parent |
REST Endpoints
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /v1/trip-categories | trip_categories:read | List all categories (tree structure) |
| GET | /v1/trip-categories/{id} | trip_categories:read | Get single category |
| POST | /v1/trip-categories | trip_categories:write | Create category |
| PATCH | /v1/trip-categories/{id} | trip_categories:write | Update category |
| DELETE | /v1/trip-categories/{id} | trip_categories:delete | Delete category (cascades children) |
GraphQL
tripCategories→[GqlTripCategory]— flat list; build tree client-side viaparentIdtripCategory(id)→GqlTripCategorycreateTripCategory(input)→GqlTripCategoryupdateTripCategory(id, input)→GqlTripCategorydeleteTripCategory(id)→Boolean
Create Category
POST /v1/trip-categories
{
"name": "Material",
"color": "#F59E0B",
"sort_order": 1
}
Child category:
POST /v1/trip-categories
{
"parent_id": "<material-uuid>",
"name": "Sand",
"color": "#D97706",
"sort_order": 1
}
Deletion Behaviour
Deleting a category cascades to all children (via ON DELETE CASCADE). A confirm dialog on the UI warns about this before deletion.
Setting a trip's category_id to a deleted category results in NULL (via ON DELETE SET NULL on the Trip table).
RBAC Permissions
| Permission | Description |
|---|---|
trip_categories:read | View categories |
trip_categories:write | Create and update categories |
trip_categories:delete | Delete categories |
Color Management
Categories use the ColorPicker component from @elcto/ui:
- Root categories get a random color from a curated HSL palette on creation
- Sub-categories inherit the parent category's color by default
- Colors are always editable via the color picker popover
- The picker includes 20 preset colors, hex input, random generator, and native OS color picker
Category Tree Display
The category list shows a hierarchical tree with:
- Color dot per category
- Depth-based indentation with vertical border lines
- Inline description below the name (with background box)
- Dividers between root categories
- Hover-revealed action buttons with tooltips (add child, edit, delete)