Reihenfolge: Cronjobs vor Agents (Dashboard, Templates, Scripts) + PLAN-Cronjob.md entfernt

This commit is contained in:
Meleki committed 2026-03-03 22:49:56 +01:00
1 parent b645625b56
commit 17e269ccb5
2 files changed
+57 -130

No files matched your search

-73
View File
@@ -1,73 +0,0 @@
## Cronjobs – Planungsentwurf
### Konzept: Eigener Worker/Service in der App
**Warum nicht Linux-Cron?**
- App ist self-contained, soll ohne externe Abhängigkeiten laufen
- Cronjobs brauchen Zugriff auf DB, Agents, Sessions, Anthropic API
- Verwaltung über das Frontend (Dashboard) wäre mit Linux-Cron extrem umständlich
- Multi-User: Jeder User hat eigene Cronjobs
### Architektur
**Backend:**
1. **`CronjobRecord`** (Model) – DB-Tabelle `cronjobs`:
- `cronjob_id` (TEXT, GUID)
- `user_id` (TEXT)
- `session_id` (TEXT) – in welcher Session soll der Prompt gesendet werden
- `name` (TEXT) – z.B. "Täglicher Standup-Report"
- `cron_expression` (TEXT) – Standard Cron-Format: `0 9 * * *` (jeden Tag um 9:00)
- `prompt` (TEXT) – die Nachricht die an Claude gesendet wird
- `is_enabled` (BOOL) – aktiv/inaktiv
- `last_run_at` (TEXT) – wann zuletzt ausgeführt
- `next_run_at` (TEXT) – nächste geplante Ausführung (vorberechnet)
- `last_run_status` (TEXT) – "success" / "error"
- `last_run_error` (TEXT) – Fehlermeldung falls error
- `created_at`, `updated_at`
2. **`CronjobService`** (IHostedService / BackgroundService):
- Startet mit der App als `AddHostedService<CronjobService>()`
- Timer prüft jede Minute: "Gibt es Cronjobs deren `next_run_at` <= jetzt?"
- Wenn ja: Prompt an die Session senden (wie ein normaler Chat-Request, aber ohne SSE – fire & forget, Result in DB speichern)
- Nach Ausführung: `last_run_at` updaten, `next_run_at` neu berechnen
3. **`CronjobEndpoint`** (REST API):
- `GET /api/cronjobs` – alle Cronjobs des Users
- `POST /api/cronjobs` – neuen Cronjob anlegen
- `PUT /api/cronjobs/{id}` – bearbeiten
- `DELETE /api/cronjobs/{id}` – löschen
- `POST /api/cronjobs/{id}/toggle` – aktivieren/deaktivieren
- `POST /api/cronjobs/{id}/run` – manuell sofort ausführen (zum Testen)
4. **Cron-Expression Parser**: Nutzen wir `Cronos` NuGet-Package (leichtgewichtig, kein Overhead) oder schreiben wir einen eigenen einfachen Parser?
**Frontend:**
5. **Dashboard**: Neue Section "Cronjobs" mit Cards (ähnlich Sessions/Agents)
6. **Cronjob-Formular** (neue Page `tpl-cronjob`):
- Name
- Session (Dropdown)
- Cron-Expression (Input + Vorschau "Nächste Ausführung: ...")
- Prompt (Textarea)
- Aktiv/Inaktiv Toggle
7. **Cronjob-Card**: Name, Session-Name, Cron-Expression human-readable, Status (aktiv/inaktiv), letzte Ausführung
### Offene Fragen an dich:
1. **Cron-Expression oder vereinfacht?** Soll der User echte Cron-Expressions eingeben (`0 9 * * 1-5`) oder lieber ein vereinfachtes UI (Dropdown: "Täglich um X", "Wöchentlich am Y um Z", etc.)?
2. **Ausführung**: Soll der Cronjob die Antwort von Claude still in die Session-History schreiben (so als hätte der User die Nachricht geschrieben)? Oder soll es einen separaten "Cronjob-Log" geben?
3. **NuGet `Cronos`** für Cron-Parsing verwenden? (Ist der De-facto-Standard in .NET, ~50KB, keine Abhängigkeiten)
4. **Benachrichtigung**: Soll der User benachrichtigt werden wenn ein Cronjob ausgeführt wurde? (z.B. über die StatusBar, oder Telegram?)
--
Antworten auf die offenen Fragen:
1. Cron-Expression
2. Einfach direkt in die Session-History schreiben (als hätte der User die Nachricht geschrieben)
3. Cronos NuGet passt
4. Telegram, falls in der Session, in der der Cronjob läuft, Telegram eingerichtet und verbunden ist
+57 -57
View File
@@ -66,13 +66,6 @@
</div>
<div class="card-grid" id="sessionCards"></div>
</section>
<section>
<div class="section-header">
<h2>Agents</h2>
<button id="newAgentBtn" class="section-add-btn"><i class="fa fa-plus"></i> Neuer Agent</button>
</div>
<div class="card-grid" id="agentCards"></div>
</section>
<section>
<div class="section-header">
<h2>Cronjobs</h2>
@@ -80,6 +73,13 @@
</div>
<div class="card-grid" id="cronjobCards"></div>
</section>
<section>
<div class="section-header">
<h2>Agents</h2>
<button id="newAgentBtn" class="section-add-btn"><i class="fa fa-plus"></i> Neuer Agent</button>
</div>
<div class="card-grid" id="agentCards"></div>
</section>
</div>
</div>
</template>
@@ -138,6 +138,55 @@
</div>
</template>
<template id="tpl-cronjob">
<div class="page form-page">
<header>
<button class="back-btn icon-btn" data-page="dashboard"><i class="fa fa-arrow-left"></i></button>
<h1 id="cronjobPageTitle">Neuer Cronjob</h1>
</header>
<div class="page-content">
<div class="form-container">
<div class="form-group">
<label for="cronjobName">Name</label>
<input type="text" id="cronjobName" placeholder="z.B. Täglicher Report">
</div>
<div class="form-group">
<label for="cronjobSession">Session</label>
<select id="cronjobSession"></select>
</div>
<div class="form-group">
<label for="cronjobCron">Cron-Expression</label>
<input type="text" id="cronjobCron" placeholder="z.B. 0 9 * * *">
<small id="cronjobCronPreview" class="form-hint"></small>
</div>
<div class="form-group">
<label for="cronjobPrompt">Prompt</label>
<textarea id="cronjobPrompt" rows="6" placeholder="Die Nachricht, die an den Agent gesendet wird..."></textarea>
</div>
<div class="form-group">
<label for="cronjobNotifySession">Benachrichtigungs-Session <small>(optional)</small></label>
<select id="cronjobNotifySession"></select>
<small class="form-hint">Wenn gesetzt, wird eine Zusammenfassung in diese Session geschrieben (z.B. eine mit Telegram).</small>
</div>
<div class="form-group form-check-group">
<label>
<input type="checkbox" id="cronjobEnabled" checked>
Aktiv
</label>
</div>
<div id="cronjobStatusBox" class="form-status-box" hidden></div>
<div class="form-actions">
<button id="cronjobSaveBtn" class="primary-btn"><i class="fa fa-save"></i> Speichern</button>
<button id="cronjobRunBtn" class="secondary-btn" hidden><i class="fa fa-play"></i> Jetzt ausführen</button>
<button id="cronjobDeleteBtn" class="danger-btn" hidden><i class="fa fa-trash"></i> Löschen</button>
</div>
</div>
</div>
</div>
</template>
<template id="tpl-agent">
<div class="page form-page">
<header>
@@ -215,55 +264,6 @@
</div>
</template>
<template id="tpl-cronjob">
<div class="page form-page">
<header>
<button class="back-btn icon-btn" data-page="dashboard"><i class="fa fa-arrow-left"></i></button>
<h1 id="cronjobPageTitle">Neuer Cronjob</h1>
</header>
<div class="page-content">
<div class="form-container">
<div class="form-group">
<label for="cronjobName">Name</label>
<input type="text" id="cronjobName" placeholder="z.B. Täglicher Report">
</div>
<div class="form-group">
<label for="cronjobSession">Session</label>
<select id="cronjobSession"></select>
</div>
<div class="form-group">
<label for="cronjobCron">Cron-Expression</label>
<input type="text" id="cronjobCron" placeholder="z.B. 0 9 * * *">
<small id="cronjobCronPreview" class="form-hint"></small>
</div>
<div class="form-group">
<label for="cronjobPrompt">Prompt</label>
<textarea id="cronjobPrompt" rows="6" placeholder="Die Nachricht, die an den Agent gesendet wird..."></textarea>
</div>
<div class="form-group">
<label for="cronjobNotifySession">Benachrichtigungs-Session <small>(optional)</small></label>
<select id="cronjobNotifySession"></select>
<small class="form-hint">Wenn gesetzt, wird eine Zusammenfassung in diese Session geschrieben (z.B. eine mit Telegram).</small>
</div>
<div class="form-group form-check-group">
<label>
<input type="checkbox" id="cronjobEnabled" checked>
Aktiv
</label>
</div>
<div id="cronjobStatusBox" class="form-status-box" hidden></div>
<div class="form-actions">
<button id="cronjobSaveBtn" class="primary-btn"><i class="fa fa-save"></i> Speichern</button>
<button id="cronjobRunBtn" class="secondary-btn" hidden><i class="fa fa-play"></i> Jetzt ausführen</button>
<button id="cronjobDeleteBtn" class="danger-btn" hidden><i class="fa fa-trash"></i> Löschen</button>
</div>
</div>
</div>
</div>
</template>
<template id="tpl-chat">
<div class="page chat-page">
<header>
@@ -441,12 +441,12 @@
<script src="js/router.js"></script>
<script src="js/commands-ui.js"></script>
<script src="js/pages/dashboard.js"></script>
<script src="js/pages/cronjob-page.js"></script>
<script src="js/pages/agent-page.js"></script>
<script src="js/pages/session-page.js"></script>
<script src="js/pages/chat-page.js"></script>
<script src="js/pages/login-page.js"></script>
<script src="js/pages/settings-page.js"></script>
<script src="js/pages/cronjob-page.js"></script>
<script src="js/pages/profile-page.js"></script>
<script src="js/app.js"></script>
</body>