@flowtile/core
v0.1.0
Published
Framework-agnostic ticket workflow engine with TypeScript-first API
Downloads
8
Maintainers
Readme
@flowtile/core
Framework-agnostic ticket workflow engine with TypeScript-first API.
Installation
npm install @flowtile/coreQuick Start
import { TicketEngine, WorkflowBuilder, MemoryAdapter } from '@flowtile/core';
// Create a workflow
const workflow = new WorkflowBuilder('my-workflow', 'My Workflow')
.addStage('todo', {
label: 'To Do',
requiredFields: ['Title'],
optionalFields: ['Description'],
exitCriteria: 'Ready to start',
color: '#6b7280',
})
.addStage('in_progress', {
label: 'In Progress',
requiredFields: ['Assignee'],
optionalFields: ['Notes'],
exitCriteria: 'Work is being done',
color: '#3b82f6',
})
.addStage('done', {
label: 'Done',
requiredFields: ['Completion notes'],
optionalFields: [],
exitCriteria: 'Complete',
color: '#10b981',
})
.build();
// Create engine
const engine = new TicketEngine({
workflow,
storage: new MemoryAdapter(),
});
// Create a ticket
const ticket = await engine.createTicket({
title: 'Fix login bug',
currentStage: 'todo',
});
// Add an entry
await engine.addEntry(ticket.id, {
ticketId: ticket.id,
stageKey: 'todo',
kind: 'note',
body: 'User reports they cannot log in',
createdBy: '[email protected]',
});
// Advance to next stage
await engine.advanceStage(ticket.id, {
madeBy: '[email protected]',
confidence: 'high',
});Preset Workflows
Use built-in workflow presets:
import { presets, TicketEngine, MemoryAdapter } from '@flowtile/core';
// Property maintenance workflow
const engine = new TicketEngine({
workflow: presets.maintenance(),
storage: new MemoryAdapter(),
});
// Other presets:
// - presets.kanban()
// - presets.bugTracker()
// - presets.helpDesk()Custom Storage Adapters
Implement the StorageAdapter interface to integrate with any database:
import { StorageAdapter, Ticket } from '@flowtile/core';
class PostgresAdapter implements StorageAdapter {
async getAll() {
// Your implementation
}
async getById(id: string) {
// Your implementation
}
async create(ticket: Ticket) {
// Your implementation
}
async update(ticket: Ticket) {
// Your implementation
}
async delete(id: string) {
// Your implementation
}
}Events
Listen to ticket lifecycle events:
engine.on('ticket:created', (ticket) => {
console.log('New ticket:', ticket.title);
});
engine.on('stage:advanced', ({ ticket, fromStage, toStage }) => {
console.log(`Ticket ${ticket.id} moved from ${fromStage} to ${toStage}`);
});Custom Exit Criteria Validators
Add custom validation logic:
const validators = new Map();
validators.set('verify', async (ticket, stageKey) => {
const photos = ticket.entries.filter(
(e) => e.stageKey === stageKey && e.kind === 'photo'
);
if (photos.length < 2) {
return {
valid: false,
reason: 'At least 2 photos are required',
};
}
return { valid: true };
});
const engine = new TicketEngine({
workflow,
storage: new MemoryAdapter(),
validators,
});API Reference
See the full documentation for detailed API reference.
License
MIT
