godcrm/scripts/create-calendar-automations.mjs
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

181 lines
8.5 KiB
JavaScript

// Script to create CRM automations for Calendar → Tickets in GERAVIKA space
// Run once, then delete. After this, rules are managed via CRM UI.
import { dbAll, dbRun, dbGet, sqlNow } from '../backend/database/connection.js';
import crypto from 'crypto';
async function main() {
// Find or create automations_list table in System Data (project 101, space 37)
let automationsTable = await dbGet(
"SELECT id FROM universal_tables WHERE project_id = 101 AND name = 'automations_list'"
);
if (!automationsTable) {
const now = new Date().toISOString();
const result = await dbRun(
"INSERT INTO universal_tables (name, display_name, project_id, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)",
['automations_list', 'Automations', 101, now, now]
);
automationsTable = { id: result.lastID || result.lastInsertRowid };
console.log('Created automations_list table:', automationsTable.id);
const columns = [
{ column_name: 'name', display_name: 'Name', type: 'text', order_index: 0 },
{ column_name: 'description', display_name: 'Description', type: 'text', order_index: 1 },
{ column_name: 'table_id', display_name: 'Table ID', type: 'number', order_index: 2 },
{ column_name: 'table_name', display_name: 'Table', type: 'text', order_index: 3 },
{ column_name: 'trigger_type', display_name: 'Trigger', type: 'select', order_index: 4 },
{ column_name: 'action_type', display_name: 'Action', type: 'select', order_index: 5 },
{ column_name: 'is_active', display_name: 'Active', type: 'checkbox', order_index: 6 },
{ column_name: 'trigger_config', display_name: 'Trigger Config', type: 'text', order_index: 7 },
{ column_name: 'action_config', display_name: 'Action Config', type: 'text', order_index: 8 },
{ column_name: 'last_run', display_name: 'Last Run', type: 'date', order_index: 9 },
{ column_name: 'run_count', display_name: 'Run Count', type: 'number', order_index: 10 },
{ column_name: 'created_at', display_name: 'Created At', type: 'date', order_index: 11 }
];
for (const col of columns) {
await dbRun(
'INSERT INTO table_columns (table_id, column_name, display_name, type, order_index, is_visible) VALUES ($1, $2, $3, $4, $5, true)',
[automationsTable.id, col.column_name, col.display_name, col.type, col.order_index]
);
}
console.log('Created automation columns');
} else {
console.log('automations_list table exists:', automationsTable.id);
}
// Find or create logs table
let logsTable = await dbGet(
"SELECT id FROM universal_tables WHERE project_id = 101 AND name = 'automation_logs_list'"
);
if (!logsTable) {
const now = new Date().toISOString();
const result = await dbRun(
"INSERT INTO universal_tables (name, display_name, project_id, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)",
['automation_logs_list', 'Automation Logs', 101, now, now]
);
logsTable = { id: result.lastID || result.lastInsertRowid };
console.log('Created logs table:', logsTable.id);
const logCols = [
{ column_name: 'automation_id', display_name: 'Automation ID', type: 'number', order_index: 0 },
{ column_name: 'automation_name', display_name: 'Automation', type: 'text', order_index: 1 },
{ column_name: 'status', display_name: 'Status', type: 'select', order_index: 2 },
{ column_name: 'trigger_data', display_name: 'Trigger Data', type: 'text', order_index: 3 },
{ column_name: 'result_data', display_name: 'Result', type: 'text', order_index: 4 },
{ column_name: 'error_message', display_name: 'Error', type: 'text', order_index: 5 },
{ column_name: 'duration_ms', display_name: 'Duration (ms)', type: 'number', order_index: 6 },
{ column_name: 'executed_at', display_name: 'Executed At', type: 'date', order_index: 7 }
];
for (const col of logCols) {
await dbRun(
'INSERT INTO table_columns (table_id, column_name, display_name, type, order_index, is_visible) VALUES ($1, $2, $3, $4, $5, true)',
[logsTable.id, col.column_name, col.display_name, col.type, col.order_index]
);
}
console.log('Created log columns');
} else {
console.log('automation_logs_list exists:', logsTable.id);
}
console.log('Tables ready:', { automationsTableId: automationsTable.id, logsTableId: logsTable.id });
// Create automations
const now = new Date().toISOString();
const automations = [
{
name: 'Personal Calendar → Task',
description: 'When a new event syncs from geramonnn@gmail.com, auto-create a Task in Family Task Board. Excludes holidays/birthdays.',
table_id: 2671,
table_name: 'google_calendar_events',
trigger_type: 'row_create',
trigger_config: JSON.stringify({}),
action_type: 'create_row',
action_config: JSON.stringify({
targetTableId: 2649,
conditions: [
{ field: 'calendar_name', operator: 'equals', value: 'geramonnn@gmail.com' },
{ field: 'status', operator: 'not_equals', value: 'cancelled' },
{ field: 'title', operator: 'not_contains', value: 'праздник' },
{ field: 'title', operator: 'not_contains', value: 'holiday' }
],
fieldMappings: [
{ sourceColumnId: 'title', targetColumnId: 'what' },
{ sourceColumnId: 'description', targetColumnId: 'why' },
{ sourceColumnId: 'start_datetime', targetColumnId: 'scheduled_date' },
{ sourceColumnId: 'end_datetime', targetColumnId: 'due_date' },
{ targetColumnId: 'state', staticValue: 24275 },
{ targetColumnId: 'type', staticValue: 24269 },
{ targetColumnId: 'priority', staticValue: 24272 }
]
}),
is_active: true, run_count: 0, last_run: null, created_at: now
},
{
name: 'Family Calendar → Task',
description: 'Auto-create Task from Family Group calendar events.',
table_id: 2671,
table_name: 'google_calendar_events',
trigger_type: 'row_create',
trigger_config: JSON.stringify({}),
action_type: 'create_row',
action_config: JSON.stringify({
targetTableId: 2649,
conditions: [
{ field: 'calendar_name', operator: 'contains', value: 'Семейная' },
{ field: 'status', operator: 'not_equals', value: 'cancelled' }
],
fieldMappings: [
{ sourceColumnId: 'title', targetColumnId: 'what' },
{ sourceColumnId: 'description', targetColumnId: 'why' },
{ sourceColumnId: 'start_datetime', targetColumnId: 'scheduled_date' },
{ sourceColumnId: 'end_datetime', targetColumnId: 'due_date' },
{ targetColumnId: 'state', staticValue: 24275 },
{ targetColumnId: 'type', staticValue: 24269 },
{ targetColumnId: 'priority', staticValue: 24272 }
]
}),
is_active: true, run_count: 0, last_run: null, created_at: now
},
{
name: 'New Event → Notification',
description: 'Notify on new calendar events (exclude Thai holidays).',
table_id: 2671,
table_name: 'google_calendar_events',
trigger_type: 'row_create',
trigger_config: JSON.stringify({}),
action_type: 'notification',
action_config: JSON.stringify({
notificationType: 'in_app',
conditions: [
{ field: 'calendar_name', operator: 'not_contains', value: 'Праздники' },
{ field: 'status', operator: 'not_equals', value: 'cancelled' }
],
recipients: ['1'],
messageTemplate: '📅 New event: {{title}} ({{start_datetime}})'
}),
is_active: false, run_count: 0, last_run: null, created_at: now
}
];
for (const auto of automations) {
const baseId = 'auto_' + Date.now() + '_' + crypto.randomBytes(4).toString('hex');
const result = await dbRun(
'INSERT INTO table_rows (table_id, base_id, data, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)',
[automationsTable.id, baseId, JSON.stringify(auto), now, now]
);
const id = result.lastID || result.lastInsertRowid;
console.log(`Created: #${id} - ${auto.name} [${auto.trigger_type}${auto.action_type}] active=${auto.is_active}`);
}
// Verify
const all = await dbAll('SELECT id, data FROM table_rows WHERE table_id = $1', [automationsTable.id]);
console.log(`\nTotal automations in GERAVIKA space: ${all.length}`);
for (const a of all) {
const d = JSON.parse(a.data);
console.log(` #${a.id}: ${d.name} [${d.trigger_type}${d.action_type}] active=${d.is_active}`);
}
process.exit(0);
}
main().catch(err => { console.error(err); process.exit(1); });