dew/packages/kanban/lib/src/kanban_config.dart
Chris Hendrickson 53f9493364 Add ProjectDirs extension pattern and injectable clock
- core: Add ProjectDirs helper class on ProjectContext (context.dirs)
  with project getter for .project/ dir; feature packages extend it
  via extension methods to expose their own dirs

- kanban: Add KanbanDirs extension on ProjectDirs exposing .kanban;
  replace all 14 p.join(context.root, '.project', 'kanban') call
  sites with context.dirs.kanban; drop now-unused path imports

- kanban: Add clock: DateTime Function() field to TicketStore
  (defaults to DateTime.now); use clock().toUtc() in create() for
  deterministic timestamps in tests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-23 23:15:38 -04:00

72 lines
1.9 KiB
Dart

import 'package:dew_core/dew_core.dart';
import 'package:path/path.dart' as p;
import 'package:yaml/yaml.dart';
class TicketTypeConfig {
final String id;
final String name;
const TicketTypeConfig({required this.id, required this.name});
}
class ColumnConfig {
final String id;
final String name;
final String color;
/// Optional list of column IDs that this column can transition to.
/// If null/empty, all transitions are allowed.
final List<String> allowedTransitions;
const ColumnConfig({
required this.id,
required this.name,
required this.color,
this.allowedTransitions = const [],
});
}
class KanbanConfig {
final String prefix;
final List<TicketTypeConfig> ticketTypes;
final List<ColumnConfig> columns;
const KanbanConfig({
required this.prefix,
required this.ticketTypes,
required this.columns,
});
}
extension KanbanDewConfig on DewConfig {
KanbanConfig get kanban {
final kanbanYaml = (raw['dew'] as YamlMap)['kanban'] as YamlMap;
return KanbanConfig(
prefix: kanbanYaml['prefix'] as String,
ticketTypes:
(kanbanYaml['ticket_types'] as YamlList)
.map((t) => TicketTypeConfig(id: t['id'] as String, name: t['name'] as String))
.toList(),
columns:
(kanbanYaml['columns'] as YamlList)
.map(
(c) => ColumnConfig(
id: c['id'] as String,
name: c['name'] as String,
color: c['color'] as String,
allowedTransitions: (c['allowed_transitions'] as YamlList?)
?.map((t) => t as String)
.toList() ??
const [],
),
)
.toList(),
);
}
}
/// Extends [ProjectDirs] with the kanban board directory.
extension KanbanDirs on ProjectDirs {
/// Absolute path to `.project/kanban/`.
String get kanban => p.join(project, 'kanban');
}