feat: automation rules
Owners and admins can set rules of the kind «when a ticket is created, moves, gets assigned, gets a comment or its pull request merges; if it is of this type, priority, area or label; then move it, assign it, label it, change its priority, comment or put it in the active sprint». Rules act as TaskStream within the workflow, run once per event and trigger no others. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { OutgoingWebhook } from '@task-stream/api/tracker/application';
|
||||
import {
|
||||
Automation,
|
||||
OutgoingWebhook,
|
||||
} from '@task-stream/api/tracker/application';
|
||||
import {
|
||||
ActivityReadModel,
|
||||
CommentReadModel,
|
||||
@@ -32,6 +35,12 @@ export type TimelineDoc = Doc<IssueTimelineEntry>;
|
||||
export type NotificationDoc = Doc<NotificationReadModel>;
|
||||
export type SavedFilterDoc = Doc<SavedFilterReadModel>;
|
||||
export type OutgoingWebhookDoc = Omit<OutgoingWebhook, 'id'> & { _id: string };
|
||||
export type AutomationDoc = Omit<Automation, 'id'> & { _id: string };
|
||||
export interface AutomationRunDoc {
|
||||
/** `ruleId:eventKey`: a rule runs once per event. */
|
||||
_id: string;
|
||||
at: Date;
|
||||
}
|
||||
export interface GitIntegrationDoc {
|
||||
_id: string;
|
||||
secret: string;
|
||||
@@ -55,6 +64,8 @@ export const ReadModels = {
|
||||
Sprint: 'SprintReadModel',
|
||||
GitIntegration: 'GitIntegration',
|
||||
OutgoingWebhook: 'OutgoingWebhook',
|
||||
Automation: 'Automation',
|
||||
AutomationRun: 'AutomationRun',
|
||||
} as const;
|
||||
|
||||
const userRef = { _id: false, id: String, name: String };
|
||||
@@ -218,6 +229,24 @@ export const OutgoingWebhookSchema = new Schema<OutgoingWebhookDoc>(
|
||||
{ ...loose, collection: 'outgoing_webhooks' },
|
||||
);
|
||||
|
||||
export const AutomationSchema = new Schema<AutomationDoc>(
|
||||
{
|
||||
_id: String,
|
||||
projectId: { type: String, index: true },
|
||||
active: Boolean,
|
||||
createdBy: userRef,
|
||||
createdAt: String,
|
||||
},
|
||||
{ ...loose, collection: 'automations' },
|
||||
);
|
||||
|
||||
export const AutomationRunSchema = new Schema<AutomationRunDoc>(
|
||||
{ _id: String, at: Date },
|
||||
{ ...loose, collection: 'automation_runs' },
|
||||
);
|
||||
// Redeliveries happen within minutes; a month of memory is plenty.
|
||||
AutomationRunSchema.index({ at: 1 }, { expireAfterSeconds: 30 * 86_400 });
|
||||
|
||||
export const READ_MODEL_SCHEMAS = [
|
||||
{ name: ReadModels.Project, schema: ProjectSchema },
|
||||
{ name: ReadModels.Issue, schema: IssueSchema },
|
||||
@@ -226,6 +255,8 @@ export const READ_MODEL_SCHEMAS = [
|
||||
{ name: ReadModels.Sprint, schema: SprintSchema },
|
||||
{ name: ReadModels.GitIntegration, schema: GitIntegrationSchema },
|
||||
{ name: ReadModels.OutgoingWebhook, schema: OutgoingWebhookSchema },
|
||||
{ name: ReadModels.Automation, schema: AutomationSchema },
|
||||
{ name: ReadModels.AutomationRun, schema: AutomationRunSchema },
|
||||
{ name: ReadModels.Activity, schema: ActivitySchema },
|
||||
{ name: ReadModels.Timeline, schema: TimelineSchema },
|
||||
{ name: ReadModels.Notification, schema: NotificationSchema },
|
||||
|
||||
Reference in New Issue
Block a user