Column mapping
Map provider statuses to Discord forum columns with custom configurations.
Column mapping controls how provider statuses (like Jira workflow statuses) translate to Discord forum channels. The plugin supports default automatic mapping, custom columns, many-to-one mappings, and track-only statuses.
Default behavior
Without any configuration, the plugin maps Jira status categories to three columns:
| Jira category | Discord column |
|---|---|
| To Do | Backlog |
| In Progress | In Progress |
| Done | Done |
These defaults work immediately. No configuration needed to start syncing.
Provider-level mapping
Override the defaults by configuring columnConfig in your provider options:
import { JiraProvider } from '@robojs/roadmap'
export default {
provider: new JiraProvider({
type: 'jira',
options: {
url: process.env.JIRA_URL,
email: process.env.JIRA_EMAIL,
apiToken: process.env.JIRA_API_TOKEN,
projectKey: process.env.JIRA_PROJECT_KEY,
columnConfig: {
columns: [
{ id: 'planning', name: 'Planning', order: 0 },
{ id: 'development', name: 'Development', order: 1 },
{ id: 'review', name: 'Review', order: 2 },
{ id: 'done', name: 'Done', order: 3, archived: true }
],
statusMapping: {
'Backlog': 'Planning',
'To Do': 'Planning',
'In Progress': 'Development',
'Code Review': 'Review',
'QA': 'Review',
'Done': 'Done',
'Closed': null,
"Won't Do": null
}
}
}
})
}import { JiraProvider } from '@robojs/roadmap'
export default {
provider: new JiraProvider({
type: 'jira',
options: {
url: process.env.JIRA_URL,
email: process.env.JIRA_EMAIL,
apiToken: process.env.JIRA_API_TOKEN,
projectKey: process.env.JIRA_PROJECT_KEY,
columnConfig: {
columns: [
{ id: 'planning', name: 'Planning', order: 0 },
{ id: 'development', name: 'Development', order: 1 },
{ id: 'review', name: 'Review', order: 2 },
{ id: 'done', name: 'Done', order: 3, archived: true }
],
statusMapping: {
'Backlog': 'Planning',
'To Do': 'Planning',
'In Progress': 'Development',
'Code Review': 'Review',
'QA': 'Review',
'Done': 'Done',
'Closed': null,
"Won't Do": null
}
}
}
})
}Column properties
Prop
Type
Many-to-one mappings
Multiple statuses can map to the same column. This is useful when your workflow has more statuses than you want Discord columns:
statusMapping: {
'Backlog': 'Planning',
'To Do': 'Planning', // Both map to Planning
'In Progress': 'Active',
'Code Review': 'Active', // Both map to Active
'QA': 'Active', // All three in the same forum
'Done': 'Done'
}statusMapping: {
'Backlog': 'Planning',
'To Do': 'Planning', // Both map to Planning
'In Progress': 'Active',
'Code Review': 'Active', // Both map to Active
'QA': 'Active', // All three in the same forum
'Done': 'Done'
}Track-only mappings
Map a status to null to track it without creating a forum thread. This is useful for statuses you want to monitor programmatically (e.g., for changelogs) without cluttering Discord:
statusMapping: {
'Done': 'Done',
'Closed': null, // Tracked but no forum thread
"Won't Do": null // Tracked but no forum thread
}statusMapping: {
'Done': 'Done',
'Closed': null, // Tracked but no forum thread
"Won't Do": null // Tracked but no forum thread
}Cards with track-only mappings have metadata.trackOnly: true and preserve their original status in metadata.originalStatus.
Per-guild runtime overrides
Override column mappings per-guild using the /roadmap setup panel or the settings API. Guild-level overrides take precedence over provider-level mappings.
import { setColumnMapping, getColumnMapping, removeColumnMapping } from '@robojs/roadmap'
// Map QA status to Development column for this guild
setColumnMapping(guildId, 'QA', 'Development')
// Track Blocked status without creating a forum thread
setColumnMapping(guildId, 'Blocked', null)
// View current mappings
const mapping = getColumnMapping(guildId)
// Remove a guild override (falls back to provider mapping)
removeColumnMapping(guildId, 'QA')import { setColumnMapping, getColumnMapping, removeColumnMapping } from '@robojs/roadmap'
// Map QA status to Development column for this guild
setColumnMapping(guildId, 'QA', 'Development')
// Track Blocked status without creating a forum thread
setColumnMapping(guildId, 'Blocked', null)
// View current mappings
const mapping = getColumnMapping(guildId)
// Remove a guild override (falls back to provider mapping)
removeColumnMapping(guildId, 'QA')Custom columns per guild
Define custom column definitions for a specific guild:
import { setCustomColumns, getCustomColumns } from '@robojs/roadmap'
setCustomColumns(guildId, [
{ id: 'backlog', name: 'Backlog', order: 0 },
{ id: 'active', name: 'Active', order: 1 },
{ id: 'done', name: 'Done', order: 2, archived: true }
])
const columns = getCustomColumns(guildId)import { setCustomColumns, getCustomColumns } from '@robojs/roadmap'
setCustomColumns(guildId, [
{ id: 'backlog', name: 'Backlog', order: 0 },
{ id: 'active', name: 'Active', order: 1 },
{ id: 'done', name: 'Done', order: 2, archived: true }
])
const columns = getCustomColumns(guildId)Resolution order
When determining which column a card belongs to, the engine checks:
- Guild-level column mapping (runtime overrides via settings)
- Provider-level status mapping (configured in
columnConfig.statusMapping) - Provider default mapping (e.g., Jira status category to default columns)
Status matching is case-insensitive at all levels.
Archived columns
Columns marked as archived: true behave differently:
- No forum channel is created for archived columns
- Existing threads are archived when a card moves to an archived column
- New cards in archived columns are skipped (no thread created)
- Moving a card out of an archived column creates a new thread
