Cronjobs + AnthropicService Singleton Refactoring
Cronjobs: - CronjobService (BackgroundService) prüft jede Minute auf fällige Jobs - Cron-Expression in Server-Lokalzeit via Cronos (CronFormat.Standard) - Cronjob-Ausführung: Prompt → Session → Agent-Antwort in Chat-History - Optionale Benachrichtigungs-Session (notify_session_id): Zusammenfassung wird in separate Session geschrieben (z.B. mit Telegram) - Telegram-Benachrichtigung mit Cronjob-Name + Ursprungs-Session - REST API: CRUD + toggle + manuelles Ausführen (/run) - Frontend: Dashboard-Cards, Cronjob-Formular mit Cron-Vorschau, Session-Dropdown, Notify-Session-Dropdown, Status-Box Refactoring: - AnthropicService als Singleton in DI registriert - ChatEndpoint + TelegramService nutzen injizierte Instanz - Redundante Dependencies (Token, ToolService, MemoryService) entfernt Neue Dateien: - Models/CronjobRecord.cs - Services/CronjobService.cs - Endpoints/CronjobEndpoint.cs - wwwroot/js/pages/cronjob-page.js - PLAN-Cronjob.md
This commit is contained in:
1 parent
0120bb8f73
commit
b645625b56
16 files changed
+1132
-28
No files matched your search
@@ -166,6 +166,7 @@ public class DatabaseService
|
||||
TryAddColumn(conn, "users", "is_admin", "INTEGER NOT NULL DEFAULT 0");
|
||||
TryAddColumn(conn, "users", "persona", "TEXT");
|
||||
TryAddColumn(conn, "users", "settings", "TEXT");
|
||||
TryAddColumn(conn, "cronjobs", "notify_session_id", "TEXT");
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS agent_skills (
|
||||
@@ -205,6 +206,28 @@ public class DatabaseService
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_telegram_links_code ON telegram_links(link_code);
|
||||
");
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS cronjobs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
cronjob_id TEXT NOT NULL UNIQUE,
|
||||
user_id TEXT NOT NULL,
|
||||
session_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
cron_expression TEXT NOT NULL,
|
||||
prompt TEXT NOT NULL,
|
||||
notify_session_id TEXT,
|
||||
is_enabled INTEGER NOT NULL DEFAULT 1,
|
||||
last_run_at TEXT,
|
||||
next_run_at TEXT,
|
||||
last_run_status TEXT,
|
||||
last_run_error TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_cronjobs_user ON cronjobs(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_cronjobs_next_run ON cronjobs(next_run_at);
|
||||
");
|
||||
}
|
||||
|
||||
private void TryAddColumn(SqliteConnection conn, string table, string column, string type)
|
||||
@@ -862,4 +885,87 @@ public class DatabaseService
|
||||
"SELECT * FROM sessions WHERE user_id = @userId AND is_deleted = 0 ORDER BY updated_at DESC",
|
||||
new { userId });
|
||||
}
|
||||
|
||||
// ── Cronjobs ──
|
||||
|
||||
public async Task<CronjobRecord> CreateCronjob(CronjobRecord cronjob)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
cronjob.CronjobId = Guid.NewGuid().ToString("N");
|
||||
cronjob.CreatedAt = now;
|
||||
cronjob.UpdatedAt = now;
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO cronjobs (cronjob_id, user_id, session_id, name, cron_expression, prompt, notify_session_id, is_enabled, next_run_at, created_at, updated_at)
|
||||
VALUES (@CronjobId, @UserId, @SessionId, @Name, @CronExpression, @Prompt, @NotifySessionId, @IsEnabled, @NextRunAt, @CreatedAt, @UpdatedAt)
|
||||
", cronjob);
|
||||
return cronjob;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CronjobRecord>> GetCronjobs(string userId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<CronjobRecord>(@"
|
||||
SELECT c.*, s.name AS session_name, ns.name AS notify_session_name
|
||||
FROM cronjobs c
|
||||
LEFT JOIN sessions s ON c.session_id = s.session_id
|
||||
LEFT JOIN sessions ns ON c.notify_session_id = ns.session_id
|
||||
WHERE c.user_id = @userId
|
||||
ORDER BY c.name",
|
||||
new { userId });
|
||||
}
|
||||
|
||||
public async Task<CronjobRecord> GetCronjob(string cronjobId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QuerySingleOrDefaultAsync<CronjobRecord>(@"
|
||||
SELECT c.*, s.name AS session_name, ns.name AS notify_session_name
|
||||
FROM cronjobs c
|
||||
LEFT JOIN sessions s ON c.session_id = s.session_id
|
||||
LEFT JOIN sessions ns ON c.notify_session_id = ns.session_id
|
||||
WHERE c.cronjob_id = @cronjobId",
|
||||
new { cronjobId });
|
||||
}
|
||||
|
||||
public async Task UpdateCronjob(CronjobRecord cronjob)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
cronjob.UpdatedAt = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE cronjobs SET name = @Name, session_id = @SessionId, cron_expression = @CronExpression,
|
||||
prompt = @Prompt, notify_session_id = @NotifySessionId, is_enabled = @IsEnabled, next_run_at = @NextRunAt, updated_at = @UpdatedAt
|
||||
WHERE cronjob_id = @CronjobId AND user_id = @UserId",
|
||||
cronjob);
|
||||
}
|
||||
|
||||
public async Task DeleteCronjob(string cronjobId, string userId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
await conn.ExecuteAsync(
|
||||
"DELETE FROM cronjobs WHERE cronjob_id = @cronjobId AND user_id = @userId",
|
||||
new { cronjobId, userId });
|
||||
}
|
||||
|
||||
public async Task UpdateCronjobRun(string cronjobId, string status, string error, string nextRunAt)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE cronjobs SET last_run_at = @now, last_run_status = @status,
|
||||
last_run_error = @error, next_run_at = @nextRunAt, updated_at = @now
|
||||
WHERE cronjob_id = @cronjobId",
|
||||
new { cronjobId, status, error, nextRunAt, now = DateTime.UtcNow.ToString("o") });
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CronjobRecord>> GetDueCronjobs()
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
return await conn.QueryAsync<CronjobRecord>(@"
|
||||
SELECT c.*, s.name AS session_name, ns.name AS notify_session_name
|
||||
FROM cronjobs c
|
||||
LEFT JOIN sessions s ON c.session_id = s.session_id
|
||||
LEFT JOIN sessions ns ON c.notify_session_id = ns.session_id
|
||||
WHERE c.is_enabled = 1 AND c.next_run_at IS NOT NULL AND c.next_run_at <= @now",
|
||||
new { now });
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user