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.
This commit is contained in:
@@ -0,0 +1,333 @@
|
||||
# Implementierungsplan: Team-Profil-Matching
|
||||
|
||||
## Übersicht
|
||||
|
||||
Convert the feature design into a series of prompts for a code-generation LLM that will implement each step with incremental progress. Make sure that each prompt builds on the previous prompts, and ends with wiring things together. There should be no hanging or orphaned code that isn't integrated into a previous step. Focus ONLY on tasks that involve writing, modifying, or testing code.
|
||||
|
||||
Die Implementierung erfolgt in **Python** (entsprechend des bestehenden Codestils
|
||||
des Repositorys). Property-Based Tests verwenden **Hypothesis**, parallel zu den
|
||||
existierenden `tests/test_*_pbt.py`-Modulen. Sub-Tasks mit `*` sind optional und
|
||||
werden nicht automatisch implementiert (gemäß Projekt-Konventionen). Jede der
|
||||
14 Korrektheits-Eigenschaften aus dem Designdokument wird in genau einem
|
||||
PBT-Sub-Task realisiert und ist mit `**Property N**` und der validierten
|
||||
Anforderung annotiert.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [x] 1. Datenmodelle und Konfiguration vorbereiten
|
||||
- [x] 1.1 `Team`, `TeamCompetence`, `TeamReference`, `ScoredTeam` in `src/teamlandkarte_mcp/models.py` ergänzen
|
||||
- Frozen Dataclasses mit den im Design festgelegten Feldern und Defaults (`field(default_factory=list)` für `competences`/`references`)
|
||||
- Typen-Hints und Docstrings analog zu `Capacity`/`ScoredCapacity`
|
||||
- _Requirements: 5.1, 6.1_
|
||||
|
||||
- [x] 1.2 `TeamMatchingConfig` und `MatchingConfig.team` in `src/teamlandkarte_mcp/config.py` ergänzen
|
||||
- Frozen Dataclass `TeamMatchingConfig` mit `top_competency_weight: float = 1.5`
|
||||
- Feld `team: TeamMatchingConfig` in `MatchingConfig` hinzufügen
|
||||
- Parser in `load_config` so erweitern, dass `[matching.team]` aus TOML gelesen wird
|
||||
- Validierung: nicht-numerischer Wert oder Wert < 1.0 → `ConfigError` mit Schlüsselname und fehlerhaftem Wert in der Meldung
|
||||
- Default-Wert `1.5` greift bei fehlendem Schlüssel
|
||||
- _Requirements: 12.5, 12.6_
|
||||
|
||||
- [x] 1.3 `config.toml.example` um `[matching.team]`-Block ergänzen
|
||||
- Kommentierter Abschnitt mit `top_competency_weight = 1.5`
|
||||
- Hinweis, dass der Wert numerisch und ≥ 1.0 sein muss
|
||||
- _Requirements: 12.5_
|
||||
|
||||
- [x] 1.4 PBT für Konfig-Validierung von `top_competency_weight`
|
||||
- **Property 13: Konfig-Validierung von `top_competency_weight`**
|
||||
- **Validates: Requirements 12.5, 12.6**
|
||||
- Hypothesis-Strategie: numerische Werte ≥ 1.0 (positiv), nicht-numerische und < 1.0 (negativ); fehlender Schlüssel → Default 1.5
|
||||
- Datei: `tests/test_team_config_top_weight_pbt.py`
|
||||
|
||||
- [x] 2. DBClient-Protokoll und SQL-Implementierung für Team-Daten
|
||||
- [x] 2.1 `DBClient`-Protokoll in `src/teamlandkarte_mcp/database/types.py` erweitern
|
||||
- Neue `TypedDict`s `TeamCompetenceRow` (`name`, `top_competency`) und `TeamReferenceRow` (`partner_name`, `projects`)
|
||||
- Methoden ergänzen: `get_all_teams`, `get_team_by_id`, `get_team_competences`, `batch_get_team_competences`, `get_team_references`, `batch_get_team_references`
|
||||
- Docstrings beschreiben Sortierung, NULL-Behandlung und INNER- vs. LEFT-JOIN-Semantik (siehe Design)
|
||||
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7_
|
||||
|
||||
- [x] 2.2 `TrinoClient.get_all_teams` und `get_team_by_id` in `src/teamlandkarte_mcp/database/trino_client.py` implementieren
|
||||
- SQL: INNER JOIN `teamlandkarte_v_teams_latest` mit `teamlandkarte_v_teammeter_organizational_units_latest` über `team_id = id`
|
||||
- `COALESCE(..., '')` für `about_us`, `offerings`, `interests`, `focus_name`
|
||||
- `ORDER BY ou.name ASC, t.team_id ASC`
|
||||
- `_ensure_select_only` und `_retry` verwenden, Connection-Pool über bestehenden `_cursor`-Context
|
||||
- `get_all_teams` ruft intern `batch_get_team_competences` und `batch_get_team_references` auf und aggregiert zu `Team`-Instanzen
|
||||
- `get_team_by_id` liefert `None`, wenn kein Treffer (auch durch INNER JOIN ausgefiltert)
|
||||
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7_
|
||||
|
||||
- [x] 2.3 `TrinoClient.get_team_competences` und `batch_get_team_competences` implementieren
|
||||
- SQL: Join auf `teamlandkarte_v_competences_latest` analog zum Capacity-Pfad zur Auflösung des Kompetenz-Namens
|
||||
- `COALESCE(top_competency, FALSE)` für NULL-Normalisierung
|
||||
- `ORDER BY tc.ouid ASC, CASE WHEN COALESCE(top_competency,FALSE) THEN 0 ELSE 1 END ASC, c.name ASC`
|
||||
- Batch-Variante in genau einer Query, `dict[str, list[TeamCompetenceRow]]` mit leeren Listen für OUIDs ohne Treffer
|
||||
- `_ensure_select_only` und `_retry` anwenden
|
||||
- _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 2.6, 2.7_
|
||||
|
||||
- [x] 2.4 `TrinoClient.get_team_references` und `batch_get_team_references` implementieren
|
||||
- SQL: LEFT JOIN auf `teamlandkarte_v_partners_latest` über `partner_id = id` als Teil derselben Query (kein zusätzlicher Roundtrip)
|
||||
- `COALESCE(p.name, '')` für `partner_name`
|
||||
- Whitespace-only `projects` werden nach dem Fetch in Python ausgefiltert
|
||||
- `ORDER BY r.ouid ASC, partner_name ASC, r.projects ASC`
|
||||
- Batch-Variante in genau einer Query, `dict[str, list[TeamReferenceRow]]` mit leeren Listen für OUIDs ohne Treffer
|
||||
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 2.6, 2.7_
|
||||
|
||||
- [x] 2.5 PBT für SELECT-Only-Eigenschaft aller neuen Trino-Queries
|
||||
- **Property 2: SELECT-Only-Eigenschaft aller neuen Trino-Queries**
|
||||
- **Validates: Requirements 2.6**
|
||||
- Stub-Cursor, der jede ausgeführte SQL durch `_ensure_select_only` validiert; Hypothesis-generierte Eingabe-Listen für die sechs neuen Methoden
|
||||
- Datei: `tests/test_team_trino_select_only_pbt.py`
|
||||
|
||||
- [x] 2.6 PBT für Stammdaten-Konsistenz und INNER-JOIN-Filter
|
||||
- **Property 3: Stammdaten-Konsistenz und INNER-JOIN-Filter**
|
||||
- **Validates: Requirements 2.1, 2.2, 2.3, 2.4, 2.5**
|
||||
- Hypothesis-Strategie: Listen aus Teams- und OU-Stub-Zeilen mit beliebigen NULL/Empty-Verteilungen; prüfen, dass NULL → "", INNER JOIN ohne Match → ausgeschlossen, `get_team_by_id` konsistent zu `get_all_teams`
|
||||
- Datei: `tests/test_team_master_data_pbt.py`
|
||||
|
||||
- [x] 2.7 PBT für Konsistenz von Einzel- und Batch-Variante der Kompetenzen
|
||||
- **Property 4: Kompetenz-Batch ist konsistent zur Einzel-Variante**
|
||||
- **Validates: Requirements 3.1, 3.3, 3.4, 3.5, 3.6, 3.7**
|
||||
- Hypothesis-Strategie: Mengen von OUIDs + zufällige Top/Name-Verteilungen + NULL für `top_competency`
|
||||
- Datei: `tests/test_team_competences_batch_pbt.py`
|
||||
|
||||
- [x] 2.8 PBT für Konsistenz von Einzel- und Batch-Variante der Referenzen
|
||||
- **Property 5: Referenz-Batch ist konsistent zur Einzel-Variante**
|
||||
- **Validates: Requirements 4.1, 4.3, 4.4, 4.5, 4.6, 4.7**
|
||||
- Hypothesis-Strategie: Referenzzeilen mit/ohne Partner und Whitespace-`projects`; prüfen, dass die Batch-Variante genau einen `cur.execute(...)`-Call gegen die References-View ausführt
|
||||
- Datei: `tests/test_team_references_batch_pbt.py`
|
||||
|
||||
- [x] 2.9 Unit-Tests für `TrinoClient`-Team-Queries (Snapshot)
|
||||
- SQL-String-Snapshot, dass INNER JOIN, `ORDER BY`, `COALESCE` und LEFT JOIN auf `partners` korrekt formuliert sind
|
||||
- Datei: `tests/test_trino_client_team_queries.py`
|
||||
- _Requirements: 2.1, 2.2, 3.1, 4.1, 4.2_
|
||||
|
||||
- [x] 3. Schema-Verifikation für die vier neuen Views
|
||||
- [x] 3.1 `schema_expected`-Map in `src/teamlandkarte_mcp/mcp_server.py` (`build_server`) erweitern
|
||||
- Einträge für `teamlandkarte_v_teams_latest`, `teamlandkarte_v_teammeter_organizational_units_latest`, `teamlandkarte_v_teammeter_team_competences_latest`, `teamlandkarte_v_team_references_latest`
|
||||
- Spalten gemäß Design (`team_id`, `ouid`, `about_us`, `offerings`, `interests`, `focus_name`; `id`, `name`; `ouid`, `competence_id`, `top_competency`; `ouid`, `partner_id`, `projects`)
|
||||
- Bestehender Pfad `verify_required_columns` wird unverändert verwendet
|
||||
- _Requirements: 12.1, 12.2, 12.3, 12.4_
|
||||
|
||||
- [x] 3.2 PBT für Schema-Verifikation der vier neuen Views
|
||||
- **Property 14: Schema-Verifikation deckt fehlende Spalten in den vier neuen Views auf**
|
||||
- **Validates: Requirements 12.1, 12.2, 12.3, 12.4**
|
||||
- Hypothesis-Strategie: Powerset der erwarteten Spalten pro View, jeweils minus eine zufällig gewählte Spalte → `SchemaIssue` mit Tabellenname und fehlender Spalte; vollständige Spaltenliste → kein Issue
|
||||
- Datei: `tests/test_team_schema_verification_pbt.py`
|
||||
|
||||
- [x] 4. Checkpoint - Datenzugriffsschicht
|
||||
- Sicherstellen, dass alle bisherigen Tests grün sind und der Server mit der erweiterten Schema-Verifikation startet. Bei Unklarheiten den Nutzer fragen.
|
||||
|
||||
- [x] 5. Profile-Erstellung und Serialisierung
|
||||
- [x] 5.1 `TeamCompetenceEntry`, `TeamReferenceEntry`, `TeamProfile` in `src/teamlandkarte_mcp/matching/profiles.py` ergänzen
|
||||
- Frozen Dataclasses mit den im Design definierten Feldern; Listenreihenfolgen entsprechen den Datenbank-Reihenfolgen
|
||||
- _Requirements: 5.1_
|
||||
|
||||
- [x] 5.2 `build_team_profile(team: Team) -> TeamProfile` implementieren
|
||||
- 1:1-Mapping von `Team`-Feldern auf `TeamProfile`; keine Re-Sortierung der Listen
|
||||
- NULL/Empty-Strings unverändert übernehmen (DB-Schicht hat bereits normalisiert)
|
||||
- _Requirements: 5.1, 5.2, 13.4_
|
||||
|
||||
- [x] 5.3 `serialize_team_profile(profile: TeamProfile) -> str` implementieren
|
||||
- Feste deutsche Überschriften: `Teamname:`, `Schwerpunkt:`, `Über uns:`, `Leistungen:`, `Interessen:`, `Kompetenzen:`, `Referenzen:` in genau dieser Reihenfolge
|
||||
- Top-Kompetenzen mit Suffix `(Top)` markieren
|
||||
- Referenz-Zeilen: `Partner: <partner_name> – Projekte: <projects>` bei vorhandenem Partner; bei leerem Partner nur `Projekte: <projects>` (kein Platzhalter)
|
||||
- Leere Listen als `Kompetenzen: (keine)` bzw. `Referenzen: (keine)` rendern
|
||||
- Reihenfolge der Listen-Elemente entspricht 1:1 der Eingabe
|
||||
- _Requirements: 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 13.1, 13.2, 13.3, 13.4_
|
||||
|
||||
- [x] 5.4 PBT für Determinismus und Vollständigkeit der Team-Profil-Serialisierung
|
||||
- **Property 6: Determinismus und Vollständigkeit der Team-Profil-Serialisierung**
|
||||
- **Validates: Requirements 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 13.1, 13.2, 13.3, 13.4**
|
||||
- Hypothesis-Strategie für `TeamProfile` analog zu `_capacity_profile` in `tests/test_profile_serialization_pbt.py`; prüft Determinismus, Idempotenz, Reihenfolge der Überschriften, `(Top)`-Marker, Partner-Optional-Verhalten und Listen-Reihenfolge
|
||||
- Datei: `tests/test_team_profile_serialization_pbt.py`
|
||||
|
||||
- [x] 5.5 Unit-Tests für `build_team_profile` und `serialize_team_profile`
|
||||
- Beispielbasiert: leere Strings, leere Listen, gemischte Top/Nicht-Top-Kompetenzen, Referenzen mit/ohne Partner_Name
|
||||
- Datei: `tests/test_team_profile_serialization_unit.py`
|
||||
- _Requirements: 5.1, 5.3, 5.4, 5.5, 5.6_
|
||||
|
||||
- [x] 6. Score-basiertes Matching für Team-Profile
|
||||
- [x] 6.1 `Matcher.match_teams` in `src/teamlandkarte_mcp/matching/matcher.py` implementieren
|
||||
- Signatur: `async def match_teams(self, teams, requirements, *, top_competency_weight) -> TeamMatchResult`
|
||||
- Kompetenz-Liste aus `team.competences` ableiten + paralleles Top-Set
|
||||
- `SimilarityEngine.compute_competence_similarity` analog zum Capacity-Pfad nutzen; pro Required-Kompetenz `weighted = min(1.0, raw_score * (top_weight if best_match in top_set else 1.0))`
|
||||
- Role Score über `SimilarityEngine.compute_role_similarity(req.role_name, team.focus_name)`
|
||||
- Overall Score über `compute_overall(...)` mit denselben Gewichten und Thresholds wie für Kapazitäten
|
||||
- Kategorisierung über `categorize(...)`
|
||||
- **Verfügbarkeitsprüfung wird nicht aufgerufen**; ein etwaiger Datumsbereich aus `req` wird ignoriert
|
||||
- Rückgabe: neues `TeamMatchResult` (`scored: list[ScoredTeam]`, `by_category: dict[str, list[ScoredTeam]]`)
|
||||
- `Matcher.summary_counts` so generalisieren, dass sowohl Capacity- als auch Team-Buckets unterstützt werden (strukturell `len`-basiert)
|
||||
- _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5, 6.7_
|
||||
|
||||
- [x] 6.2 PBT für Top-Kompetenz-Monotonie im Score-Matching
|
||||
- **Property 7: Top-Kompetenz-Monotonie im Score-Matching**
|
||||
- **Validates: Requirements 6.4**
|
||||
- Hypothesis-Strategie: Kompetenz-Listen + `top_weight ∈ [1.0, 5.0]`; vergleicht `T_top` (alle Top) mit `T_plain`; bei `top_weight == 1.0` exakt 0.0 Differenz
|
||||
- Datei: `tests/test_team_score_top_weight_pbt.py`
|
||||
|
||||
- [x] 6.3 PBT für Score-Pfad-Validität und Verfügbarkeits-Ignoranz
|
||||
- **Property 8: Score-Pfad liefert gültige Score- und Kategorie-Werte**
|
||||
- **Validates: Requirements 6.1, 6.2, 6.3, 6.5, 6.7**
|
||||
- Hypothesis-Strategie für `Team`-Listen + Stub-`SimilarityEngine`; prüft Score-Bereich `[0,1]`, Kategorie-Set, Konsistenz mit `categorize(...)` und Invarianz unter `req.date_start`/`req.date_end`
|
||||
- Datei: `tests/test_team_score_pipeline_pbt.py`
|
||||
|
||||
- [x] 7. LLM-Volltext-Matching für Team-Profile
|
||||
- [x] 7.1 `LlmFulltextMatcher.match_teams` in `src/teamlandkarte_mcp/matching/llm_fulltext_matcher.py` implementieren
|
||||
- Signatur parallel zu `match_capacities`/`match_tasks`, akzeptiert `task_profile: TaskProfile` und `teams: list[Team]`
|
||||
- Pro Team `build_team_profile + serialize_team_profile`; User-Prompt im Format `=== Aufgabe ===` + `=== Team ===` mit `ID:`-Header
|
||||
- System-Prompt: bestehender Capacity-Prompt mit minimaler Wortwahl-Anpassung (`Kapazitätsprofil` → `Profil`); JSON-Schema `{"category", "rationale"}` unverändert
|
||||
- Concurrency über bestehende `asyncio.Semaphore` (`max_concurrency`)
|
||||
- Fehlerbehandlung: `LlmFulltextError` für JSON-Parse-Fehler und `AzureAPIError`; ungültige Kategorien werden via `normalize_category` auf `Irrelevant` gemappt mit Hinweis-Suffix in der Rationale
|
||||
- Sortierung pro Kategorie: `(category_rank, item_id_asc)` mit `item_id = team_id`
|
||||
- Rückgabe: bestehender `LlmFulltextResult`-Typ (`by_category` + `errors`)
|
||||
- _Requirements: 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7_
|
||||
|
||||
- [x] 7.2 PBT für LLM-Pfad als vollständige Partition mit gültigen Kategorien
|
||||
- **Property 9: LLM-Pfad ist eine vollständige Partition mit gültigen Kategorien**
|
||||
- **Validates: Requirements 7.1, 7.2, 7.3, 7.6, 7.7**
|
||||
- Hypothesis-Strategie: `mask: list[bool]` analog zu `tests/test_batch_completeness_pbt.py` (`_MaskLlm`-Pattern); prüft Vollständigkeit, Eindeutigkeit, Sortierung, gültige Kategorien und nicht-leere Rationales bei Erfolg
|
||||
- Datei: `tests/test_team_llm_fulltext_partition_pbt.py`
|
||||
|
||||
- [x] 7.3 PBT für ungültige LLM-Kategorien (Irrelevant-Fallback)
|
||||
- **Property 10: Ungültige LLM-Kategorien fallen auf Irrelevant zurück**
|
||||
- **Validates: Requirements 7.5**
|
||||
- Hypothesis-Strategie: zufällige Strings (außerhalb der erlaubten Kategorien) + JSON-Wrapper; prüft `category == "Irrelevant"` und Hinweis-Substring in `rationale`
|
||||
- Datei: `tests/test_team_llm_invalid_category_pbt.py`
|
||||
|
||||
- [x] 8. Checkpoint - Matching-Pipelines
|
||||
- Sicherstellen, dass die Score- und LLM-Pfade isoliert lauffähig sind und alle Tests grün sind. Bei Unklarheiten den Nutzer fragen.
|
||||
|
||||
- [x] 9. MCP-Tools für Team-Suche und Team-Detailansicht
|
||||
- [x] 9.1 `_ALLOWED_PROFILE_TYPES` und `_get_teams_cached()` in `src/teamlandkarte_mcp/mcp_server.py` ergänzen
|
||||
- String-Konstante `_ALLOWED_PROFILE_TYPES = ("capacity", "team")`
|
||||
- Neuer `QueryCache[list[Team]]`-Eintrag (`all_teams`) parallel zum Capacity-Cache; ruft `db_client.get_all_teams()`
|
||||
- _Requirements: 1.1_
|
||||
|
||||
- [x] 9.2 Tool `find_matching_teams` registrieren
|
||||
- Signatur: `async def find_matching_teams(role_name: str, competences: list[str], matching_method: str = "") -> str`
|
||||
- `_resolve_matching_method` und `_validate_requirements_minimum` wiederverwenden; ungültiges `matching_method` → Fehlermeldung mit erlaubten Werten, **kein** DB-/LLM-Aufruf
|
||||
- Confirm-Gate über `_require_confirmed_or_auto(req)`
|
||||
- Score-Pfad: `matcher.match_teams(...)` mit `cfg.matching.team.top_competency_weight`
|
||||
- LLM-Pfad: `task_profile = build_task_profile_from_requirements(req)` → `llm_fulltext_matcher.match_teams(task_profile=task_profile, teams=teams)`
|
||||
- Persistenz im `SearchCache` mit `results_payload["search_type"] = "team_search"` und `matching_method`
|
||||
- Antwort: `SEARCH_ID=<uuid>` + `META=<json>` mit `search_type` und `matching_method` + Markdown-Tabellen (Summary + Top-Kategorie)
|
||||
- _Requirements: 1.3, 1.4, 1.5, 1.6, 6.1, 7.1, 8.1, 8.2, 8.3_
|
||||
|
||||
- [x] 9.3 Tool `list_teams(limit: int = 20) -> str` registrieren
|
||||
- Markdown-Tabelle mit Spalten `Team Id`, `Team Name`, `Schwerpunkt`, `Anzahl Kompetenzen`, `Anzahl Referenzen`
|
||||
- Empty-Fallback-Text wie bei `list_free_capacities`
|
||||
- _Requirements: 9.1_
|
||||
|
||||
- [x] 9.4 Tool `get_team_details(team_id: str) -> str` registrieren
|
||||
- Markdown-Tabelle für ein Team plus Sektionen `## Über uns`, `## Leistungen`, `## Interessen`, `## Kompetenzen` (mit `(Top)`-Marker), `## Referenzen` (Partner_Name fett gedruckt, sonst nur Projekte) und `## Next steps`
|
||||
- Wenn `db_client.get_team_by_id(team_id)` `None` liefert → `f"Team not found: {team_id}"`
|
||||
- Reihenfolge der Listen entspricht der DB-Reihenfolge
|
||||
- _Requirements: 9.2, 9.3, 9.4_
|
||||
|
||||
- [x] 9.5 `_coerce_team(item)` Helper implementieren
|
||||
- Rehydratisiert persistierte SearchCache-Einträge zurück in `Team`-Instanzen (analog zu `_coerce_capacity`)
|
||||
- Handhabt sowohl `Team`-Instanzen als auch verschachtelte `dict`-Repräsentationen (mit/ohne `team`-Wrapper)
|
||||
- _Requirements: 8.4_
|
||||
|
||||
- [x] 9.6 `_format_results_table` für `search_type="team_search"` erweitern
|
||||
- Spalten im `score`-Modus: `Team Name`, `Schwerpunkt`, `Top-Kompetenzen`, `Role Score`, `Competence Score`, `Overall Score`, `Category`
|
||||
- Spalten im `llm_fulltext`-Modus: `Team Name`, `Schwerpunkt`, `Top-Kompetenzen`, `Category`, `Begründung`
|
||||
- `Top-Kompetenzen` ist die kommaseparierte Liste aller `competences` mit `top_competency=True`
|
||||
- `Begründung` nutzt bestehenden `_format_rationale_for_table`-Helper
|
||||
- Sortierkey im LLM-Modus: `(category_rank, item.get("team_id") or "")`
|
||||
- _Requirements: 6.6, 7.8, 8.4_
|
||||
|
||||
- [x] 9.7 `filter_search_results` und `get_results_by_category` für `team_search` erweitern
|
||||
- `role_filter` matcht gegen `team.focus_name`
|
||||
- `competence_filter` matcht gegen `[c["name"] for c in item["competences"]]`; Filterwerte mit Suffix `(Top)` werden auf Top-Kompetenzen beschränkt (Suffix wird vor Vergleich entfernt)
|
||||
- `availability_date_start`, `availability_date_end`, `is_fully_available` werden ignoriert; `Applied Filters`-Tabelle erhält für jeden Wert einen Hinweis mit Substring `team_search` und Markierung "nicht wirksam"
|
||||
- `task_*`-Filter bleiben für `team_search` inaktiv (existierender Pfad)
|
||||
- _Requirements: 6.7, 8.4, 8.5, 8.6_
|
||||
|
||||
- [x] 9.8 PBT für `matching_method`-Validierung in `find_matching_teams`
|
||||
- **Property 1: `matching_method`-Validierung in `find_matching_teams`**
|
||||
- **Validates: Requirements 1.5, 1.6**
|
||||
- Hypothesis-Strategie: zufällige Strings außerhalb `{"score","llm_fulltext"}` (case-insensitiv getrimmt) und nicht leer/None; prüft Fehlermeldung enthält beide erlaubten Werte und keine DB-/LLM-Aufrufe erfolgen
|
||||
- Datei: `tests/test_team_matching_method_validation_pbt.py`
|
||||
|
||||
- [x] 9.9 PBT für META und SearchCache-Markierung von Team-Suchen
|
||||
- **Property 11: META und SearchCache markieren Team-Suchen korrekt**
|
||||
- **Validates: Requirements 1.4, 8.1, 8.2, 8.3, 8.4**
|
||||
- Hypothesis-Strategie: zufällige Inputs + Snapshot-Parser für `SEARCH_ID` und `META`-JSON; prüft `search_type=="team_search"`, `matching_method ∈ {...}`, Konsistenz mit `SearchCache`-Eintrag und Header in der per-Kategorie-Tabelle
|
||||
- Datei: `tests/test_team_meta_search_type_pbt.py`
|
||||
|
||||
- [x] 9.10 PBT für Verfügbarkeitsfilter-Ignoranz in Team-Suchen
|
||||
- **Property 12: Verfügbarkeitsfilter werden in Team-Suchen ignoriert**
|
||||
- **Validates: Requirements 6.7, 8.5, 8.6**
|
||||
- Hypothesis-Strategie: zufällige Datumswerte + `is_fully_available`; prüft, dass die gefilterte Item-Menge gleich der ohne Verfügbarkeitsfilter bleibt und die `Applied Filters`-Tabelle den `team_search`-Hinweis enthält
|
||||
- Datei: `tests/test_team_filter_ignores_availability_pbt.py`
|
||||
|
||||
- [x] 9.11 Unit-Tests für `find_matching_teams`, `list_teams`, `get_team_details`
|
||||
- Tools sind über `FastMCP` registriert (Anforderungen 1.3, 9.1, 9.2)
|
||||
- `find_matching_capacities`-Snapshot-Test: Output für festen Input bleibt nach Refactoring unverändert (Anforderung 1.2)
|
||||
- Markdown-Outputs enthalten geforderte Header und Sektionen (Anforderungen 9.1, 9.2, 9.4)
|
||||
- `get_team_details("unknown")` enthält `unknown` in der Fehlermeldung (Anforderung 9.3)
|
||||
- Datei: `tests/test_team_tools_unit.py`
|
||||
- _Requirements: 1.2, 1.3, 9.1, 9.2, 9.3, 9.4_
|
||||
|
||||
- [x] 10. Checkpoint - MCP-Tool-Surface
|
||||
- Sicherstellen, dass alle bisherigen und neuen Tests grün sind und der Server `find_matching_teams`, `list_teams`, `get_team_details` korrekt registriert. Bei Unklarheiten den Nutzer fragen.
|
||||
|
||||
- [x] 11. Integrationstests
|
||||
- [x] 11.1 Smoke-Test für `find_matching_teams` im `score`-Modus
|
||||
- Gemockter Trino-Cursor + Stub-`SimilarityEngine`; voller Pfad `find_matching_teams` → `SearchCache` → `get_results_by_category` → `filter_search_results`
|
||||
- Datei: `tests/test_team_integration_score.py`
|
||||
- _Requirements: 6.1, 8.1, 8.2, 8.4_
|
||||
|
||||
- [x] 11.2 Smoke-Test für `find_matching_teams` im `llm_fulltext`-Modus
|
||||
- Gemockter Trino-Cursor + Mock-`AzureOpenAIClient`; voller Pfad inkl. `errors`-Liste bei simuliertem LLM-Fehler
|
||||
- Datei: `tests/test_team_integration_llm_fulltext.py`
|
||||
- _Requirements: 7.1, 7.6, 8.1, 8.2, 8.4_
|
||||
|
||||
- [x] 12. Dokumentation und Agenten-Konfiguration
|
||||
- [x] 12.1 `docs/architecture.md` um Team-Profil-Abschnitte ergänzen
|
||||
- Neuer Unterabschnitt "Team Profile" im Datenmodell-Kapitel mit Feldern, Datenquellen und View-Verknüpfungen
|
||||
- Datenquellen-Tabelle um die vier neuen Views inkl. relevanter Spalten erweitern
|
||||
- Joins dokumentieren: `teams_latest.team_id = organizational_units_latest.id` (INNER JOIN für Team_Name), `ouid` zu Kompetenzen/Referenzen, `team_references_latest.partner_id = partners_latest.id` (LEFT JOIN, Spalte `name` als Partner_Name)
|
||||
- `Profile_Type`-Parameter und Wertebereiche im Tool-Surface-Abschnitt für `find_matching_capacities`/`find_matching_teams`/`list_teams`/`get_team_details` dokumentieren
|
||||
- Runtime-View-Abschnitt um Aufgabe→Team in beiden Matching-Methoden ergänzen
|
||||
- _Requirements: 11.1, 11.2, 11.3, 11.4, 11.5, 11.6_
|
||||
|
||||
- [x] 12.2 `README.md` um Team-Suche-Hinweise ergänzen
|
||||
- Quick-Start- und Usage-Abschnitt: Wahl zwischen `capacity`- und `team`-Suche
|
||||
- Auflistung der zusätzlichen Datenbank-Views inkl. Join-Bedingungen
|
||||
- Hinweis: Verfügbarkeitsfilter wirken in Team-Suchen nicht; abweichende Ergebnisspalten in `score`/`llm_fulltext`
|
||||
- _Requirements: 11.7, 11.8, 11.9_
|
||||
|
||||
- [x] 12.3 `.github/agents/teamlandkarte_agent.md` und `.kiro/agents/teamlandkarte.md` aktualisieren
|
||||
- `Profile_Type`-Werte `capacity` und `team` mit Bedeutung dokumentieren
|
||||
- Initiale Captures-Phase um explizite Frage nach `Profile_Type` ergänzen (sofern nicht aus Verlauf ersichtlich)
|
||||
- Skills/Workflows um `find_matching_teams`, `list_teams`, `get_team_details` erweitern; `matching_method`-Parameter erwähnen
|
||||
- Hinweis: Verfügbarkeitsfilter sind in Team-Suchen nicht wirksam; Ergebnisspalten weichen ab
|
||||
- Bestätigungs-Workflow (`show_pending_requirements`, `confirm_requirements`) bleibt für beide `Profile_Type`-Werte unverändert
|
||||
- _Requirements: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6_
|
||||
|
||||
- [x] 12.4 Doku-Snapshot-Tests
|
||||
- Prüft, dass `docs/architecture.md`, `README.md`, `.kiro/agents/teamlandkarte.md`, `.github/agents/teamlandkarte_agent.md` die definierten Stichworte enthalten (`Profile_Type`, `find_matching_teams`, `team_search`, `top_competency_weight`)
|
||||
- Datei: `tests/test_team_documentation_snapshots.py`
|
||||
- _Requirements: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9_
|
||||
|
||||
- [x] 13. Erweiterung der bestehenden Test-Suite um Team-Profil-Abdeckung
|
||||
- [x] 13.1 Bestehende End-to-End- und Routing-Tests um Team-Pfade ergänzen
|
||||
- `tests/test_mcp_routing_unit.py`, `tests/test_search_cache.py`, `tests/test_pagination.py`, `tests/test_filters.py` so erweitern, dass beide `Profile_Type`-Werte (`capacity`, `team`) mit beiden `matching_method`-Werten (gemocktes LLM und gemockte DB) abgedeckt sind
|
||||
- _Requirements: 12.7_
|
||||
|
||||
- [x] 14. Final-Checkpoint - Vollständigkeit und Konsistenz
|
||||
- Sicherstellen, dass alle Pflicht-Tasks (ohne `*`) abgeschlossen sind, alle Tests grün sind und die Dokumentation konsistent ist. Bei Unklarheiten den Nutzer fragen.
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Sub-Tasks mit `*` sind optional und werden nur auf ausdrückliche Anweisung implementiert.
|
||||
- Jede Korrektheits-Eigenschaft aus dem Designdokument ist genau einem PBT-Sub-Task zugeordnet (Properties 1–14 in den Tasks 1.4, 2.5–2.8, 3.2, 5.4, 6.2, 6.3, 7.2, 7.3, 9.8, 9.9, 9.10).
|
||||
- Checkpoints (Tasks 4, 8, 10, 14) erzwingen einen grünen Test-Lauf vor dem nächsten Abschnitt.
|
||||
- Die Implementierungssprache ist Python (gemäß bestehendem Codestil); PBT-Framework ist Hypothesis.
|
||||
|
||||
## Workflow-Abschluss
|
||||
|
||||
Dieser Workflow erstellt ausschließlich Design- und Planungsartefakte. Die
|
||||
eigentliche Implementierung beginnt, sobald der Nutzer in `tasks.md` einen Task
|
||||
über "Start task" anstößt.
|
||||
Reference in New Issue
Block a user