/ opencodehub / src / pages / api / automation-rules.ts
swadhinbiswas Fix: Add date validation in analysis.ts to prevent RangeError · 1/20/2026
a7662cd
143 lines · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
 * Automation Rules API
 * CRUD operations for workflow automation rules
 */

import type { APIRoute } from "astro";
import { eq, and } from "drizzle-orm";
import { getDatabase, schema } from "@/db";
import { withErrorHandler, Errors } from "@/lib/errors";
import { logger } from "@/lib/logger";
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import { success, created, badRequest, unauthorized } from "@/lib/api";

function generateId(): string {
    return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}

export const GET: APIRoute = withErrorHandler(async ({ locals, url }) => {
    const user = locals.user;

    if (!user) {
        return unauthorized();
    }

    const repoId = url.searchParams.get("repositoryId");
    if (!repoId) {
        return badRequest("repositoryId required");
    }

    const db = getDatabase() as NodePgDatabase<typeof schema>;
    const rules = await db.query.automationRules.findMany({
        where: eq(schema.automationRules.repositoryId, repoId),
    });

    return success({ rules });
});

export const POST: APIRoute = withErrorHandler(async ({ locals, request }) => {
    const user = locals.user;

    if (!user) {
        return unauthorized();
    }

    const body = await request.json();
    const { repositoryId, name, description, trigger, conditions, actions } = body;

    if (!repositoryId || !name || !trigger || !actions) {
        return badRequest("Missing required fields");
    }

    const db = getDatabase() as NodePgDatabase<typeof schema>;

    const rule = {
        id: generateId(),
        repositoryId,
        createdById: user.id,
        name,
        description: description || null,
        trigger,
        conditions: conditions ? JSON.stringify(conditions) : null,
        actions: typeof actions === "string" ? actions : JSON.stringify(actions),
        isEnabled: true,
        priority: 0,
        runCount: 0,
        createdAt: new Date(),
        updatedAt: new Date(),
    };

    await db.insert(schema.automationRules).values(rule);

    logger.info({ ruleId: rule.id, userId: user.id, repositoryId }, "Automation rule created");

    return created({ rule });
});

export const PATCH: APIRoute = withErrorHandler(async ({ locals, request, url }) => {
    const user = locals.user;

    if (!user) {
        return unauthorized();
    }

    const ruleId = url.searchParams.get("id");
    if (!ruleId) {
        return badRequest("Rule ID required");
    }

    const body = await request.json();
    const db = getDatabase() as NodePgDatabase<typeof schema>;

    const updates: Record<string, unknown> = {
        updatedAt: new Date(),
    };

    if (body.name !== undefined) updates.name = body.name;
    if (body.description !== undefined) updates.description = body.description;
    if (body.trigger !== undefined) updates.trigger = body.trigger;
    if (body.conditions !== undefined) {
        updates.conditions = typeof body.conditions === "string"
            ? body.conditions
            : JSON.stringify(body.conditions);
    }
    if (body.actions !== undefined) {
        updates.actions = typeof body.actions === "string"
            ? body.actions
            : JSON.stringify(body.actions);
    }
    if (body.isEnabled !== undefined) updates.isEnabled = body.isEnabled;
    if (body.priority !== undefined) updates.priority = body.priority;

    await db
        .update(schema.automationRules)
        .set(updates)
        .where(eq(schema.automationRules.id, ruleId));

    logger.info({ ruleId, userId: user.id }, "Automation rule updated");

    return success({ success: true });
});

export const DELETE: APIRoute = withErrorHandler(async ({ locals, url }) => {
    const user = locals.user;

    if (!user) {
        return unauthorized();
    }

    const ruleId = url.searchParams.get("id");
    if (!ruleId) {
        return badRequest("Rule ID required");
    }

    const db = getDatabase() as NodePgDatabase<typeof schema>;
    await db
        .delete(schema.automationRules)
        .where(eq(schema.automationRules.id, ruleId));

    logger.info({ ruleId, userId: user.id }, "Automation rule deleted");

    return success({ success: true });
});