Files
Orchestrator/bahn/teamlandkarte-mcp/.kiro/specs/team-profile-matching/requirements.md
T
ankn a5f8fb49ab Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
2026-06-30 20:39:52 +02:00

232 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Anforderungsdokument
## Einleitung
Dieses Dokument beschreibt die Anforderungen für ein neues Feature der Teamlandkarte: das **Matching gegen Team-Profile** als zusätzliche Profilart neben den bestehenden Kapazitätsprofilen. Bisher vergleicht das System eine offene Aufgabe ausschließlich mit Kapazitätsprofilen einzelner Mitarbeitender (`teamlandkarte_v_capacities_latest` und zugehörige Tabellen). Künftig soll der Nutzer pro Suchanfrage wählen können, ob eine Aufgabe gegen **Kapazitätsprofile** (bisheriges Verhalten) oder gegen **Team-Profile** (neue Profilart) gematcht wird.
Ein Team-Profil aggregiert Daten aus mehreren Datenbank-Views: Stammdaten und Beschreibung aus `teamlandkarte_v_teams_latest` (Spalten `about_us`, `offerings`, `interests`, `focus_name`), den Teamnamen über INNER JOIN mit `teamlandkarte_v_teammeter_organizational_units_latest` (Join `team_id = id`), Team-Kompetenzen aus `teamlandkarte_v_teammeter_team_competences_latest` (Join über `ouid`, mit Top-Kompetenz-Markierung über `top_competency`) sowie Team-Referenzen aus `teamlandkarte_v_team_references_latest` (Join über `ouid`, Partner-Auflösung über `teamlandkarte_v_partners_latest.id` via `partner_id`, plus Projektbeschreibung in `projects`).
Das neue Feature soll die bestehenden Matching-Verfahren (`score` und `llm_fulltext`) wiederverwenden, sodass der Nutzer beide Verfahren auch auf Team-Profile anwenden kann. MCP-Tools, Agenten-Konfigurationen, Architekturdokumentation und README werden entsprechend erweitert.
## Glossar
- **MCP_Server**: Der Teamlandkarte MCP-Server (Modul `mcp_server.py`), der die MCP-Tools für Matching, Suche und Datenanzeige bereitstellt.
- **DBClient**: Protokollklasse aus `database/types.py`, die alle Datenbankzugriffe abstrahiert.
- **TrinoClient**: Konkrete `DBClient`-Implementierung (`database/trino_client.py`) für Trino/Presto.
- **Matcher**: Bestehende, Score-basierte Matching-Komponente in `matching/matcher.py`.
- **LLM_Fulltext_Matcher**: Bestehendes Modul für den LLM-basierten Volltext-Vergleich (`matching/llm_fulltext_matcher.py`).
- **AzureOpenAIClient**: Wrapper für Azure-OpenAI-Aufrufe in `azure/openai_client.py`.
- **LLM**: Large Language Model (Azure OpenAI Chat Completion).
- **Capacity**: Frozen Dataclass `Capacity` in `models.py` (Kapazitätseintrag eines Mitarbeitenden).
- **Team**: Neue Frozen Dataclass, die ein Team mit aggregierten Profilfeldern (Name, `about_us`, `offerings`, `interests`, `focus_name`, Kompetenzen, Referenzen) repräsentiert.
- **Team_Id**: Wert der Spalte `team_id` in `teamlandkarte_v_teams_latest` bzw. der Spalte `id` in `teamlandkarte_v_teammeter_organizational_units_latest`. Eindeutiger fachlicher Identifikator eines Teams.
- **Ouid**: Wert der Spalte `ouid`, die in `teamlandkarte_v_teams_latest`, `teamlandkarte_v_teammeter_team_competences_latest` und `teamlandkarte_v_team_references_latest` vorkommt und als Join-Schlüssel zwischen Stammdaten, Kompetenzen und Referenzen eines Teams dient.
- **Team_Name**: Wert der Spalte mit dem Teamnamen aus `teamlandkarte_v_teammeter_organizational_units_latest`, ermittelt über INNER JOIN mit `teamlandkarte_v_teams_latest` (`team_id = id`).
- **Team_About_Us**: Wert der Spalte `about_us` aus `teamlandkarte_v_teams_latest` (Beschreibung des Teams).
- **Team_Offerings**: Wert der Spalte `offerings` aus `teamlandkarte_v_teams_latest` (Leistungen des Teams).
- **Team_Interests**: Wert der Spalte `interests` aus `teamlandkarte_v_teams_latest` (Interessen des Teams).
- **Team_Focus_Name**: Wert der Spalte `focus_name` aus `teamlandkarte_v_teams_latest` (Schwerpunkt des Teams).
- **Team_Competence**: Eintrag aus `teamlandkarte_v_teammeter_team_competences_latest` mit den Feldern `competence_id` (Fremdschlüssel auf den Kompetenz-Namen analog zu Kapazitätskompetenzen) und `top_competency` (Boolean). Ein Team kann mehrere Team_Competence-Einträge haben (1:n über `ouid`).
- **Top_Competency**: Boolean-Spalte `top_competency` aus `teamlandkarte_v_teammeter_team_competences_latest`, die kennzeichnet, ob eine Team_Competence eine Top-Kompetenz des Teams ist.
- **Team_Reference**: Eintrag aus `teamlandkarte_v_team_references_latest` mit den Feldern `partner_id` (Fremdschlüssel auf `teamlandkarte_v_partners_latest.id`) und `projects` (Projektbeschreibung). Ein Team kann mehrere Team_Reference-Einträge haben (1:n über `ouid`).
- **Partner**: Eintrag aus `teamlandkarte_v_partners_latest`. Eine Team_Reference verweist über die Spalte `partner_id` auf einen Partner; die Verknüpfung erfolgt über `teamlandkarte_v_team_references_latest.partner_id = teamlandkarte_v_partners_latest.id`.
- **Partner_Name**: Wert der Spalte `name` aus `teamlandkarte_v_partners_latest`, der einer Team_Reference über `partner_id` zugeordnet ist. Ist `partner_id` `NULL` oder existiert kein passender Partner, gilt der Partner_Name als leere Zeichenkette.
- **Team_Profile**: Aggregiertes Volltext-Profil eines Teams, bestehend aus `Team_Id`, `Team_Name`, `Team_Focus_Name`, `Team_About_Us`, `Team_Offerings`, `Team_Interests`, einer Liste von Kompetenznamen mit Top-Markierung sowie einer Liste von Referenzeinträgen (Partner_Name + Projektbeschreibung).
- **Capacity_Profile**: Bestehendes aggregiertes Volltext-Profil einer Kapazität (Rolle, Kompetenzen, Beschreibung, Referenzen, Zertifikate).
- **Task_Profile**: Bestehendes aggregiertes Volltext-Profil einer Aufgabe (Titel, Beschreibung, gesuchte Kompetenzen).
- **Profile_Type**: Auswahlwert für die zu matchende Profilart. Erlaubte Werte: `capacity` (Kapazitätsprofile, bisheriges Verhalten) und `team` (Team-Profile, neu).
- **Matching_Method**: Bestehender Auswahlwert für das Verfahren. Erlaubte Werte: `score` und `llm_fulltext`.
- **Kategorie**: Eine der Ergebniskategorien `Top`, `Good`, `Partial`, `Low`, `Irrelevant`.
- **Rationale**: Vom LLM erzeugte Kurzbegründung (12 Sätze) für die zugewiesene Kategorie (nur im `llm_fulltext`-Modus).
- **find_matching_capacities**: MCP-Tool für die Suchrichtung Aufgabe→Kapazität (bestehend).
- **find_matching_teams**: Neues MCP-Tool für die Suchrichtung Aufgabe→Team.
- **SearchCache**: Bestehende Cache-Komponente für persistierte Suchergebnisse.
- **Teamlandkarte_Agent**: GitHub-Copilot-Agent in `.github/agents/teamlandkarte_agent.md` und Kiro-Pendant in `.kiro/agents/teamlandkarte.md`.
- **Architecture_Doc**: `docs/architecture.md`.
- **Readme**: `README.md` im Repository-Root.
## Anforderungen
### Anforderung 1: Auswahl des Profil-Typs für das Matching
**User Story:** Als Nutzer möchte ich beim Matching für eine offene Aufgabe entscheiden können, ob ich gegen Kapazitätsprofile oder gegen Team-Profile matche, damit ich je nach Fragestellung Personen oder Teams als Vorschläge erhalte.
#### Akzeptanzkriterien
1. THE MCP_Server SHALL einen Profile_Type mit den erlaubten Werten `capacity` und `team` definieren.
2. WHEN der Nutzer eine Aufgabe gegen Kapazitätsprofile matchen möchte, THE MCP_Server SHALL das bestehende Tool `find_matching_capacities` mit unverändertem Verhalten bereitstellen (Profile_Type implizit `capacity`).
3. WHEN der Nutzer eine Aufgabe gegen Team-Profile matchen möchte, THE MCP_Server SHALL ein neues Tool `find_matching_teams` bereitstellen, das Profile_Type `team` realisiert.
4. THE MCP_Server SHALL den verwendeten Profile_Type (`capacity` oder `team`) im Antwort-`META`-JSON sowie in der angezeigten Suchkonfiguration ausweisen.
5. THE MCP_Server SHALL den Parameter `matching_method` (`score` oder `llm_fulltext`) auch im Tool `find_matching_teams` akzeptieren und mit den gleichen Default- und Validierungsregeln behandeln wie in `find_matching_capacities`.
6. IF der Nutzer in `find_matching_teams` einen ungültigen Wert für `matching_method` übergibt, THEN THE MCP_Server SHALL eine Fehlermeldung zurückgeben, die die erlaubten Werte (`score`, `llm_fulltext`) auflistet, und die Suche nicht ausführen.
### Anforderung 2: Datenabfrage für Team-Stammdaten und Teamname
**User Story:** Als Entwickler möchte ich, dass das System Team-Stammdaten inklusive Teamnamen aus der Datenbank lädt, damit Team-Profile vollständig aufgebaut werden können.
#### Akzeptanzkriterien
1. THE DBClient SHALL eine Methode bereitstellen, die alle aktiven Teams aus `teamlandkarte_v_teams_latest` zurückgibt, inklusive der Spalten `team_id`, `ouid`, `about_us`, `offerings`, `interests` und `focus_name`.
2. THE DBClient SHALL den Team_Name pro Team über INNER JOIN von `teamlandkarte_v_teams_latest` mit `teamlandkarte_v_teammeter_organizational_units_latest` über die Bedingung `teamlandkarte_v_teams_latest.team_id = teamlandkarte_v_teammeter_organizational_units_latest.id` ermitteln.
3. WHEN für ein Team kein passender Eintrag in `teamlandkarte_v_teammeter_organizational_units_latest` existiert, THE DBClient SHALL dieses Team durch den INNER JOIN aus dem Ergebnis ausschließen.
4. WHEN eine der Spalten `about_us`, `offerings`, `interests` oder `focus_name` `NULL` oder leer ist, THE DBClient SHALL für das jeweilige Feld eine leere Zeichenkette zurückgeben.
5. THE DBClient SHALL eine Methode bereitstellen, die ein einzelnes Team anhand seiner Team_Id (oder Ouid) zurückgibt, einschließlich Team_Name über denselben INNER JOIN.
6. THE TrinoClient SHALL alle neuen SQL-Abfragen ausschließlich als `SELECT`-Statements ausführen und die bestehende Read-Only-Guard `_ensure_select_only` verwenden.
7. THE TrinoClient SHALL die neuen Abfragen über die bestehende Connection-Pool-Infrastruktur und die Retry-Logik (`_retry`) ausführen.
### Anforderung 3: Datenabfrage für Team-Kompetenzen
**User Story:** Als Entwickler möchte ich, dass das System die Kompetenzen eines Teams inklusive Top-Kompetenz-Markierung und aufgelöstem Kompetenz-Namen lädt, damit Team-Profile die fachlichen Fähigkeiten korrekt abbilden.
#### Akzeptanzkriterien
1. THE DBClient SHALL eine Methode bereitstellen, die für eine gegebene Ouid alle zugeordneten Team_Competence-Einträge aus `teamlandkarte_v_teammeter_team_competences_latest` zurückgibt, inklusive der Felder `competence_id` und `top_competency`.
2. THE DBClient SHALL den Kompetenz-Namen pro Team_Competence durch denselben Join-Mechanismus ermitteln, der bereits für Kapazitäts-Kompetenzen verwendet wird, sodass aus der `competence_id` der lesbare Kompetenz-Name abgeleitet wird.
3. THE DBClient SHALL eine Batch-Variante bereitstellen, die für eine Liste von Ouid-Werten alle zugehörigen Team_Competence-Einträge inklusive aufgelöster Kompetenz-Namen in höchstens einer SQL-Abfrage lädt.
4. WHEN ein Team keine Team_Competence-Einträge besitzt, THE DBClient SHALL eine leere Liste für dieses Team zurückgeben.
5. WHEN `top_competency` für einen Team_Competence-Eintrag `NULL` ist, THE DBClient SHALL den Wert als `false` interpretieren.
6. WHEN die `competence_id` eines Team_Competence-Eintrags zu keinem Kompetenz-Namen aufgelöst werden kann, THE DBClient SHALL diesen Eintrag aus dem Ergebnis ausschließen.
7. THE DBClient SHALL die Reihenfolge der Team_Competence-Einträge pro Team deterministisch zurückgeben (primär: Top-Kompetenzen vor Nicht-Top-Kompetenzen, sekundär: Kompetenz-Name aufsteigend).
### Anforderung 4: Datenabfrage für Team-Referenzen
**User Story:** Als Entwickler möchte ich, dass das System die Referenzen eines Teams inklusive Partner-Namen und Projektbeschreibung lädt, damit Team-Profile bisherige Projekte und Auftraggeber abbilden.
#### Akzeptanzkriterien
1. THE DBClient SHALL eine Methode bereitstellen, die für eine gegebene Ouid alle zugeordneten Team_Reference-Einträge aus `teamlandkarte_v_team_references_latest` zurückgibt, einschließlich der Spalte `projects` und des über `partner_id` aufgelösten Partner_Name.
2. THE DBClient SHALL den Partner_Name pro Team_Reference über LEFT JOIN auf `teamlandkarte_v_partners_latest` mit der Bedingung `teamlandkarte_v_team_references_latest.partner_id = teamlandkarte_v_partners_latest.id` ermitteln und die Spalte `name` als Partner_Name übernehmen.
3. THE DBClient SHALL eine Batch-Variante bereitstellen, die für eine Liste von Ouid-Werten alle zugehörigen Team_Reference-Einträge inklusive aufgelöster Partner_Name in höchstens einer SQL-Abfrage lädt; der Partner-Join SHALL Bestandteil derselben Referenz-Abfrage sein und keine zusätzliche SQL-Abfrage erzeugen.
4. WHEN ein Team keine Team_Reference-Einträge besitzt, THE DBClient SHALL eine leere Liste für dieses Team zurückgeben.
5. IF die `partner_id` einer Team_Reference `NULL` ist oder der Join auf `teamlandkarte_v_partners_latest` keinen Treffer liefert, THEN THE DBClient SHALL den Partner_Name dieser Team_Reference als leere Zeichenkette zurückgeben und die Referenz dennoch mit dem Feld `projects` in der Ergebnisliste belassen.
6. WHEN das Feld `projects` einer Team_Reference `NULL` oder ausschließlich Whitespace ist, THE DBClient SHALL diesen Eintrag aus dem Ergebnis ausschließen.
7. THE DBClient SHALL die Reihenfolge der Team_Reference-Einträge pro Team deterministisch zurückgeben (z. B. nach Partner_Name aufsteigend, dann nach Projektbeschreibung aufsteigend).
### Anforderung 5: Aufbau des Team_Profile
**User Story:** Als Entwickler möchte ich, dass das System aus den Datenbankfeldern ein konsistentes Volltext-Profil pro Team erzeugt, damit beide Matching-Verfahren eine einheitliche Eingabe erhalten.
#### Akzeptanzkriterien
1. THE MCP_Server SHALL pro Team ein Team_Profile bilden, das die folgenden Felder enthält: `team_id`, `ouid`, `team_name`, `focus_name`, `about_us`, `offerings`, `interests`, `competences` (Liste von Einträgen mit Kompetenz-Namen und `top_competency`-Flag) und `references` (Liste von Einträgen mit `partner_name` und `projects`).
2. WHEN ein Feld in der Datenbank leer oder `NULL` ist, THE MCP_Server SHALL das entsprechende Feld im Team_Profile mit einer leeren Zeichenkette bzw. einer leeren Liste belegen, ohne das gesamte Profil zu verwerfen.
3. WHEN der Partner_Name eines Team_Reference-Eintrags leer ist, THE MCP_Server SHALL die Referenz dennoch in `references` aufnehmen und ausschließlich das Feld `projects` in die serialisierte Darstellung übernehmen, ohne einen Platzhaltertext für den Partner einzufügen.
4. THE MCP_Server SHALL das Team_Profile in einer für das LLM lesbaren, deterministischen Textstruktur serialisieren, in der jedes Feld klar mit einer Überschrift gekennzeichnet ist (z. B. `Teamname:`, `Schwerpunkt:`, `Über uns:`, `Leistungen:`, `Interessen:`, `Kompetenzen:`, `Referenzen:`).
5. THE MCP_Server SHALL Top-Kompetenzen in der serialisierten Darstellung erkennbar markieren (z. B. durch ein vorangestelltes Symbol oder das Suffix `(Top)`), sodass das LLM und der Nutzer Top-Kompetenzen von Nicht-Top-Kompetenzen unterscheiden können.
6. THE MCP_Server SHALL jeden Eintrag im Abschnitt `Referenzen:` so darstellen, dass sowohl Partner_Name als auch Projekte für das LLM sichtbar sind (z. B. im Format `Partner: <partner_name> Projekte: <projects>` oder als gleichwertige strukturierte Darstellung).
7. THE MCP_Server SHALL die Reihenfolge der Felder in der serialisierten Darstellung über alle Teams konstant halten, sodass die Eingabe für das LLM bzw. den Score-Matcher deterministisch ist.
### Anforderung 6: Score-basiertes Matching für Team-Profile
**User Story:** Als Nutzer möchte ich Team-Profile auch im Score-basierten Modus matchen können, damit ich Teams mit denselben numerischen Bewertungen wie Kapazitäten vergleichen kann.
#### Akzeptanzkriterien
1. WHEN `find_matching_teams` mit `matching_method = "score"` aufgerufen wird, THE MCP_Server SHALL das Score-basierte Matching auf Team-Profile anwenden und für jedes Team eine Competence Score, eine Role Score und eine Overall Score berechnen.
2. THE MCP_Server SHALL die Competence Score eines Teams aus den Team_Competence-Einträgen berechnen, wobei die Liste der Kompetenz-Namen analog zur Liste der Kapazitäts-Kompetenzen verwendet wird.
3. THE MCP_Server SHALL die Role Score eines Teams aus dem Team_Focus_Name als Stellvertreter für die Rolle berechnen, da Teams keine Rolle im Sinne einer Kapazität besitzen.
4. WHERE Top-Kompetenzen vorhanden sind, THE MCP_Server SHALL Top-Kompetenzen bei der Berechnung der Competence Score höher gewichten als Nicht-Top-Kompetenzen, wobei der Gewichtungsfaktor in der Konfiguration unter dem Schlüssel `matching.team.top_competency_weight` mit Standardwert `1.5` einstellbar ist.
5. THE MCP_Server SHALL die Ergebnisse in dieselben Kategorien (`Top`, `Good`, `Partial`, `Low`, `Irrelevant`) einordnen, die auch für Kapazitätsprofile gelten.
6. THE MCP_Server SHALL die Ergebnistabelle für `find_matching_teams` im `score`-Modus mit den Spalten `Team Name`, `Schwerpunkt`, `Top-Kompetenzen`, `Role Score`, `Competence Score`, `Overall Score`, `Category` ausgeben.
7. THE MCP_Server SHALL die Verfügbarkeit eines Teams nicht prüfen, da Team-Profile keinen Verfügbarkeitszeitraum besitzen; ein etwaig übergebener Zeitraum SHALL ignoriert und in der `Applied Filters`-Tabelle als nicht wirksam markiert werden.
### Anforderung 7: LLM-Volltext-Matching für Team-Profile
**User Story:** Als Nutzer möchte ich Team-Profile auch im LLM-Volltext-Modus matchen können, damit der Vergleich auf Basis der Beschreibungstexte (about_us, offerings, interests) und Referenzen erfolgt.
#### Akzeptanzkriterien
1. WHEN `find_matching_teams` mit `matching_method = "llm_fulltext"` aufgerufen wird, THE LLM_Fulltext_Matcher SHALL für jedes Team einen LLM-Vergleich zwischen Task_Profile und Team_Profile durchführen.
2. THE LLM_Fulltext_Matcher SHALL pro Team genau eine Kategorie aus der Menge `Top`, `Good`, `Partial`, `Low`, `Irrelevant` zurückgeben.
3. THE LLM_Fulltext_Matcher SHALL pro Team eine Rationale mit 1 bis 2 Sätzen zurückgeben, die die Zuweisung in die jeweilige Kategorie erläutert.
4. THE LLM_Fulltext_Matcher SHALL die LLM-Antwort als strukturiertes JSON pro Team anfordern und parsen (Felder: `category`, `rationale`).
5. IF das LLM für ein Team eine Kategorie zurückgibt, die nicht in der erlaubten Menge liegt, THEN THE LLM_Fulltext_Matcher SHALL dieses Team der Kategorie `Irrelevant` zuordnen und die Rationale durch einen Hinweis auf die ungültige LLM-Antwort ergänzen.
6. IF der LLM-Aufruf für ein Team fehlschlägt, THEN THE LLM_Fulltext_Matcher SHALL dieses Team in einer separaten Fehlerliste ausweisen und es nicht als reguläres Ergebnis kategorisieren.
7. THE LLM_Fulltext_Matcher SHALL die Ergebnisse nach Kategorie gruppieren und innerhalb jeder Kategorie eine deterministische Sortierreihenfolge anwenden (Sortierung primär nach Kategorie, sekundär nach `team_id` aufsteigend).
8. WHEN `matching_method = "llm_fulltext"` verwendet wird, THE MCP_Server SHALL die Ergebnistabelle für `find_matching_teams` mit den Spalten `Team Name`, `Schwerpunkt`, `Top-Kompetenzen`, `Category`, `Begründung` ausgeben.
### Anforderung 8: Persistenz und Pagination der Team-Suche
**User Story:** Als Nutzer möchte ich auch bei einer Team-Suche durch Kategorien blättern und Filter anwenden können, damit der bestehende Such-Workflow konsistent bleibt.
#### Akzeptanzkriterien
1. WHEN `find_matching_teams` ein Suchergebnis erzeugt, THE MCP_Server SHALL ein gültiges `search_id` zurückgeben, das mit `get_results_by_category` und `filter_search_results` verwendet werden kann.
2. THE MCP_Server SHALL im persistierten Suchergebnis (`SearchCache`) ein Feld `search_type` mit dem Wert `team_search` hinterlegen, um Team-Suchen von Kapazitäts-Suchen (`capacity_search`) zu unterscheiden.
3. THE MCP_Server SHALL im `META`-JSON des Suchergebnisses sowohl `search_type = "team_search"` als auch das verwendete `matching_method` ausweisen, damit Folgewerkzeuge das Schema korrekt interpretieren können.
4. WHEN `get_results_by_category` ein Team-Suchergebnis paginiert, THE MCP_Server SHALL die Ergebnistabelle mit den für Teams definierten Spalten (`Team Name`, `Schwerpunkt`, `Top-Kompetenzen`, ...) ausgeben.
5. WHEN `filter_search_results` ein Team-Suchergebnis filtert, THE MCP_Server SHALL die Filterung auf für Teams sinnvolle Filter beschränken (Schwerpunkt-Filter, Kompetenz-Filter, Top-Kompetenz-Filter).
6. IF ein für Teams nicht anwendbarer Filter (z. B. `availability_date_start`, `availability_date_end`, `is_fully_available`) auf ein Team-Suchergebnis angewendet wird, THEN THE MCP_Server SHALL den Filter ignorieren und in der `Applied Filters`-Tabelle einen Hinweis aufnehmen, dass der Filter im Team-Suchmodus nicht wirksam ist.
### Anforderung 9: Detail- und Listen-Tools für Teams
**User Story:** Als Nutzer möchte ich einzelne Teams einsehen und eine Liste verfügbarer Teams abrufen können, damit ich Teams unabhängig von einem Matching-Lauf erkunden kann.
#### Akzeptanzkriterien
1. THE MCP_Server SHALL ein Tool `list_teams` bereitstellen, das die ersten `limit` Teams (Default 20) als Markdown-Tabelle mit den Spalten `Team Id`, `Team Name`, `Schwerpunkt`, `Anzahl Kompetenzen`, `Anzahl Referenzen` ausgibt.
2. THE MCP_Server SHALL ein Tool `get_team_details` bereitstellen, das anhand einer Team_Id ein einzelnes Team_Profile als Markdown-Tabelle plus Beschreibungstexte (`Über uns`, `Leistungen`, `Interessen`) und Listen (`Kompetenzen` mit Top-Markierung, `Referenzen` mit Partner_Name und Projektbeschreibung) ausgibt.
3. IF kein Team mit der angegebenen Team_Id existiert, THEN THE MCP_Server SHALL eine Fehlermeldung zurückgeben, die die ungültige Team_Id nennt.
4. THE MCP_Server SHALL die Listen `Kompetenzen` und `Referenzen` in der gleichen deterministischen Reihenfolge ausgeben, die der DBClient liefert (siehe Anforderungen 3.7 und 4.7).
### Anforderung 10: Anpassung der Agenten-Konfigurationen
**User Story:** Als Nutzer möchte ich, dass sowohl der GitHub-Copilot-Agent `teamlandkarte_agent` als auch der Kiro-Pendant-Agent das neue Matching gegen Team-Profile kennen und mich aktiv nach der gewünschten Profilart fragen, damit das neue Feature über die Agenten nutzbar ist.
#### Akzeptanzkriterien
1. THE Teamlandkarte_Agent SHALL in seiner Konfigurationsdatei (`.github/agents/teamlandkarte_agent.md`) und im Pendant `.kiro/agents/teamlandkarte.md` die Existenz und den Zweck der beiden Profile_Type-Werte `capacity` und `team` dokumentieren.
2. WHEN der Nutzer eine Suche nach passenden Profilen für eine Aufgabe startet, THE Teamlandkarte_Agent SHALL den Nutzer explizit nach dem gewünschten Profile_Type (`capacity` oder `team`) fragen, sofern dieser nicht bereits aus dem Verlauf hervorgeht.
3. THE Teamlandkarte_Agent SHALL die Skills/Workflows so erweitern, dass `find_matching_teams` als alternatives Such-Tool zu `find_matching_capacities` verfügbar ist und mit dem Parameter `matching_method` aufgerufen wird.
4. THE Teamlandkarte_Agent SHALL den Nutzer darauf hinweisen, dass bei einer Team-Suche keine Verfügbarkeitsfilter wirksam sind und die Ergebnisspalten von einer Kapazitäts-Suche abweichen.
5. THE Teamlandkarte_Agent SHALL den bestehenden Bestätigungs-Workflow (`show_pending_requirements`, `confirm_requirements`) beibehalten und für beide Profile_Type-Werte gleich anwenden.
6. THE Teamlandkarte_Agent SHALL die neuen Detail- und Listen-Tools (`list_teams`, `get_team_details`) in den Skills/Workflows erwähnen.
### Anforderung 11: Aktualisierung von Architektur- und README-Dokumentation
**User Story:** Als Entwickler oder Onboardee möchte ich, dass `architecture.md` und `README.md` das Matching gegen Team-Profile beschreiben, damit ich Architektur und Nutzung des Systems korrekt verstehe.
#### Akzeptanzkriterien
1. THE Architecture_Doc SHALL einen Abschnitt enthalten, der das Team_Profile als zusätzliche Profilart beschreibt, einschließlich seiner Felder, Datenquellen und der Verknüpfungen zwischen den Views.
2. THE Architecture_Doc SHALL die zusätzlichen Datenquellen (`teamlandkarte_v_teams_latest`, `teamlandkarte_v_teammeter_organizational_units_latest`, `teamlandkarte_v_teammeter_team_competences_latest`, `teamlandkarte_v_team_references_latest`) im Datenmodell- und Schema-Verifikationsabschnitt aufführen, einschließlich der relevanten Spalten.
3. THE Architecture_Doc SHALL die Verknüpfungen zwischen `teamlandkarte_v_teams_latest.team_id` und `teamlandkarte_v_teammeter_organizational_units_latest.id` (INNER JOIN für Team_Name) sowie über `ouid` zu Kompetenzen und Referenzen dokumentieren.
4. THE Architecture_Doc SHALL die Verknüpfung zwischen `teamlandkarte_v_team_references_latest.partner_id` und `teamlandkarte_v_partners_latest.id` sowie die Übernahme der Spalte `name` als Partner_Name in das Team_Profile dokumentieren.
5. THE Architecture_Doc SHALL den Profile_Type-Parameter und seine Wertebereiche im Tool-Surface-Abschnitt für die neuen und geänderten Tools dokumentieren.
6. THE Architecture_Doc SHALL den Runtime-View für die Suchrichtung Aufgabe→Team in beiden Matching-Methoden (`score` und `llm_fulltext`) ergänzen.
7. THE Readme SHALL im Quick-Start- und Usage-Abschnitt erklären, wie der Nutzer zwischen `capacity`- und `team`-Suche wählt.
8. THE Readme SHALL die zusätzlichen Datenbank-Views aufführen, die der Server für Team-Profile liest, einschließlich der Join-Bedingungen für Team_Name (über `team_id`/`id`), Kompetenzen und Referenzen (über `ouid`) sowie Partner (über `partner_id`).
9. THE Readme SHALL beschreiben, dass für Team-Suchen keine Verfügbarkeitsfilter angewendet werden und welche Ergebnisspalten in den jeweiligen Modi (`score`, `llm_fulltext`) ausgegeben werden.
### Anforderung 12: Konfiguration und Schema-Verifikation
**User Story:** Als Betreiber möchte ich, dass die neuen Datenbank-Views beim Start des Servers verifiziert werden und dass relevante Defaults konfigurierbar sind, damit Fehlkonfigurationen früh erkannt werden.
#### Akzeptanzkriterien
1. THE MCP_Server SHALL beim Start die Existenz der Spalten `team_id`, `ouid`, `about_us`, `offerings`, `interests`, `focus_name` in `teamlandkarte_v_teams_latest` über die Schema-Verifikation prüfen.
2. THE MCP_Server SHALL beim Start die Existenz der Spalte `id` (sowie der Spalte für den Teamnamen) in `teamlandkarte_v_teammeter_organizational_units_latest` über die Schema-Verifikation prüfen.
3. THE MCP_Server SHALL beim Start die Existenz der Spalten `ouid`, `competence_id`, `top_competency` in `teamlandkarte_v_teammeter_team_competences_latest` über die Schema-Verifikation prüfen.
4. THE MCP_Server SHALL beim Start die Existenz der Spalten `ouid`, `partner_id`, `projects` in `teamlandkarte_v_team_references_latest` über die Schema-Verifikation prüfen.
5. THE MCP_Server SHALL die Konfigurationsdatei `config.toml` um einen optionalen Schlüssel `matching.team.top_competency_weight` (Default `1.5`) erweitern, der die Gewichtung von Top-Kompetenzen im Score-Matching steuert.
6. IF `matching.team.top_competency_weight` einen nicht-numerischen Wert oder einen Wert kleiner als `1.0` enthält, THEN THE MCP_Server SHALL beim Start einen `ConfigError` mit beschreibender Meldung werfen.
7. THE MCP_Server SHALL alle bestehenden Tests so erweitern oder ergänzen, dass sowohl die Profile_Type-Werte `capacity` als auch `team` (mit beiden Matching-Methoden, gemocktem LLM und gemockter DB) abgedeckt sind.
### Anforderung 13: Round-Trip-Eigenschaft der Team-Profil-Serialisierung
**User Story:** Als Entwickler möchte ich sicherstellen, dass die deterministische Serialisierung eines Team_Profile stabil ist und sich semantisch identische Eingaben auf identische Ausgaben abbilden, damit die LLM-Eingabe reproduzierbar und cachebar ist.
#### Akzeptanzkriterien
1. FOR ALL Team-Profile mit identischen Feldwerten in identischer Reihenfolge, THE MCP_Server SHALL identische serialisierte Strings produzieren (Determinismus).
2. WHEN ein Team_Profile zweimal hintereinander aus identischen Datenbankzeilen aufgebaut und serialisiert wird, THE MCP_Server SHALL beide Male denselben Serialisierungsstring produzieren (Idempotenz der Profil-Bildung).
3. THE MCP_Server SHALL in der serialisierten Darstellung jedes Profilfeld mit einer eindeutigen, festen Überschrift versehen, sodass aus dem Serialisierungsstring die Zuordnung der Werte zu den Feldern eindeutig ablesbar ist.
4. THE MCP_Server SHALL die Reihenfolge der Listen-Elemente (`competences`, `references`) in der serialisierten Darstellung mit der vom DBClient gelieferten Reihenfolge übereinstimmen lassen, sodass keine Sortier-Diskrepanzen zwischen DB-Schicht und Serialisierungs-Schicht entstehen.