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:
2026-06-30 20:39:52 +02:00
parent 2f2b295531
commit a5f8fb49ab
1717 changed files with 447332 additions and 0 deletions
@@ -0,0 +1,250 @@
# Feature: team-profile-matching, Property 14: Schema-Verifikation deckt fehlende Spalten in den vier neuen Views auf
"""Property-based test for schema verification of the four new team views.
Validates Property 14 from the team-profile-matching design:
*Für jede* Mock-DB-Antwort, die in einer der vier Views
(``teamlandkarte_v_teams_latest``,
``teamlandkarte_v_teammeter_organizational_units_latest``,
``teamlandkarte_v_teammeter_team_competences_latest``,
``teamlandkarte_v_team_references_latest``) eine erwartete Spalte
weglässt, liefert ``verify_required_columns(...)`` für die in
``mcp_server.build_server`` konfigurierte ``schema_expected``-Erweiterung
einen ``SchemaIssue`` mit dem betroffenen Tabellennamen und enthält die
fehlende Spalte in ``message``. Wenn alle erwarteten Spalten vorhanden
sind, ist das Issue-Set für diese vier Views leer.
The Hypothesis strategy generates, for a randomly chosen view, a
non-empty subset of its expected columns to drop. The stub DB then
returns ``full_set - dropped`` for that view (and the full sets for the
other three views). The test asserts that ``verify_required_columns``:
1. Returns at least one ``SchemaIssue`` whose ``table`` equals the
chosen view.
2. The issue's ``message`` mentions every dropped column (lowercased,
per the verifier's normalization).
3. No issues are reported for the other three views (which received
their full column sets).
The positive case is covered by an additional non-property test that
feeds the full column sets and expects an empty issue list.
**Validates: Requirements 12.1, 12.2, 12.3, 12.4**
"""
from __future__ import annotations
from typing import Iterable
from hypothesis import given, settings
from hypothesis import strategies as st
from teamlandkarte_mcp.database.schema_verifier import (
SchemaIssue,
verify_required_columns,
)
# ---------------------------------------------------------------------------
# Source of truth: the four new views and their expected columns.
# Mirrors the ``schema_expected`` extension configured in
# ``mcp_server.build_server`` (see design.md, "Schema-Verifikation beim
# Start"). Keeping this map local keeps the test independent of
# ``build_server`` runtime wiring (which requires a full config + DB).
# ---------------------------------------------------------------------------
_EXPECTED_COLUMNS: dict[str, frozenset[str]] = {
"teamlandkarte_v_teams_latest": frozenset(
{"team_id", "ouid", "about_us", "offerings", "interests", "focus_name"}
),
"teamlandkarte_v_teammeter_organizational_units_latest": frozenset(
{"id", "name"}
),
"teamlandkarte_v_teammeter_team_competences_latest": frozenset(
{"ouid", "competence_id", "top_competency"}
),
"teamlandkarte_v_team_references_latest": frozenset(
{"ouid", "partner_id", "projects"}
),
}
_VIEW_NAMES: tuple[str, ...] = tuple(_EXPECTED_COLUMNS.keys())
# ---------------------------------------------------------------------------
# Test double
# ---------------------------------------------------------------------------
class _StubDB:
"""Stub DB exposing ``get_table_columns`` for a fixed mapping.
The verifier protocol only requires this single method (see
``schema_verifier.SchemaIntrospector``), so this stub is sufficient
to exercise the full code path without touching a real database.
"""
def __init__(self, mapping: dict[str, list[str]]):
self._mapping = mapping
def get_table_columns(self, table: str) -> list[str]:
# ``verify_required_columns`` treats unknown tables as "no columns".
return list(self._mapping.get(table, []))
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _full_columns_for_all_views() -> dict[str, list[str]]:
"""Return the full column lists for every configured view."""
return {view: sorted(cols) for view, cols in _EXPECTED_COLUMNS.items()}
def _expected_map() -> dict[str, set[str]]:
"""Return a fresh ``expected`` map matching the verifier's signature.
The verifier expects ``dict[str, set[str]]``; the canonical map uses
``frozenset`` for immutability, so we materialize plain ``set``s here.
"""
return {view: set(cols) for view, cols in _EXPECTED_COLUMNS.items()}
def _issues_for_table(
issues: Iterable[SchemaIssue], table: str
) -> list[SchemaIssue]:
return [issue for issue in issues if issue.table == table]
# ---------------------------------------------------------------------------
# Hypothesis strategies
# ---------------------------------------------------------------------------
def _drop_subset_strategy() -> st.SearchStrategy[tuple[str, frozenset[str]]]:
"""Strategy for ``(view, columns_to_drop)`` pairs.
Picks a view from the four configured views and a non-empty subset
of its expected columns to "drop" (i.e. omit from the stub DB's
response for that view). The subset is non-empty so the property's
precondition ("at least one expected column is omitted") always
holds.
"""
def _for_view(view: str) -> st.SearchStrategy[tuple[str, frozenset[str]]]:
cols = sorted(_EXPECTED_COLUMNS[view])
# Subset of size in [1, len(cols)]: covers the full powerset
# minus the empty set, which corresponds to the design's
# "Powerset ... minus a randomly chosen column".
return st.lists(
st.sampled_from(cols),
min_size=1,
max_size=len(cols),
unique=True,
).map(lambda picks: (view, frozenset(picks)))
return st.sampled_from(_VIEW_NAMES).flatmap(_for_view)
# ---------------------------------------------------------------------------
# Property: dropping any subset of columns yields an issue per dropped column
# ---------------------------------------------------------------------------
@settings(max_examples=100, deadline=None)
@given(case=_drop_subset_strategy())
def test_missing_columns_in_any_of_the_four_views_produces_schema_issue(
case: tuple[str, frozenset[str]],
) -> None:
"""Property 14 - negative direction.
For every (view, non-empty drop-subset), the verifier emits a
``SchemaIssue`` whose ``table`` is the view and whose ``message``
mentions every dropped column. Other views (with full column sets)
must not produce any issues.
"""
view, dropped = case
full_cols = _EXPECTED_COLUMNS[view]
remaining = sorted(full_cols - dropped)
db_mapping = _full_columns_for_all_views()
db_mapping[view] = remaining
db = _StubDB(db_mapping)
issues = verify_required_columns(db=db, expected=_expected_map())
# 1) The affected view is reported exactly once.
affected = _issues_for_table(issues, view)
assert len(affected) == 1, (
f"Expected exactly one SchemaIssue for {view!r}, got {affected!r}"
)
# 2) Each dropped column (normalized to lowercase, like the verifier
# does internally) appears in the issue message.
message = affected[0].message
assert message.startswith("missing columns: "), message
for col in dropped:
assert col.lower() in message, (
f"Dropped column {col!r} not mentioned in issue message {message!r}"
)
# 3) The other three views must not produce any issues, since they
# were given their full expected column sets.
for other in _VIEW_NAMES:
if other == view:
continue
assert _issues_for_table(issues, other) == [], (
f"Unexpected issue for unaffected view {other!r}: "
f"{_issues_for_table(issues, other)!r}"
)
# ---------------------------------------------------------------------------
# Positive case: full column sets -> no issues for the four views
# ---------------------------------------------------------------------------
def test_full_column_sets_for_all_four_views_yield_no_issues() -> None:
"""Property 14 - positive direction.
When every view exposes its full expected column set, the verifier
must return zero issues for the four configured team views.
"""
db = _StubDB(_full_columns_for_all_views())
issues = verify_required_columns(db=db, expected=_expected_map())
issues_for_team_views = [
issue for issue in issues if issue.table in _EXPECTED_COLUMNS
]
assert issues_for_team_views == []
# ---------------------------------------------------------------------------
# Sanity check: the configured map in ``build_server`` matches the
# canonical map used by this test. This is not part of Property 14 but
# guards against silent drift between the schema verifier wiring and
# the test's source of truth.
# ---------------------------------------------------------------------------
def test_canonical_map_matches_mcp_server_configuration() -> None:
"""The four-view subset of ``schema_expected`` matches this test."""
import inspect
from teamlandkarte_mcp import mcp_server
source = inspect.getsource(mcp_server.build_server)
for view, cols in _EXPECTED_COLUMNS.items():
assert view in source, (
f"View {view!r} missing from mcp_server.build_server"
)
for col in cols:
assert f'"{col}"' in source, (
f"Column {col!r} for view {view!r} missing "
f"from mcp_server.build_server"
)