feat(livia)!: Exposé-Funktion vollständig entfernt

Runde 8 hat Livia zur Research- & Market-Intelligence-Agentin gemacht. Die
Exposé-Erstellung war der Kern ihrer alten Rolle und fällt mit ihr weg — sie
wird nicht nachgeordnet weitergeführt. Ein zweiter Reiter hätte die Funktion
sichtbar gelassen und die neue Positionierung damit halbiert.

Entfernt: 23 Dateien (Arbeitsbereich, dreistufiger Assistent, Dossier mit elf
Bereichen, Provider, Services, Hooks, Feldkatalog, Mockdaten, deterministischer
Textbaustein) sowie `generateExposeText` aus `IAIService` und beiden
Implementierungen.

Livias Arbeitsplatz zeigt jetzt nur noch die Recherche-Leads — ohne
Reiterbalken, weil eine Leiste mit einem Eintrag eine Alternative behauptet,
die es nicht gibt. Ihr Personalblatt, die Bearbeitungsverlaufs-Einträge und die
Teamdokumentation sind auf die neue Rolle nachgezogen; die beiden
Beispielvorgänge zeigen jetzt eine Leaderzeugung und ein Review mit
widersprüchlichen Quellen statt Lagebeschrieb und Exposétext.

Bei Nora entfällt die Mehrfachauswahl in der Objektliste: sie diente allein der
Weiterleitung an die Exposé-Erstellung. Eine Auswahl ohne Ziel wäre ein
Bedienelement, das nichts auslöst. Die Matching-Darstellung selbst bleibt
unverändert.

Der Wiederaufbau ist in `archive/livia/` beschrieben; das Manifest hält jetzt
fest, welche seiner Annahmen eingetreten sind und welche nicht — Livia bleibt
im Team, nur die Funktion ist weg.

Geprüft: tsc 0 Fehler, eslint 0 Fehler/0 Warnungen, 423/423 Tests grün,
Produktionsbuild erfolgreich, Smoke-Test über sieben Seiten ohne
Laufzeitfehler, 12/12 Abnahmekriterien erfüllt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin SutterandClaude Opus 5 committed 2026-08-23 22:44:08 +02:00
1 parent f5451f649f
commit a219d3f2ec
33 files changed
+178 -2474

No files matched your search

-8
View File
@@ -1,8 +0,0 @@
import type { CreateExposeLeadInput, ExposeLead } from '../domain/exposeLead'
export interface IExposeLeadProvider {
getAll(): Promise<ExposeLead[]>
getById(id: string): Promise<ExposeLead | null>
create(input: CreateExposeLeadInput): Promise<ExposeLead>
archive(id: string): Promise<ExposeLead>
}
-9
View File
@@ -1,9 +0,0 @@
import type { ExposeDraft } from '../domain/expose'
export interface IExposeProvider {
/** Entwurf zu einem Lead und Objekt — null, solange keiner besteht. */
getDraft(leadId: string, propertyId: string): Promise<ExposeDraft | null>
save(draft: ExposeDraft): Promise<ExposeDraft>
/** Setzt den Erstellungszeitpunkt — trennt «gespeichert» von «erstellt». */
markGenerated(draftId: string): Promise<ExposeDraft>
}
-36
View File
@@ -1,36 +0,0 @@
import { mockExposeLeads } from '../mock-data/exposeLeads'
import type { ExposeLead } from '../domain/exposeLead'
import { ExposeLeadStatus } from '../domain/exposeLead'
import type { IExposeLeadProvider } from './IExposeLeadProvider'
let store: ExposeLead[] = [...mockExposeLeads]
let sequence = store.length
export const MockupExposeLeadProvider: IExposeLeadProvider = {
async getAll() {
return [...store]
},
async getById(id) {
return store.find(l => l.id === id) ?? null
},
async create(input) {
sequence += 1
const lead: ExposeLead = {
...input,
id: `lead-${String(sequence).padStart(3, '0')}`,
receivedAt: input.receivedAt ?? new Date().toISOString(),
status: input.status ?? ExposeLeadStatus.ACTIVE,
}
store = [lead, ...store]
return lead
},
async archive(id) {
const idx = store.findIndex(l => l.id === id)
if (idx === -1) throw new Error(`Lead ${id} nicht gefunden`)
store[idx] = { ...store[idx], status: ExposeLeadStatus.ARCHIVED }
return store[idx]
},
}
-37
View File
@@ -1,37 +0,0 @@
import type { ExposeDraft } from '../domain/expose'
import type { IExposeProvider } from './IExposeProvider'
/**
* Entwurfsablage der Demo — in-memory, wie alle Mockup-Provider.
*
* Der Schlüssel ist das Paar aus Lead und Objekt: derselbe Lead kann mehrere
* Objekte empfehlen, und jedes bekommt sein eigenes Exposé.
*/
const store = new Map<string, ExposeDraft>()
function key(leadId: string, propertyId: string): string {
return `${leadId}::${propertyId}`
}
export const MockupExposeProvider: IExposeProvider = {
async getDraft(leadId, propertyId) {
return store.get(key(leadId, propertyId)) ?? null
},
async save(draft) {
const saved: ExposeDraft = { ...draft, updatedAt: new Date().toISOString() }
store.set(key(draft.leadId, draft.propertyId), saved)
return saved
},
async markGenerated(draftId) {
for (const [k, d] of store) {
if (d.id === draftId) {
const updated: ExposeDraft = { ...d, generatedAt: new Date().toISOString() }
store.set(k, updated)
return updated
}
}
throw new Error(`Exposé-Entwurf ${draftId} nicht gefunden`)
},
}