Skip to main content

Swimlanes

A swimlane is a category that groups board cards by responsibility — Strategy, Engineering, Mechanical, Driver, Logistics, Hospitality, Auto. Every account has its own catalogue; the seed installs seven defaults that cover the majority of race-stand workflows.

Swimlanes are referenced by name from the board cards swimlane column and from issue rule actions — so renaming a lane is a catalogue-level operation, not a per-card update.

Source:

  • API route: apps/api/src/routes/swimlanes.ts
  • Schema: swimlanes table in apps/api/src/db/schema.ts

The seven default lanes

make seed installs:

PositionNameColorTypical owner
0Strategy#0070F3 (blue)Race engineer / strategist
1Engineering#22C55E (green)Performance / data engineer
2Mechanical#F59E0B (amber)Mechanic / pit crew
3Driver#7B61FF (purple)Driver coach
4Logistics#94A3B8 (slate)Truck / paddock
5Hospitality#FFD700 (gold)Sponsor / guest ops
6Auto#E10600 (red)Auto-fired rules — see Issue Rules

The seven lanes mirror HH-DM's stock list. They're wired into the seeded Issue Rules (rules write into Strategy / Engineering / Mechanical / Auto, depending on the trigger).

Position ordering

Lanes carry an integer position. The board card form's lane dropdown, the kanban column rail, and the Admin grid all sort by position ascending, breaking ties alphabetically by name.

When you create a new lane via POST /swimlanes without a position, the server places it at the end of the list:

const position = body.position ?? existing.length;

Reordering is a series of PATCH /swimlanes/:id calls that update position. The admin UI's drag-handle ribbon does this transparently; ad-hoc API consumers should make sure to keep positions unique within an account.

How board cards reference a lane

board_cards.swimlane is a plain text column — it stores the lane name, not its UUID. This intentionally mirrors HH-DM's behaviour: lane names are stable enough that a card surviving a rename is the wrong default. If you rename "Mechanical" to "Pit Crew", existing cards keep swimlane: "Mechanical" until you re-categorise them.

Same convention applies to issue rule action bodies — they reference the lane by name:

{
"action": {
"type": "card",
"swimlane": "Strategy",
"priority": "high",
"titleTemplate": "Yellow flag on lap {{lapNumber}}"
}
}

Authoring lanes

Today the catalogue is managed via the API directly. Wire shape (see /swimlanes for the full reference):

# Create
curl -X POST http://localhost:6161/swimlanes \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Catering", "color": "#10B981" }'

# Update
curl -X PATCH http://localhost:6161/swimlanes/<id> \
-H "Authorization: Bearer $TOKEN" \
-d '{ "position": 0 }'

# Delete
curl -X DELETE http://localhost:6161/swimlanes/<id> \
-H "Authorization: Bearer $TOKEN"

Constraints: name ≤ 60 chars; color ≤ 20 chars (typically a hex string); position is a non-negative int.

What's coming

  • Per-lane WIP limits — soft caps on the number of "in progress" cards per lane.
  • Per-lane default assignee — auto-set the assignee when a card is created in a given lane (e.g. cards in Mechanical default to the on-call mechanic).
  • Lane-scoped permissions — restrict who can move a card out of Auto into a real lane after triage.