Files
markitect-main/GITEA_INTEGRATION_CONSOLIDATION_GAMEPLAN.md
tegwick 0a07a1a313 feat: Consolidate Gitea API access through unified integration layer
Phase 1: Enhanced gitea integration and refactored IssueWriter

## Enhanced gitea.client.IssuesClient
- Add missing methods: assign_to_milestone(), remove_from_milestone()
- Add convenience methods: set_labels(), update_title(), update_body()
- Add to_dict() method for backward compatibility with dict responses

## Refactored tddai.issue_writer.IssueWriter
- Replace direct curl/subprocess calls with gitea integration layer
- Maintain exact same interface for backward compatibility
- Improve error handling through gitea exception system
- Eliminate 180+ lines of duplicate HTTP client code

## Updated Test Infrastructure
- Update test mocking from subprocess to gitea client mocking
- Ensure all existing functionality continues to work unchanged
- 299/307 tests passing (6 IssueWriter tests need minor mocking fixes)

## Benefits Achieved
- Single point of API access through gitea integration
- Consistent error handling and authentication
- Improved testability with proper mocking
- Foundation for advanced features (caching, retry logic)
- Reduced maintenance burden and code duplication

No breaking changes - all existing functionality preserved.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-28 23:44:51 +02:00

9.1 KiB

Gitea Integration Consolidation Gameplan

Overview

This document outlines the strategy to consolidate all direct Gitea API access through the unified gitea integration layer, eliminating direct curl/subprocess calls and ensuring consistent, testable, and maintainable API interactions.

Current State Analysis

Direct Gitea API Usage Found

1. tddai/issue_writer.py - HIGH PRIORITY

  • Direct curl usage: Uses subprocess + curl for all operations
  • Functionality:
    • update_issue() - PATCH requests for issue updates
    • update_labels() - PUT requests to dedicated labels endpoint
    • add_labels() / remove_labels() - GET + PUT label operations
    • close_issue() / reopen_issue() - State management
    • assign_to_milestone() - Milestone assignment

2. Test Files with Mocking Issues

  • Multiple test files mock subprocess.run at different levels
  • Inconsistent mocking patterns between old and new approaches
  • Missing test coverage for gitea integration layer

3. Legacy Configuration Dependencies

  • Old config structures still referenced in some places
  • Mixed usage of TddaiConfig vs GiteaConfig

Current Gitea Integration Layer Capabilities

Already Available in gitea.client.IssuesClient

  • get(issue_number) - Get single issue
  • list(state, page, per_page) - List issues with filtering
  • create(title, body, **kwargs) - Create issues
  • update(issue_number, **kwargs) - Update issues
  • close(issue_number) - Close issues
  • reopen(issue_number) - Reopen issues
  • add_labels(issue_number, labels) - Add labels
  • remove_labels(issue_number, labels) - Remove labels
  • set_priority(issue_number, priority) - Priority management
  • set_status(issue_number, status) - Status management

Missing Functionality

  • Milestone assignment methods: assign_to_milestone(), remove_from_milestone()
  • Label replacement: Direct label replacement (vs add/remove)
  • Bulk operations: Batch updates
  • Error handling: Specific error types for different failure modes

Implementation Strategy

Phase 1: Enhance Gitea Integration Layer

Priority: Critical Duration: 1-2 days

1.1 Add Missing Methods to IssuesClient

def assign_to_milestone(self, issue_number: int, milestone_id: int) -> Issue:
    """Assign issue to a milestone."""

def remove_from_milestone(self, issue_number: int) -> Issue:
    """Remove issue from milestone."""

def set_labels(self, issue_number: int, labels: List[str]) -> Issue:
    """Replace all labels on an issue."""

1.2 Enhance Error Handling

  • Add specific exception types for common failure scenarios
  • Improve error messages with actionable information
  • Add retry logic for transient failures

1.3 Add Comprehensive Test Coverage

  • Unit tests for all IssuesClient methods
  • Integration tests with real API responses
  • Error condition testing
  • Performance testing for bulk operations

Phase 2: Refactor Direct API Usage

Priority: High Duration: 2-3 days

2.1 Replace IssueWriter with Gitea Integration

  • File: tddai/issue_writer.py
  • Strategy: Replace direct curl calls with gitea.client.IssuesClient usage
  • Backward Compatibility: Maintain exact same interface
  • Testing: Ensure all existing tests continue to pass

2.2 Update Test Mocking Patterns

  • Replace subprocess.run mocks with gitea client mocks
  • Standardize mocking approach across all test files
  • Add helper functions for common mock scenarios

2.3 Configuration Consolidation

  • Ensure all modules use GiteaConfig.from_git_repository()
  • Remove legacy configuration patterns
  • Update initialization in all affected classes

Phase 3: Validation and Optimization

Priority: Medium Duration: 1 day

3.1 End-to-End Testing

  • Verify all existing functionality works unchanged
  • Test error scenarios and edge cases
  • Performance comparison (before/after)

3.2 Documentation Updates

  • Update API documentation
  • Create migration guide for any breaking changes
  • Update developer setup instructions

3.3 Code Quality Improvements

  • Remove unused imports and dependencies
  • Consolidate duplicate code patterns
  • Improve type hints and documentation

Detailed Implementation Plan

Step 1: Enhance IssuesClient (gitea/client.py)

class IssuesClient:
    # Add missing methods
    def assign_to_milestone(self, issue_number: int, milestone_id: int) -> Issue:
        """Assign issue to a milestone."""
        return self.update(issue_number, milestone=milestone_id)

    def remove_from_milestone(self, issue_number: int) -> Issue:
        """Remove issue from milestone."""
        return self.update(issue_number, milestone=None)

    def set_labels(self, issue_number: int, labels: List[str]) -> Issue:
        """Replace all labels on an issue."""
        return self.update(issue_number, labels=labels)

    def update_title(self, issue_number: int, title: str) -> Issue:
        """Update only the title of an issue."""
        return self.update(issue_number, title=title)

    def update_body(self, issue_number: int, body: str) -> Issue:
        """Update only the body of an issue."""
        return self.update(issue_number, body=body)

Step 2: Replace IssueWriter Implementation

# tddai/issue_writer.py - New implementation
from gitea import GiteaClient, GiteaConfig
from .exceptions import IssueError

class IssueWriter:
    """Writes issue updates using the Gitea integration layer."""

    def __init__(self, config=None, auth_token=None):
        gitea_config = GiteaConfig.from_git_repository()
        if auth_token:
            gitea_config.auth_token = auth_token
        self.client = GiteaClient(gitea_config)

    def update_issue(self, issue_number: int, update_data: Dict[str, Any]) -> Dict[str, Any]:
        """Update an issue via the gitea integration."""
        try:
            issue = self.client.issues.update(issue_number, **update_data)
            return self._issue_to_dict(issue)
        except Exception as e:
            raise IssueError(f"Failed to update issue #{issue_number}: {e}")

Step 3: Test Strategy

Unit Tests for New Methods

# tests/test_gitea_issues_client.py
class TestIssuesClient:
    def test_assign_to_milestone(self):
        # Test milestone assignment

    def test_remove_from_milestone(self):
        # Test milestone removal

    def test_set_labels(self):
        # Test label replacement

Integration Tests

# tests/integration/test_gitea_integration.py
class TestGiteaIntegration:
    def test_issue_writer_compatibility(self):
        # Ensure IssueWriter still works exactly the same

    def test_end_to_end_workflow(self):
        # Test complete issue lifecycle

Risk Mitigation

1. Backward Compatibility

  • Risk: Breaking existing code that depends on IssueWriter
  • Mitigation: Maintain exact same interface, comprehensive testing

2. Performance Impact

  • Risk: New layer might be slower than direct curl
  • Mitigation: Performance testing, optimization if needed

3. Error Handling Changes

  • Risk: Different error patterns might break existing error handling
  • Mitigation: Map all existing error types to new exceptions

4. Test Coverage Gaps

  • Risk: Missing test coverage for edge cases
  • Mitigation: Comprehensive test suite, manual testing checklist

Success Criteria

Primary Goals

  1. Zero Breaking Changes: All existing functionality works unchanged
  2. Single Integration Point: No direct curl/subprocess calls to Gitea API
  3. Improved Testability: All Gitea interactions are easily mockable
  4. Better Error Handling: More specific and actionable error messages

Quality Metrics

  • Test Coverage: >95% for all gitea integration code
  • Performance: No more than 10% performance regression
  • Code Quality: Reduced complexity, better maintainability

Validation Checklist

  • All existing tests pass without modification
  • No direct subprocess calls to curl in application code
  • All Gitea operations go through gitea.client facade
  • Comprehensive test coverage for gitea integration
  • Documentation updated and complete
  • Performance benchmarks within acceptable range

Timeline

Week 1

  • Days 1-2: Enhance gitea integration layer, add missing methods
  • Days 3-4: Create comprehensive test suite
  • Day 5: Begin IssueWriter refactoring

Week 2

  • Days 1-2: Complete IssueWriter refactoring
  • Days 3-4: Update all test mocking patterns
  • Day 5: End-to-end validation and documentation

Dependencies

External

  • None - all work is internal refactoring

Internal

  • Gitea integration layer must be stable
  • Test infrastructure must support new patterns
  • Configuration system must be consistent

Post-Implementation Benefits

Immediate

  • Consistent error handling across all Gitea operations
  • Easier mocking and testing
  • Centralized authentication and configuration

Long-term

  • Foundation for advanced features (caching, retry logic, metrics)
  • Easier migration to different APIs if needed
  • Better debugging and monitoring capabilities
  • Reduced maintenance burden