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.
108 lines
5.0 KiB
Markdown
108 lines
5.0 KiB
Markdown
# 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
|
|
|
|
- [x] 1. Add name field to Task model and update TrinoClient queries
|
|
- [x] 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_
|
|
|
|
- [x] 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_
|
|
|
|
- [x] 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**
|
|
|
|
- [x] 2. Add `get_task_by_name` to protocol and TrinoClient
|
|
- [x] 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_
|
|
|
|
- [x] 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**
|
|
|
|
- [x] 3. Checkpoint
|
|
- Ensure all tests pass, ask the user if questions arise.
|
|
|
|
- [x] 4. Update MCP tool output formatting
|
|
- [x] 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_
|
|
|
|
- [x] 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**
|
|
|
|
- [x] 5. Update `get_task_details` resolution logic
|
|
- [x] 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**
|
|
|
|
- [x] 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_
|
|
|
|
- [x] 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)
|