diff --git a/lib/api.js b/lib/api.js index 1a619b2..6525b4b 100644 --- a/lib/api.js +++ b/lib/api.js @@ -614,6 +614,8 @@ function createExternalApi(deps) { sanitizeInput(b.firma), sanitizeInput(b.stelle), sanitizeInput(b.ort || ''), + sanitizeInput(b.adresse || ''), + sanitizeInput(b.ansprechpartner || ''), sanitizeInput(b.gehalt || ''), sanitizeInput(b.beschreibung || ''), sanitizeInput(b.quelle_url || ''), @@ -642,7 +644,7 @@ function createExternalApi(deps) { if (existing) { await dbRun( - `UPDATE jobangebote SET firma = ?, stelle = ?, ort = ?, gehalt = ?, + `UPDATE jobangebote SET firma = ?, stelle = ?, ort = ?, adresse = ?, ansprechpartner = ?, gehalt = ?, beschreibung = ?, quelle_url = ?, art = ?, anzeige_datum = ?, kontakt_email = ?, status = ?, url_norm = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, [...fields, existing.id] @@ -653,8 +655,8 @@ function createExternalApi(deps) { const result = await dbRun( `INSERT INTO jobangebote - (external_id, quelle, firma, stelle, ort, gehalt, beschreibung, quelle_url, art, anzeige_datum, kontakt_email, status, url_norm) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + (external_id, quelle, firma, stelle, ort, adresse, ansprechpartner, gehalt, beschreibung, quelle_url, art, anzeige_datum, kontakt_email, status, url_norm) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [externalId, quelle, ...fields] ); const row = await dbGet('SELECT * FROM jobangebote WHERE id = ?', [result.lastID]); diff --git a/lib/openapi.js b/lib/openapi.js index 1992e2c..c638020 100644 --- a/lib/openapi.js +++ b/lib/openapi.js @@ -855,6 +855,8 @@ function buildOpenApiSpec(baseUrl = '') { firma: { type: 'string' }, stelle: { type: 'string' }, ort: { type: 'string', nullable: true }, + adresse: { type: 'string', nullable: true, description: 'Anschrift des Arbeitgebers (Straße, Hausnummer, PLZ, Ort)' }, + ansprechpartner: { type: 'string', nullable: true, description: 'Name des Ansprechpartners für die Bewerbung' }, gehalt: { type: 'string', nullable: true }, beschreibung: { type: 'string', nullable: true }, quelle_url: { type: 'string', nullable: true }, @@ -877,6 +879,8 @@ function buildOpenApiSpec(baseUrl = '') { firma: { type: 'string' }, stelle: { type: 'string' }, ort: { type: 'string' }, + adresse: { type: 'string', description: 'Anschrift des Arbeitgebers (Straße, Hausnummer, PLZ, Ort)' }, + ansprechpartner: { type: 'string', description: 'Name des Ansprechpartners für die Bewerbung' }, gehalt: { type: 'string' }, beschreibung: { type: 'string', description: 'Stellenbeschreibungstext' }, quelle_url: { type: 'string' }, diff --git a/server.js b/server.js index 1bafe84..f847df4 100644 --- a/server.js +++ b/server.js @@ -640,6 +640,8 @@ function initializeDatabase() { firma TEXT NOT NULL, stelle TEXT NOT NULL, ort TEXT, + adresse TEXT, + ansprechpartner TEXT, gehalt TEXT, beschreibung TEXT, quelle_url TEXT, @@ -657,6 +659,8 @@ function initializeDatabase() { // Migration: add columns to pre-existing jobangebote tables. db.run('ALTER TABLE jobangebote ADD COLUMN anzeige_datum DATE', () => {}); db.run('ALTER TABLE jobangebote ADD COLUMN kontakt_email TEXT', () => {}); + db.run('ALTER TABLE jobangebote ADD COLUMN adresse TEXT', () => {}); + db.run('ALTER TABLE jobangebote ADD COLUMN ansprechpartner TEXT', () => {}); // Normalized URL for URL-based de-duplication of offers (see lib/blacklist). db.run('ALTER TABLE jobangebote ADD COLUMN url_norm TEXT', () => { // Backfill url_norm for rows ingested before this column existed. @@ -1726,11 +1730,23 @@ initializeDatabase().then(() => { angebot.quelle ? `Importiert via: ${angebot.quelle}` : null, ].filter(Boolean); + // Employer address (street, house number, city) and contact person go into + // the AI notes so the LLM can use them for the letter's Anschriftfeld and + // salutation. + let anschrift = (angebot.adresse || '').trim(); + if (angebot.ort && !anschrift.toLowerCase().includes(String(angebot.ort).toLowerCase())) { + anschrift = anschrift ? `${anschrift}, ${angebot.ort}` : String(angebot.ort); + } + const llmNotizen = [ + anschrift ? `Anschrift des Arbeitgebers: ${anschrift}` : null, + angebot.ansprechpartner ? `Ansprechpartner: ${angebot.ansprechpartner}` : null, + ].filter(Boolean).join('\n'); + const result = await dbRun( `INSERT INTO bewerbungen (datum, firma, stelle, art, status, notizen, ort, stellenbeschreibung, - quelle_url, email_empfaenger, generierung_status) - VALUES (?, ?, ?, ?, 'Entwurf', ?, ?, ?, ?, ?, 'nicht_gestartet')`, + quelle_url, email_empfaenger, llm_notizen, generierung_status) + VALUES (?, ?, ?, ?, 'Entwurf', ?, ?, ?, ?, ?, ?, 'nicht_gestartet')`, [ datum, sanitizeInput(angebot.firma), @@ -1741,6 +1757,7 @@ initializeDatabase().then(() => { angebot.beschreibung || '', angebot.quelle_url || '', angebot.kontakt_email || '', + llmNotizen, ] ); @@ -1799,7 +1816,7 @@ initializeDatabase().then(() => { const b = req.body || {}; const quelleUrl = sanitizeInput(b.quelle_url || ''); await dbRun( - `UPDATE jobangebote SET firma = ?, stelle = ?, ort = ?, gehalt = ?, + `UPDATE jobangebote SET firma = ?, stelle = ?, ort = ?, adresse = ?, ansprechpartner = ?, gehalt = ?, beschreibung = ?, kontakt_email = ?, quelle_url = ?, anzeige_datum = ?, url_norm = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, @@ -1807,6 +1824,8 @@ initializeDatabase().then(() => { sanitizeInput((b.firma || '').trim()) || angebot.firma, sanitizeInput((b.stelle || '').trim()) || angebot.stelle, sanitizeInput(b.ort || ''), + sanitizeInput(b.adresse || ''), + sanitizeInput(b.ansprechpartner || ''), sanitizeInput(b.gehalt || ''), sanitizeInput(b.beschreibung || ''), sanitizeInput(b.kontakt_email || ''), diff --git a/views/bewerbung.ejs b/views/bewerbung.ejs index 13c8e67..93102fc 100644 --- a/views/bewerbung.ejs +++ b/views/bewerbung.ejs @@ -360,7 +360,8 @@ Versand über <%= mailFrom %>. Empfängeradresse eingeben, Betreff und Text prüfen, Anhänge auswählen und senden.

-
+ <%= j.gehalt %><% } %>

<% } %> + <% if (j.adresse) { %> +

+ Anschrift: + <%= j.adresse %> +

+ <% } %> + <% if (j.ansprechpartner) { %> +

+ Ansprechpartner: + <%= j.ansprechpartner %> +

+ <% } %> <% if (j.anzeige_datum) { %>

Anzeige: @@ -179,6 +191,14 @@ Ort + +

<% } %> + <% if (j.adresse) { %> +

+ Anschrift: + <%= j.adresse %> +

+ <% } %> + <% if (j.ansprechpartner) { %> +

+ Ansprechpartner: + <%= j.ansprechpartner %> +

+ <% } %> <% if (j.quelle_url) { %>