feat(config): add automation.cron schema for scheduled jobs
This commit is contained in:
@@ -0,0 +1,78 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { configSchema } from './schema.js';
|
||||||
|
|
||||||
|
describe('configSchema automation', () => {
|
||||||
|
const baseConfig = {
|
||||||
|
telegram: { bot_token: 'test-token', allowed_chat_ids: [123] },
|
||||||
|
models: { default: { provider: 'anthropic', model: 'claude-sonnet' } },
|
||||||
|
};
|
||||||
|
|
||||||
|
it('accepts config without automation section', () => {
|
||||||
|
const result = configSchema.parse(baseConfig);
|
||||||
|
expect(result.automation).toBeDefined();
|
||||||
|
expect(result.automation.cron).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts config with cron jobs', () => {
|
||||||
|
const result = configSchema.parse({
|
||||||
|
...baseConfig,
|
||||||
|
automation: {
|
||||||
|
cron: [{
|
||||||
|
name: 'morning-briefing',
|
||||||
|
schedule: '0 9 * * *',
|
||||||
|
message: 'Good morning!',
|
||||||
|
output: { channel: 'telegram', peer: '123' },
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(result.automation.cron).toHaveLength(1);
|
||||||
|
expect(result.automation.cron[0].name).toBe('morning-briefing');
|
||||||
|
expect(result.automation.cron[0].enabled).toBe(true); // default
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects cron job with empty name', () => {
|
||||||
|
expect(() => configSchema.parse({
|
||||||
|
...baseConfig,
|
||||||
|
automation: {
|
||||||
|
cron: [{
|
||||||
|
name: '',
|
||||||
|
schedule: '0 9 * * *',
|
||||||
|
message: 'test',
|
||||||
|
output: { channel: 'telegram', peer: '123' },
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
})).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects cron job with empty schedule', () => {
|
||||||
|
expect(() => configSchema.parse({
|
||||||
|
...baseConfig,
|
||||||
|
automation: {
|
||||||
|
cron: [{
|
||||||
|
name: 'test',
|
||||||
|
schedule: '',
|
||||||
|
message: 'test',
|
||||||
|
output: { channel: 'telegram', peer: '123' },
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
})).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts cron job with optional fields', () => {
|
||||||
|
const result = configSchema.parse({
|
||||||
|
...baseConfig,
|
||||||
|
automation: {
|
||||||
|
cron: [{
|
||||||
|
name: 'test',
|
||||||
|
schedule: '0 9 * * *',
|
||||||
|
message: 'test',
|
||||||
|
output: { channel: 'telegram', peer: '123' },
|
||||||
|
enabled: false,
|
||||||
|
timezone: 'America/New_York',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(result.automation.cron[0].enabled).toBe(false);
|
||||||
|
expect(result.automation.cron[0].timezone).toBe('America/New_York');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -71,6 +71,22 @@ const mcpSchema = z.object({
|
|||||||
servers: z.array(mcpServerSchema).default([]),
|
servers: z.array(mcpServerSchema).default([]),
|
||||||
}).default({ servers: [] });
|
}).default({ servers: [] });
|
||||||
|
|
||||||
|
const cronJobSchema = z.object({
|
||||||
|
name: z.string().min(1, 'Cron job name is required'),
|
||||||
|
schedule: z.string().min(1, 'Cron schedule is required'),
|
||||||
|
message: z.string().min(1, 'Cron message is required'),
|
||||||
|
output: z.object({
|
||||||
|
channel: z.string().min(1),
|
||||||
|
peer: z.string().min(1),
|
||||||
|
}),
|
||||||
|
enabled: z.boolean().default(true),
|
||||||
|
timezone: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const automationSchema = z.object({
|
||||||
|
cron: z.array(cronJobSchema).default([]),
|
||||||
|
}).default({});
|
||||||
|
|
||||||
export const configSchema = z.object({
|
export const configSchema = z.object({
|
||||||
telegram: telegramSchema,
|
telegram: telegramSchema,
|
||||||
server: serverSchema.default({}),
|
server: serverSchema.default({}),
|
||||||
@@ -79,8 +95,10 @@ export const configSchema = z.object({
|
|||||||
hooks: hooksSchema.default({}),
|
hooks: hooksSchema.default({}),
|
||||||
skills: skillsSchema.default({}),
|
skills: skillsSchema.default({}),
|
||||||
mcp: mcpSchema.default({ servers: [] }),
|
mcp: mcpSchema.default({ servers: [] }),
|
||||||
|
automation: automationSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Config = z.infer<typeof configSchema>;
|
export type Config = z.infer<typeof configSchema>;
|
||||||
export type TelegramConfig = z.infer<typeof telegramSchema>;
|
export type TelegramConfig = z.infer<typeof telegramSchema>;
|
||||||
export type ModelConfig = z.infer<typeof modelConfigSchema>;
|
export type ModelConfig = z.infer<typeof modelConfigSchema>;
|
||||||
|
export type CronJobConfig = z.infer<typeof cronJobSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user