Files
issue-core/CLAUDE.md
tegwick f89772ac79 fix: update remaining .feedback references to feedback
Update directory structure diagrams and copy examples to use
the new visible feedback/ directory instead of hidden .feedback/

This ensures all documentation is consistent with the
ReusableCapabilitiesArchitecture v0.1 specification.
2025-12-17 22:40:06 +01:00

16 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Issue Facade is a universal CLI for issue tracking that provides a unified interface to multiple issue tracking backends (GitHub, GitLab, Gitea, local SQLite). It implements the Facade Pattern to abstract away differences between various issue tracking systems, providing developers with a consistent CLI experience regardless of the underlying backend.

Development Commands

Installation & Setup

  • Install for development: pip install -e ".[dev]"
  • Install production: pip install -e .
  • Clean build artifacts: make issue-facade-clean

Testing

  • Run all tests: pytest tests/
  • Run specific test file: pytest tests/test_gitea_backend.py
  • Run with coverage: pytest tests/ --cov=issue_tracker --cov-report=html --cov-report=term
  • Run integration tests: pytest tests/test_gitea_integration.py -v

Code Quality

  • Run linter: make issue-facade-lint
  • Format code: black issue_tracker/ tests/ (line length: 100)
  • Sort imports: isort issue_tracker/ tests/

CLI Usage

The project provides two entry points: issue and issue-tracker (both execute issue_tracker.cli.main:main)

Common commands:

  • issue list - List issues
  • issue show <number> - Show issue details
  • issue create "Title" - Create new issue
  • issue close <number> - Close issue
  • issue backend list - List configured backends
  • issue sync - Synchronize with remote backend

Architecture

Core Design Pattern: Facade with Plugin Architecture

The codebase implements a plugin-based facade pattern with clear separation of concerns:

┌─────────────────────────────────────────┐
│         CLI Layer (Click)               │
│   issue_tracker/cli/*.py                │
└───────────────┬─────────────────────────┘
                │
┌───────────────▼─────────────────────────┐
│     Core Domain Models                  │
│   issue_tracker/core/models.py          │
│   (Issue, Label, User, etc.)            │
└───────────────┬─────────────────────────┘
                │
┌───────────────▼─────────────────────────┐
│     Backend Interface (ABC)             │
│   issue_tracker/core/interfaces.py      │
│   IssueBackend, LocalBackend,           │
│   RemoteBackend, SyncableBackend        │
└───────────────┬─────────────────────────┘
                │
        ┌───────┴────────┐
        │                │
┌───────▼──────┐  ┌──────▼───────┐
│Local Backend │  │Gitea Backend │
│  (SQLite)    │  │  (REST API)  │
└──────────────┘  └──────────────┘

Key Components

1. Core Domain Models (issue_tracker/core/models.py)

  • Issue: Universal issue model with state management, label categorization, and domain logic
  • Label: Supports categorization (priority/type/status/other) with cached properties
  • User, Milestone, Comment: Supporting models
  • IssueState, Priority, IssueType: Enumerations with backend mapping

The Issue model uses @cached_property for performance optimization and includes domain logic methods (close(), reopen(), add_label(), etc.) that enforce business rules.

2. Backend Interface (issue_tracker/core/interfaces.py)

  • IssueBackend (ABC): Defines the contract all backends must implement
  • LocalBackend, RemoteBackend: Marker interfaces for backend categorization
  • SyncableBackend: Interface for backends supporting synchronization
  • BackendCapabilities: Describes feature support per backend
  • BackendFactory: Registry pattern for backend creation

Critical: All backends MUST implement the full IssueBackend interface. The interface includes:

  • Connection management: connect(), disconnect(), test_connection()
  • CRUD operations: create_issue(), get_issue(), update_issue(), delete_issue()
  • Query operations: list_issues(), search_issues()
  • Label, User, Milestone, Comment operations
  • Optional: bulk_update_issues() (if capabilities support it)

3. Backend Implementations

Local Backend (issue_tracker/backends/local/backend.py):

  • Uses SQLite with schema defined in schema.sql
  • Full offline functionality
  • Serves as synchronization source of truth
  • Implements LocalBackend and SyncableBackend

Gitea Backend (issue_tracker/backends/gitea/backend.py):

  • REST API integration with Gitea instances
  • Rate limiting and error handling
  • ID mapping between local and remote issues
  • Implements RemoteBackend and SyncableBackend

4. CLI Layer (issue_tracker/cli/)

  • main.py: Entry point, Click group setup, command registration
  • commands.py: Core issue operations (list, show, create, close)
  • backend_commands.py: Backend management (add, list, switch)
  • sync_commands.py: Synchronization operations
  • utils.py: Helper functions for formatting and backend access

ID Mapping Strategy

The system uses a dual-ID approach for cross-backend synchronization:

  • id: Universal ID (UUID for local, external ID for remote)
  • number: Human-readable sequential number (user-facing)
  • backend_id: Backend-specific identifier for sync

When syncing, backends maintain mappings between local numbers and remote IDs. The Gitea backend stores this in sync_metadata on the Issue model.

State Management

IssueState enum provides universal states with backend-specific mapping via to_backend_string():

  • OPEN, CLOSED, IN_PROGRESS, BLOCKED
  • Some backends (like Gitea) only support OPEN/CLOSED, so IN_PROGRESS and BLOCKED map to OPEN

Testing Strategy

Test Organization

  • test_gitea_backend.py: Unit tests for Gitea backend with mocked API
  • test_gitea_integration.py: Full integration tests with real Gitea instance
  • test_cli_commands.py: CLI command testing

Integration Tests

The integration tests (test_gitea_integration.py) expect a Gitea instance at http://localhost:3000 with test credentials. They create a temporary test repository, run full CRUD operations, and clean up afterwards.

Important: Integration tests use pytest markers:

  • @pytest.mark.integration - Integration tests (slower)
  • @pytest.mark.unit - Unit tests (fast)

Run only unit tests: pytest -m unit Run only integration tests: pytest -m integration

Common Development Tasks

Adding a New Backend

  1. Create backend package in issue_tracker/backends/<name>/
  2. Implement IssueBackend interface (or extend LocalBackend/RemoteBackend)
  3. Implement all abstract methods from the interface
  4. Define BackendCapabilities to specify supported features
  5. Register backend in BackendFactory (typically in __init__.py)
  6. Add configuration handling in CLI backend commands
  7. Write unit tests with mocked external dependencies
  8. Write integration tests if applicable

Modifying the Issue Model

When changing issue_tracker/core/models.py:

  1. Update the Issue dataclass definition
  2. Update to_dict() serialization method
  3. Invalidate caches if adding/modifying label-dependent properties
  4. Update all backend implementations to handle new fields
  5. Update database schema in backends/local/schema.sql
  6. Write migration logic if modifying existing fields

Adding CLI Commands

  1. Add command function in appropriate file (commands.py, backend_commands.py, etc.)
  2. Use @click.command() decorator with appropriate options
  3. Call get_backend(ctx) to retrieve the active backend
  4. Use format_issue() or format_issue_list() from utils.py for consistent output
  5. Handle errors with raise click.ClickException(message)
  6. Register command in main.py if creating new command group

Configuration

Project Configuration (pyproject.toml)

  • Entry points: issue and issue-tracker commands
  • Dependencies: click, requests, python-dateutil
  • Optional dependencies: dev, docs, gitea, github, jira
  • Code style: Black (line-length=100), isort (profile="black")
  • Test markers: unit, integration, slow

Makefile Integration

The capability integrates with the parent markitect project via Makefile:

  • Prefixed targets: issue-facade-* for development commands
  • Unprefixed targets: issue-* for user-facing CLI operations
  • Uses pip install -e for editable installation

Important Patterns and Conventions

Error Handling

  • Backend-specific errors inherit from base exceptions (e.g., GiteaAPIError)
  • CLI commands convert exceptions to click.ClickException with user-friendly messages
  • Use specific exception types for rate limiting, authentication, network issues

Type Hints

  • Mypy strict mode enabled (disallow_untyped_defs = true)
  • All functions must have type annotations
  • Use Optional[T] for nullable types
  • Use List[T], Dict[K, V] from typing module (Python 3.8 compatibility)

Performance Optimizations

  • Use @cached_property for expensive computations (e.g., label categorization)
  • Call invalidate_cache() when modifying cached data
  • Single-pass algorithms for label categorization in Issue model

Synchronization

When implementing sync:

  1. Local backend is source of truth
  2. Remote backends track last sync timestamp
  3. Use get_issues_modified_since() for incremental sync
  4. Handle conflicts via SyncableBackend.resolve_sync_conflict()
  5. Store sync metadata in Issue.sync_metadata dict

Dependencies and External Systems

Runtime Dependencies

  • click: CLI framework (>=8.0.0)
  • requests: HTTP client for remote backends (>=2.25.0)
  • python-dateutil: Date/time parsing (>=2.8.0)

Development Dependencies

  • pytest: Testing framework with markers support
  • pytest-cov: Coverage reporting
  • pytest-mock: Mocking utilities
  • black, isort, flake8, mypy: Code quality tools

External Systems

  • Gitea API: REST API at /api/v1/ endpoints
  • SQLite: Local database (no server required)
  • Future: GitHub API, GitLab API, JIRA API

Repository Context

This is a capability within the larger markitect project (/capabilities/issue-facade/). The capability:

  • Can be installed independently via pip install -e .
  • Integrates with parent project via Makefile targets
  • Follows markitect capability conventions for structure and naming

Feedback and Continuous Improvement

This capability implements the feedback pattern - a lightweight, unstructured feedback loop for continuous improvement based on real-world usage from master projects integrating this capability.

Overview

The feedback system consists of:

  • feedback/ directory: Stores all feedback with minimal organization
  • .capability/feedback CLI tool: Standalone tool for submitting and managing feedback
  • No structure imposement: Accept any text/markdown format
  • Capability-owned: Maintainers organize and prioritize feedback

Directory Structure

feedback/
├── inbound/         # New feedback from users (unreviewed)
├── reviewed/        # Feedback reviewed by maintainers
├── archived/        # Resolved or outdated feedback
└── README.md        # Complete documentation

For Users: Submitting Feedback

Users of issue-facade (master projects integrating it) can submit feedback in multiple ways:

Option 1: Using feedback CLI

# Quick text feedback
./.capability/feedback submit "The sync command is slow with 1000+ issues"

# From a file
./.capability/feedback submit detailed-feedback.md

# With metadata
./.capability/feedback submit "Bug report" --category=bug --contact=me@email.com

Option 2: Direct file drop (no CLI needed)

# Just create a markdown file in inbound/
cat > feedback/inbound/$(date +%Y%m%d)-sync-issue.md << 'EOF'
The sync is taking 10+ minutes with our 5000-issue repo.
Would love to see progress indicators or batch processing.
EOF

Option 3: From master project

cd my-master-project
echo "Feedback about issue-facade..." > feedback.md
cp feedback.md capabilities/issue-facade/feedback/inbound/$(date +%Y%m%d)-feedback.md

For Maintainers: Processing Feedback

List and review feedback:

# List pending feedback
./.capability/feedback list

# Show specific feedback
./.capability/feedback show 20251217-103045-abc12345.md

# Show statistics
./.capability/feedback stats

Process feedback:

# Mark as reviewed
./.capability/feedback review 20251217-103045-abc12345.md

# Create issue from feedback
./.capability/feedback review 20251217-103045-abc12345.md --create-issue

# Archive when resolved
./.capability/feedback archive 20251217-103045-abc12345.md

Manual workflow (without CLI):

# 1. List new feedback
ls -lt feedback/inbound/

# 2. Read feedback
cat feedback/inbound/20251217-103045-sync-issue.md

# 3. Take action (create issue, fix, document)
issue create "Feature: Show sync progress" \
  --description "$(cat feedback/inbound/20251217-103045-sync-issue.md)" \
  --label=feedback --label=feature

# 4. Move to reviewed
mv feedback/inbound/20251217-103045-sync-issue.md feedback/reviewed/

Integration with Development Workflow

Feedback informs:

  • Roadmap prioritization: Most requested features get priority
  • Bug triage: Real-world issues from production usage
  • Documentation improvements: Where users struggle
  • UX enhancements: Friction points in actual usage

Review rhythm:

  • Daily: Quick scan of new feedback
  • Weekly: Deep review, create issues, respond to users
  • Monthly: Archive old feedback, analyze trends

Feedback Pattern (Reusable Across Capabilities)

The feedback system is capability-agnostic and can be copied to any markitect capability:

  1. Copy the pattern:

    mkdir -p feedback/inbound feedback/reviewed feedback/archived
    cp /path/to/feedback-template/README.md feedback/
    cp /path/to/feedback-template/feedback .capability/
    chmod +x .capability/feedback
    
  2. Document in CAPABILITY-issue-tracking.yaml:

    feedback:
      enabled: true
      method: feedback-capability
      submission:
        cli: ".capability/feedback submit 'Your feedback'"
        directory: "feedback/inbound/"
    
  3. Add to Makefile (optional):

    feedback:
        @./.capability/feedback submit "$(MSG)"
    

Future Evolution:

  • When capability becomes a service, add API endpoint: POST /api/feedback
  • API writes to same feedback/inbound/ directory
  • Maintains consistency across CLI, file drop, and API submission

Why This Pattern?

  • Decentralized: Each capability owns its feedback
  • Flexible: No forms, no required structure
  • Durable: Plain files survive system changes
  • Auditable: Git tracks all feedback
  • Actionable: Feedback lives where maintainers work
  • Scalable: Works for 1 user or 1000 users
  • Future-proof: Can evolve to CLI/API while maintaining structure

See feedback/README.md for complete documentation.