Merge branch 'feature/speaker_renaming' into 'develop'

Remade replace Speaker module which now takes the premade speaker mapping json...

See merge request proj-wise2526-video2document/video2document!89
This commit is contained in:
Hughes, Mike
2026-01-15 14:36:24 +01:00
8 changed files with 459 additions and 224 deletions
Vendored
BIN
View File
Binary file not shown.
+138 -92
View File
@@ -1,5 +1,5 @@
// Loading required packages // Loading required packages
require("./requires.js") require("./requires.js");
console.log(start); console.log(start);
const https = require("https"); const https = require("https");
@@ -55,16 +55,17 @@ req.end();
// Initialising map to be used to store the functionality later on for reloadability // Initialising map to be used to store the functionality later on for reloadability
mapFunctions = new Map() mapFunctions = new Map();
// Loading the Function Map // Loading the Function Map
var path = `${mainDir}/services/modules` var path = `${mainDir}/services/modules`;
var folders = fs.readdirSync(path).filter(function (file) { var folders = fs.readdirSync(path).filter(function (file) {
return fs.statSync(path+'/'+file).isDirectory(); return fs.statSync(path + "/" + file).isDirectory();
}); });
folders.forEach(element => { folders.forEach((element) => {
var commandFiles = fs.readdirSync(`${path}/${element}`).filter(file => file.endsWith('.js') && !file.startsWith("index")); var commandFiles = fs
.readdirSync(`${path}/${element}`)
.filter((file) => file.endsWith(".js") && !file.startsWith("index"));
for (const file of commandFiles) { for (const file of commandFiles) {
delete require.cache[require.resolve(`${path}/${element}/${file}`)]; delete require.cache[require.resolve(`${path}/${element}/${file}`)];
const command = require(`${path}/${element}/${file}`); const command = require(`${path}/${element}/${file}`);
@@ -74,11 +75,13 @@ folders.forEach(element => {
// The startup information for the project, here you can add stuff that might be nice to see when the app starts // The startup information for the project, here you can add stuff that might be nice to see when the app starts
mapFunctions.get("Startup_function").function() mapFunctions.get("Startup_function").function();
console.log("------------------------------------ Status ------------------------------------"); console.log(
"------------------------------------ Status ------------------------------------"
);
console.log(__dirname); console.log(__dirname);
console.log(platform); console.log(platform);
console.log(`The Startup took ${new Date() - start}ms`) console.log(`The Startup took ${new Date() - start}ms`);
console.log(`${mapFunctions.size} Function modules loaded`); console.log(`${mapFunctions.size} Function modules loaded`);
console.log("--------------------------------------------------------------------------------"); console.log("--------------------------------------------------------------------------------");
@@ -93,11 +96,11 @@ function createWindow() {
webPreferences: { webPreferences: {
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,
preload: `${mainDir}/electron/main/preload.js` preload: `${mainDir}/electron/main/preload.js`,
} },
}); });
mainWindow.loadFile('./electron/main/index.html'); mainWindow.loadFile("./electron/main/index.html");
} }
electron.app.whenReady().then(createWindow); electron.app.whenReady().then(createWindow);
@@ -107,20 +110,10 @@ electron.ipcMain.handle('get-module-names', async () => {
"ai_modules":[], "ai_modules":[],
"transcription_modules":[] "transcription_modules":[]
} }
mapFunctions.forEach(e => {
switch(e.type){
case "llm":
module_array.ai_modules.push({"name": e.name, "displayname": e.displayname})
break;
case "transcription":
module_array.transcription_modules.push({"name": e.name, "displayname": e.displayname})
break;
}
})
// console.log(module_array);
return module_array
}); });
// console.log(module_array);
return module_array;
});
// electron.ipcMain.on("get_modules", async (event, args) => { // electron.ipcMain.on("get_modules", async (event, args) => {
// let module_array = { // let module_array = {
@@ -142,21 +135,21 @@ electron.ipcMain.handle('get-module-names', async () => {
// mainWindow.webContents.send("modules", module_array) // mainWindow.webContents.send("modules", module_array)
// }) // })
var globalArgs = {} var globalArgs = {};
var globalFinalHtmlPath = "" var globalFinalHtmlPath = "";
electron.ipcMain.on("file_submit", async (event, args) => { electron.ipcMain.on("file_submit", async (event, args) => {
try { try {
globalArgs = args globalArgs = args;
let curstep = 0 let curstep = 0;
let totalsteps = 4 let totalsteps = 4;
const TEMPLATE_MAP = { const TEMPLATE_MAP = {
"followup-report": "followup_report.txt", "followup-report": "followup_report.txt",
"agenda": "agenda.txt", agenda: "agenda.txt",
"result-protocol": "result_protocol.txt", "result-protocol": "result_protocol.txt",
"sprint-planning": "sprint_planning_note.txt", "sprint-planning": "sprint_planning_note.txt",
"custom": "custom_document.txt" custom: "custom_document.txt",
}; };
const templateFile = TEMPLATE_MAP[args.document.type]; const templateFile = TEMPLATE_MAP[args.document.type];
@@ -166,106 +159,159 @@ electron.ipcMain.on("file_submit", async (event, args) => {
} }
console.log(args); console.log(args);
let audiopath = "" let audiopath = "";
let transcriptpath = "" let transcriptpath = "";
console.log("\n\n Running the Video to Audio Extractor"); console.log("\n\n Running the Video to Audio Extractor");
// This code handles the Video to Audio extraction module call // This code handles the Video to Audio extraction module call
await mapFunctions.get("module-handler").function(args.video.module, {inputVideoPath: args.video.inputVideoPath, outputType: mapFunctions.get(args.transcription.module).audioformat}).then(resp => { await mapFunctions
console.log(resp); .get("module-handler")
audiopath = resp .function(args.video.module, {
curstep++ inputVideoPath: args.video.inputVideoPath,
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) outputType: mapFunctions.get(args.transcription.module).audioformat,
}).catch(err => {
mainWindow.webContents.send("error", err)
console.log(err);
return
}) })
.then((resp) => {
console.log("\n\n Running the Audio to Transcription module");
// TODO implement transcription module
// This code handles the Audio to Text transcription module call
await mapFunctions.get("module-handler").function(args.transcription.module, audiopath).then(resp => {
console.log(resp); console.log(resp);
transcriptpath = resp audiopath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the Transcription Summarizer module"); console.log("\n\n Running the Transcription Summarizer module");
// This code summarises the transcript, so that it can be used by an llm // This code summarises the transcript, so that it can be used by an llm
// await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => { // await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => {
await mapFunctions.get("summarize-transcription2").function(transcriptpath).then(resp => { await mapFunctions
.get("summarize-transcription2")
.function(transcriptpath)
.then((resp) => {
console.log(resp); console.log(resp);
transcriptpath = resp transcriptpath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the LLM module"); console.log("\n\n Running the LLM module");
// TODO implement documentation module // TODO implement documentation module
// This code handles the Text to Document processing module call // This code handles the Text to Document processing module call
console.log(`\n\n Running the LLM for Document Style ${args.document.type}`); console.log(
`\n\n Running the LLM for Document Style ${args.document.type}`
);
await mapFunctions.get("module-handler").function(args.document.module, { inputTranscriptPath: transcriptpath, documentTypePath: "./storage/documentType/" + templateFile, language: "en" }).then(resp => { await mapFunctions
.get("module-handler")
.function(args.document.module, {
inputTranscriptPath: transcriptpath,
documentTypePath: "./storage/documentType/" + templateFile,
language: "en",
})
.then((resp) => {
console.log(resp); console.log(resp);
globalFinalHtmlPath = resp globalFinalHtmlPath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
await mapFunctions.get("extract-speaker-snippets").function({audioPath: audiopath, jsonPath: transcriptpath }).then(resp => {
mainWindow.webContents.send("speakerAudios", resp)
}).catch(err => {
mainWindow.webContents.send("error", err)
console.log(err); console.log(err);
return return;
});
await mapFunctions
.get("extract-speaker-snippets")
.function({ audioPath: audiopath, jsonPath: transcriptpath })
.then((resp) => {
mainWindow.webContents.send("speakerAudios", resp);
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
}) });
electron.ipcMain.on("file_download", async () => { electron.ipcMain.on("file_download", async () => {
await mapFunctions.get("htmlDocumentConverter").convert({inputPath:globalFinalHtmlPath, format: globalArgs.document.outputType, showDialog: true}); await mapFunctions
}) .get("htmlDocumentConverter")
.convert({
inputPath: globalFinalHtmlPath,
format: globalArgs.document.outputType,
showDialog: true,
});
});
electron.ipcMain.on("speaker_submit", async() => { electron.ipcMain.on("speaker_submit", async (event, args) => {
console.log("\n\n\nJa also hier kam was an \n\n\n"); console.log("\n\n\nJa also hier kam was an \n\n\n");
}) console.log(args);
try {
await mapFunctions.get("replace_speaker").function(args);
event.reply("speaker_submit_response", { success: true });
} catch (error) {
console.error("Error:", error);
event.reply("speaker_submit_response", {
success: false,
error: error.message,
});
}
});
let q = {
video: {
module: "String", // The name of the module, idk if we ever implement other extraction modules, the default one is extraction-video-to-audio
inputVideoPath: "String", // See script.js on line 27 for an example of what this should look like
outputType: "String", // The file format to be used for the audio output file, such as wav, mp3, flac and so on
},
transcription: {
module: "String", // The module name of the transcription model you want to use
},
document: {
module: "String", // The module name of the AI model you want to use to create the document
styles: [
// An array of all the document styles/prompts you want to have the document be processed with
{
prompt: "String",
},
],
},
};
//gibt Documentfiles an preload zurück //gibt Documentfiles an preload zurück
electron.ipcMain.handle('get-txt-files', () => { electron.ipcMain.handle("get-txt-files", () => {
const storagePath = `${mainDir}/storage/documentType` const storagePath = `${mainDir}/storage/documentType`;
return fs.readdirSync(storagePath) return fs.readdirSync(storagePath).filter((f) => f.endsWith(".txt"));
.filter(f => f.endsWith('.txt'))
}); });
//speichern neuer document types //speichern neuer document types
electron.ipcMain.handle('save-txt-file', (event, fileName, content) => { electron.ipcMain.handle("save-txt-file", (event, fileName, content) => {
const filePath = `${mainDir}/storage/documentType/${fileName}.txt`; const filePath = `${mainDir}/storage/documentType/${fileName}.txt`;
fs.writeFileSync(filePath, content, 'utf8'); fs.writeFileSync(filePath, content, "utf8");
return true; return true;
}); });
@@ -0,0 +1,79 @@
const fs = require('fs');
const path = require('path');
const module_exports = {
name: "replace_speaker",
type: "processor",
displayname: "Speaker Name Replacer",
description: "Replaces speaker placeholder names with actual names based on a mapping in HTML files",
async function(speakerMapping) {
// Relativ von dieser Datei aus
const documentsDir = path.resolve(__dirname, '../../../storage/documents');
const inputHtmlPath = await this.getNewestFile(documentsDir, '.html');
if (!inputHtmlPath) {
throw new Error(`No HTML files found in ${documentsDir}`);
}
return await this.replaceNames(inputHtmlPath, speakerMapping);
},
getNewestFile: async function(dirPath, extension) {
try {
const files = await fs.promises.readdir(dirPath);
const filtered = files.filter(f => f.endsWith(extension));
if (filtered.length === 0) return null;
const filesWithStats = await Promise.all(
filtered.map(async (f) => {
const fullPath = path.join(dirPath, f);
const stats = await fs.promises.stat(fullPath);
return { path: fullPath, time: stats.mtimeMs };
})
);
return filesWithStats.reduce((newest, curr) =>
curr.time > newest.time ? curr : newest
).path;
} catch (error) {
console.error("Error reading directory:", error);
throw error;
}
},
replaceNames: async function(inputHtmlPath, speakerMapping) {
try {
const htmlContent = await fs.promises.readFile(inputHtmlPath, "utf-8");
let outputContent = htmlContent;
Object.entries(speakerMapping).forEach(([placeholder, value]) => {
// Extract name if value is an object
const displayName = typeof value === 'string' ? value : value.name;
// Normalize placeholder for matching (remove case sensitivity)
const normalizedPlaceholder = placeholder.toLowerCase();
// Replace all variations: speakerA, SpeakerA, SPEAKERA, speaker_a, Speaker A, etc.
// Matches with optional spaces, underscores, and parentheses
const regex = new RegExp(
`\\b[Ss]peaker\\s*[_-]?\\s*${placeholder.charAt(placeholder.length - 1)}\\b|\\b${placeholder}\\b`,
'gi'
);
outputContent = outputContent.replace(regex, displayName);
});
await fs.promises.writeFile(inputHtmlPath, outputContent, "utf-8");
return inputHtmlPath;
} catch (error) {
console.error("Error replacing speaker names:", error);
throw error;
}
}
};
module.exports = module_exports;
+32 -13
View File
@@ -1,26 +1,45 @@
# Meeting Agenda Generator
Du bist ein erfahrener Moderator und Projektmanager. Du bist ein erfahrener Moderator und Projektmanager.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle eine sinnvolle Meeting-Agenda basierend auf dem folgenden Transkript. **speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
ANFORDERUNGEN: Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle eine sinnvolle Meeting-Agenda basierend auf dem Meeting-Transkript.
## ANFORDERUNGEN:
- Rekonstruiere die tatsächlichen Themenblöcke - Rekonstruiere die tatsächlichen Themenblöcke
- Ordne sie logisch und chronologisch - Ordne sie logisch und chronologisch
- Fasse ähnliche Diskussionen zusammen - Fasse ähnliche Diskussionen zusammen
- Keine irrelevanten Details aufnehmen - Keine irrelevanten Details aufnehmen
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
- Titel der Agenda
- Ziel des Meetings (12 Sätze)
- Agenda-Punkte (nummeriert)
- Thema
- Kurzbeschreibung
- Ziel des Punktes (Information, Entscheidung, Diskussion)
STIL: ### 1. Titel der Agenda
### 2. Ziel des Meetings
- 12 präzise Sätze
### 3. Agenda-Punkte (nummeriert)
Für jeden Punkt:
- **Thema**
- **Kurzbeschreibung**
- **Ziel des Punktes:** (Information / Entscheidung / Diskussion)
## STIL:
- Klar, kompakt - Klar, kompakt
- Business-orientiert - Business-orientiert
- Keine Sprecher- oder Zeitangaben - Keine Sprecher- oder Zeitangaben
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Logische Reihenfolge
TRANSKRIPT: ---
**TRANSKRIPT:**
+34 -12
View File
@@ -1,22 +1,44 @@
# Custom Document Generator
Du bist ein intelligenter Dokumenten-Generator. Du bist ein intelligenter Dokumenten-Generator.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle ein individuelles Dokument basierend auf: Erstelle ein individuelles Dokument basierend auf:
1) dem Meeting-Transkript 1. dem Meeting-Transkript
2) der zusätzlichen Nutzeranweisung 2. der zusätzlichen Nutzeranweisung
WICHTIG: ## ANFORDERUNGEN:
- Priorisiere die Nutzeranweisung - **Priorisiere die Nutzeranweisung** über standardisierte Strukturen
- Nutze das Transkript als Wissensquelle - Nutze das Transkript als Wissensquelle
- Struktur, Tonalität und Detailgrad anpassen - Struktur, Tonalität und Detailgrad nach Nutzervorgabe anpassen
- Inhalte logisch zusammenführen - Inhalte logisch zusammenführen
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
FORMAT: ## VORGEHEN:
- Passe Struktur und Stil an den Nutzerwunsch an 1. Lese die Nutzeranweisung sorgfältig
- Klare Überschriften 2. Extrahiere aus dem Transkript die relevanten Informationen
- Keine Sprecher- oder Zeitangaben 3. Erstelle das Dokument nach der gewünschten Struktur
4. Behalte Sprecher-Platzhalter unverändert
TRANSKRIPT & NUTZERANWEISUNG: ## ALLGEMEINE RICHTLINIEN:
- Entferne Redundanzen und Smalltalk
- Keine Zeitstempel oder Sprecherangaben (wenn nicht gefordert)
- Sachlich, präzise, professionell
- Keine Spekulationen oder Meinungen (wenn nicht gefordert)
---
**NUTZERANWEISUNG:**
[Hier kommt die Anforderung des Nutzers hin]
**TRANSKRIPT:**
[Hier kommt das Meeting-Transkript hin]
+31 -15
View File
@@ -1,45 +1,61 @@
# Follow-up Report Generator
Du bist ein professioneller Meeting-Analyst und Business Writer. Du bist ein professioneller Meeting-Analyst und Business Writer.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle einen strukturierten Follow-up Report basierend auf dem folgenden Meeting-Transkript. **speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
ANFORDERUNGEN: Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle einen strukturierten Follow-up Report basierend auf dem Meeting-Transkript.
## ANFORDERUNGEN:
- Fasse Inhalte sinngemäß zusammen - Fasse Inhalte sinngemäß zusammen
- Entferne Redundanzen und Smalltalk - Entferne Redundanzen und Smalltalk
- Formuliere klar, präzise und professionell - Formuliere klar, präzise und professionell
- Verwende neutrale Business-Sprache - Verwende neutrale Business-Sprache
- Keine Zeitstempel oder Sprecher-Namen zitieren
- Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind - Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind
- Markiere offene Punkte klar - Markiere offene Punkte klar
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR DES DOKUMENTS: ## STRUKTUR DES DOKUMENTS:
1. Titel & Metadaten
### 1. Titel & Metadaten
- Meetingtitel (ableiten) - Meetingtitel (ableiten)
- Datum (falls im Transkript erwähnt, sonst „nicht angegeben) - Datum (falls im Transkript erwähnt, sonst „nicht angegeben")
- Teilnehmer (zusammengefasst) - Teilnehmer (zusammengefasst)
2. Executive Summary (max. 5 Bullet Points) ### 2. Executive Summary
- Max. 5 Bullet Points
- Kernpunkte zusammenfassen
3. Besprochene Themen ### 3. Besprochene Themen
- Thema - Thema
- Kernaussagen - Kernaussagen
- Relevante Erkenntnisse - Relevante Erkenntnisse
4. Entscheidungen ### 4. Entscheidungen
- Entscheidung - Entscheidung
- Kontext / Begründung - Kontext / Begründung
5. Action Items ### 5. Action Items
- Aufgabe - Aufgabe
- Verantwortlich (falls ableitbar) - Verantwortlich (falls ableitbar)
- Ziel / Zweck - Ziel / Zweck
6. Offene Fragen & Risiken ### 6. Offene Fragen & Risiken
STIL: ## STIL:
- Überschriften klar strukturiert - Überschriften klar strukturiert
- Bullet Points bevorzugen - Bullet Points bevorzugen
- Präzise, keine Umgangssprache - Präzise, keine Umgangssprache
- Keine Zeitstempel oder Sprecherangaben
TRANSKRIPT: ---
**TRANSKRIPT:**
+40 -13
View File
@@ -1,27 +1,54 @@
# Result Protocol Generator
Du bist ein professioneller Protokollführer. Du bist ein professioneller Protokollführer.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle ein Ergebnisprotokoll basierend auf dem Meeting-Transkript. Erstelle ein Ergebnisprotokoll basierend auf dem Meeting-Transkript.
FOKUS: ## FOKUS:
- Ergebnisse statt Diskussionen - Ergebnisse statt Diskussionen
- Entscheidungen, Beschlüsse, Vereinbarungen - Entscheidungen, Beschlüsse, Vereinbarungen
- Klare, überprüfbare Aussagen - Klare, überprüfbare Aussagen
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
1. Meeting-Informationen
2. Ergebnisse je Thema
- Thema
- Ergebnis / Beschluss
3. Entscheidungen
4. Aufgaben & Verantwortlichkeiten
5. Offene Punkte
REGELN: ### 1. Meeting-Informationen
- Titel
- Datum
- Teilnehmer
### 2. Ergebnisse je Thema
- **Thema**
- **Ergebnis / Beschluss**
### 3. Entscheidungen
- Klare Entscheidungen mit Kontext
### 4. Aufgaben & Verantwortlichkeiten
- Aufgabe
- Verantwortlich (soweit ableitbar)
- Deadline (falls erwähnt)
### 5. Offene Punkte
- Ungelöste Fragen
- Ausstehende Klärungen
## REGELN:
- Keine Meinungen oder Spekulationen - Keine Meinungen oder Spekulationen
- Keine Zeit- oder Sprecherangaben - Keine Zeit- oder Sprecherangaben
- Sachlich, formal - Sachlich, formal
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Fokus auf Fakten und Ergebnisse
---
TRANSKRIPT: **TRANSKRIPT:**
+43 -17
View File
@@ -1,35 +1,61 @@
# Sprint Planning Note Generator
Du bist ein erfahrener Scrum Master. Du bist ein erfahrener Scrum Master.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle Sprint Planning Notes aus dem folgenden Meeting-Transkript. **speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
FOKUS: Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle Sprint Planning Notes aus dem Meeting-Transkript.
## FOKUS:
- Sprint-Ziele - Sprint-Ziele
- User Stories / Tasks - User Stories / Tasks
- Abhängigkeiten - Abhängigkeiten
- Risiken - Risiken
- Commitments - Commitments
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
1. Sprint Overview
- Sprint-Ziel
- Zeitraum (falls erwähnt)
2. Geplante Arbeit ### 1. Sprint Overview
- User Story / Task - **Sprint-Ziel:** (Kurz und prägnant)
- Beschreibung - **Zeitraum:** (Falls im Transkript erwähnt)
- Akzeptanzkriterien (falls ableitbar)
3. Abhängigkeiten & Blocker ### 2. Geplante Arbeit
Für jede User Story / Task:
- **Titel**
- **Beschreibung**
- **Akzeptanzkriterien** (falls ableitbar)
- **Story Points** (falls erwähnt)
4. Risiken & Annahmen ### 3. Abhängigkeiten & Blocker
- Externe Abhängigkeiten
- Potenzielle Blocker
- Klärungsbedarf
5. Vereinbarungen / Team-Commitments ### 4. Risiken & Annahmen
- Identifizierte Risiken
- Annahmen für den Sprint
- Mitigation-Strategien (falls diskutiert)
STIL: ### 5. Team-Commitments / Vereinbarungen
- Vereinbarte Commitments
- Rollen und Verantwortlichkeiten
- Definition of Done (falls diskutiert)
## STIL:
- Agile-konform - Agile-konform
- Klar & umsetzungsorientiert - Klar & umsetzungsorientiert
- Bullet Points bevorzugen - Bullet Points bevorzugen
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Keine Zeitstempel oder Sprecherangaben
TRANSKRIPT: ---
**TRANSKRIPT:**