<!-- source-hash: 17f22ebd29735a4ef28b5782559c367e -->
Defines the core data types and utility functions for the Kanban-style ticket board, including column definitions, ticket shapes, and helpers for mapping ticket statuses to board columns.

## Key Components

### Types

| Type | Description |
|------|-------------|
| `BoardPriority` | Union type for ticket priority levels: `low`, `medium`, `high`, `urgent` |
| `BoardTicketAssignee` | Assignee shape with optional avatar, initials, and name |
| `BoardTicket` | Core ticket shape with status, priority, assignees, tags, and device info |
| `BoardColumnDef` | Column definition including tickets, loading states, and drag/drop controls |
| `BoardChange` | Represents a ticket move event between columns with ordering context |

### Functions

| Function | Description |
|----------|-------------|
| `columnFromTicketStatus` | Creates a `BoardColumnDef` from a `TicketStatus` with optional overrides |
| `groupTicketsByStatus` | Buckets a flat ticket array into ordered columns by status |
| `canonicalize` (internal) | Normalizes raw status strings to `TicketStatus`, including legacy `ACTION_REQUIRED → TECH_REQUIRED` mapping |

## Usage Example

```typescript
import { groupTicketsByStatus, columnFromTicketStatus } from './types'

// Group tickets into columns for the board
const columns = groupTicketsByStatus(tickets, [
  'ACTIVE',
  'TECH_REQUIRED',
  'ON_HOLD',
  'RESOLVED',
])

// Build a single column with custom label and loading state
const activeColumn = columnFromTicketStatus('ACTIVE', activeTickets, {
  label: 'In Progress',
  isLoadingMore: true,
  total: 42,
})
```

> `canonicalize` handles legacy status values automatically — `ACTION_REQUIRED` from older API responses is silently mapped to `TECH_REQUIRED` before bucketing.