Files
Orchestrator/bahn/teamlandkarte-mcp/.kiro/specs/task-name-column/tasks.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

5.0 KiB

Implementation Plan: Task Name Column

Overview

Add the name__c database column to the Task model and all task queries, enabling users to see and look up tasks by their short human-readable name. Changes span model, database layer, protocol, and MCP tool output.

Tasks

  • 1. Add name field to Task model and update TrinoClient queries

    • 1.1 Add name: Optional[str] field to the Task dataclass in models.py

      • Insert name: Optional[str] after id field
      • Field must be Optional since name__c can be NULL in the database
      • Requirements: 1.1, 1.4
    • 1.2 Update get_open_tasks SQL queries in trino_client.py to SELECT t.name__c

      • Add t.name__c to the unlimited query SELECT clause
      • Add t.name__c to the CTE inner SELECT and outer SELECT in the limited query
      • Update row unpacking to extract the name value
      • Populate name field in Task construction (map NULL to None)
      • Requirements: 1.2, 1.4
    • 1.3 Update get_task_by_id SQL query in trino_client.py to SELECT t.name__c

      • Add t.name__c to the SELECT clause
      • Update row unpacking to extract the name value
      • Populate name field in Task construction (map NULL to None)
      • Requirements: 1.3, 1.4
    • * 1.4 Write property test: Task name field preserves database value

      • Property 1: Task name field preserves database value
      • Generate random (name__c_value | None) values using Hypothesis
      • Construct Task objects via the row-mapping pattern, assert task.name == input_value
      • Validates: Requirements 1.1, 1.2, 1.3, 1.4
  • 2. Add get_task_by_name to protocol and TrinoClient

    • 2.1 Add get_task_by_name method to DBClient protocol in database/types.py

      • Method signature: def get_task_by_name(self, name: str) -> Task | None
      • Include docstring: "Fetch one published task by its short name (name__c)."
      • Requirements: 3.1
    • 2.2 Implement get_task_by_name in TrinoClient

      • SQL query selects same columns as get_task_by_id plus t.name__c
      • WHERE clause filters on t.name__c = ? and t.status__c = ?
      • ORDER BY t.createddate DESC to handle duplicates (return first match)
      • Reuse same row-assembly logic as get_task_by_id
      • Return None for empty string input or no matching rows
      • Requirements: 3.1, 3.2, 3.3
    • * 2.3 Write property test: Name lookup returns correct task

      • Property 3: Name lookup returns correct task
      • Generate random tasks with unique names, mock DB cursor
      • Call get_task_by_name(name), assert returned task's name matches
      • Validates: Requirements 3.2
  • 3. Checkpoint

    • Ensure all tests pass, ask the user if questions arise.
  • 4. Update MCP tool output formatting

    • 4.1 Add "Name" column to list_open_tasks output table

      • Add "Name" to the header list (between task_id and Title)
      • Add str(task.name or "") to each row
      • Update the empty-row fallback to include the extra column
      • Requirements: 2.1
    • 4.2 Add "Name" to get_task_details summary table

      • Add "Name" to the header list
      • Add str(task.name or "") to the row data
      • Requirements: 2.2
    • * 4.3 Write property test: Task output contains name

      • Property 2: Task output contains name
      • Generate random Task objects with non-None names using st.text(min_size=1)
      • Format through output functions, assert name appears as substring
      • Validates: Requirements 2.1, 2.2
  • 5. Update get_task_details resolution logic

    • 5.1 Add name-based fallback resolution in get_task_details tool

      • After get_task_by_id returns None, call db_client.get_task_by_name(task_id)
      • If both return None, return "Task not found or not published: {task_id}"
      • Requirements: 3.4, 3.5
    • * 5.2 Write property test: Name resolution equivalence

      • Property 4: Name resolution equivalence
      • Generate a task with non-None name, mock both lookup methods
      • Call get_task_details with name and with ID, assert outputs identical
      • Validates: Requirements 3.4
    • * 5.3 Write property test: Unknown identifier returns not-found

      • Property 5: Unknown identifier returns not-found
      • Generate random strings not matching any known task ID or name
      • Call get_task_details, assert output contains "not found"
      • Validates: Requirements 3.3, 3.5
  • 6. Update FakeDBClient in tests and add get_task_by_name stub

    • Add name field to FakeTask in existing test files
    • Add get_task_by_name method to FakeDBClient
    • Update existing test assertions that check table headers (add "Name" column)
    • Requirements: 3.1
  • 7. Final checkpoint

    • Ensure all tests pass, ask the user if questions arise.

Notes

  • Tasks marked with * are optional and can be skipped for faster MVP
  • Each task references specific requirements for traceability
  • Property tests use Hypothesis with @settings(max_examples=100)
  • The implementation language is Python (matching the existing codebase)