Fehler melden mit Screenshot und Markierung, Sammlung für Bearbeiter

Käfer-Button unten rechts: nimmt den sichtbaren Bildschirm mit html2canvas
(selbst gehostet) auf, Vorschau mit roten Rechtecken, Beschreibung, Name
optional, Senden ohne Anmeldung. Aus offenen Dialogen heraus wird der
Dialog selbst aufgenommen. Bearbeiter sehen die Meldungen unter „Fehler"
mit Zähler, kopieren einen fertigen Claude-Prompt und den Screenshot.

Serverseitig: Pfade nur in exakter Schreibweise, /api standardmäßig nur
für Bearbeiter mit ausdrücklicher Freigabeliste, Bremse zählt jeden
Versuch vor dem Lesen großer Bodies, X-Forwarded-For nur von vertrauten
Proxys, Nutzertext im Prompt eingezäunt. HTTP-Tests für die Sperren.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ferdi2goandClaude Fable 5.1 committed 2026-10-15 08:19:46 +00:00
1 parent 6a3c68aaac
commit 4ec23ccd25
15 files changed
+877 -36

No files matched your search

+8
View File
@@ -1,5 +1,6 @@
import fs from 'node:fs';
import path from 'node:path';
import { DEFAULT_PROMPT_TEMPLATE } from './bugs.js';
const DEFAULT_STATE = () => ({
persons: [],
@@ -7,6 +8,7 @@ const DEFAULT_STATE = () => ({
holidays: [],
assignments: {},
requests: [],
bugs: [],
exported: {},
settings: {
meetingTime: '09:30',
@@ -16,6 +18,7 @@ const DEFAULT_STATE = () => ({
inviteAttendees: false,
historyWindowDays: 60,
holidaysSeeded: false,
bugPromptTemplate: DEFAULT_PROMPT_TEMPLATE,
targetCalendarHref: '',
targetCalendarName: '',
absenceCalendarHref: '',
@@ -37,7 +40,9 @@ export function imageMime(buffer) {
export function createStore(dataDir) {
const file = path.join(dataDir, 'rotatory.json');
const photoDir = path.join(dataDir, 'photos');
const bugDir = path.join(dataDir, 'bugs');
fs.mkdirSync(photoDir, { recursive: true });
fs.mkdirSync(bugDir, { recursive: true });
let state = DEFAULT_STATE();
if (fs.existsSync(file)) {
@@ -60,5 +65,8 @@ export function createStore(dataDir) {
readPhoto: (id) => (fs.existsSync(photoPath(id)) ? fs.readFileSync(photoPath(id)) : null),
savePhoto: (id, buffer) => fs.writeFileSync(photoPath(id), buffer),
deletePhoto: (id) => { try { fs.unlinkSync(photoPath(id)); } catch {} },
saveBug: (id, buffer) => fs.writeFileSync(path.join(bugDir, `${id}.png`), buffer),
readBug: (id) => (fs.existsSync(path.join(bugDir, `${id}.png`)) ? fs.readFileSync(path.join(bugDir, `${id}.png`)) : null),
deleteBug: (id) => { try { fs.unlinkSync(path.join(bugDir, `${id}.png`)); } catch {} },
};
}