ADR-0003: Architecture Decisions¶
“Architecture is the art of how to waste space.” — Philip Johnson
Status¶
Accepted
Context¶
The seedling template needs to make specific architectural decisions about project structure, file organization, and development patterns. These decisions will affect all projects generated from the template.
Decision¶
Adopt specific architectural patterns and conventions for consistency and maintainability.
Consequences¶
Project Structure¶
src/ Layout¶
Why src/ layout?
Import clarity: Prevents import confusion between package and test files
Standard practice: Industry standard for Python projects
IDE support: Better IDE support and autocomplete
Testing clarity: Clear separation between source and test code
Packaging: Easier to package and distribute
Package Organization¶
src/{{ project_slug }}/
├── __init__.py # Package initialization
├── core/ # Core functionality
├── utils/ # Utility functions
├── config/ # Configuration management
└── models/ # Data models
Testing Strategy¶
Multi-level Testing¶
Unit tests: Fast, isolated tests for individual functions
Integration tests: Tests for component interactions
End-to-end tests: Full workflow testing
Property-based testing: Hypothesis for edge case discovery
Test Organization¶
tests/
├── unit/ # Unit tests
├── integration/ # Integration tests
└── e2e/ # End-to-end tests
Documentation Architecture¶
Sphinx Configuration¶
Furo theme: Modern, responsive theme with dark mode
MyST parser: Markdown support with extensions
API documentation: Automatic API documentation generation
Search functionality: Built-in search capabilities
Documentation Structure¶
docs/
├── source/ # Sphinx source files
│ ├── api.md # API documentation
│ ├── contributing.md # Contributing guide
│ └── index.md # Main documentation
├── build/ # Generated documentation
└── Makefile # Documentation build commands
CI/CD Pipeline¶
GitHub Actions Workflows¶
CI workflow: Multi-environment testing with matrix strategy
Documentation workflow: Automatic documentation deployment
Release workflow: Automated PyPI publishing
Security workflow: CodeQL security scanning
Static analysis: Pre-commit-ci integration
Quality Gates¶
Linting: Ruff for code quality
Type checking: MyPy for type safety
Test coverage: Minimum 80% coverage requirement
Security scanning: pip-audit for vulnerability detection
Complexity analysis: Xenon for code complexity
Configuration Management¶
Environment-based Configuration¶
Development: Local development settings
Testing: Test-specific configuration
Production: Production deployment settings
CI/CD: Automated testing configuration
Configuration Files¶
pyproject.toml: Project metadata and tool configuration
.pre-commit-config.yaml: Pre-commit hooks configuration
noxfile.py: Nox session definitions
justfile: Development task definitions
Dependency Management¶
uv-based Dependencies¶
Core dependencies: Essential runtime dependencies
Development dependencies: Development and testing tools
Documentation dependencies: Documentation generation tools
Type checking dependencies: Type checking tools
Security dependencies: Security scanning tools
Dependency Groups¶
[project.optional-dependencies]
dev = ["pytest", "ruff", "mypy", "pre-commit"]
docs = ["sphinx", "furo", "myst-parser"]
typecheck = ["mypy", "types-requests"]
security = ["pip-audit"]
Code Quality Standards¶
Type Safety¶
Full type hints: All public APIs must have type hints
MyPy strict mode: Zero type errors required
Type checking in CI: Automated type checking in CI pipeline
Type coverage: High type coverage requirements
Code Style¶
Black formatting: Consistent code formatting
Ruff linting: Comprehensive linting rules
Import sorting: isort for import organization
Docstring standards: Google or NumPy style docstrings
Security Considerations¶
Dependency Security¶
Regular scanning: Automated vulnerability scanning
Security updates: Prompt security update process
Dependency pinning: Pinned dependency versions
Audit trail: Security audit documentation
Code Security¶
Static analysis: CodeQL security scanning
Secret detection: Pre-commit hooks for secret detection
Input validation: Comprehensive input validation
Error handling: Secure error handling practices
Performance Optimization¶
Build Performance¶
Caching: Effective caching strategies
Parallel execution: Parallel test execution
Incremental builds: Incremental documentation builds
Dependency optimization: Optimized dependency resolution
Runtime Performance¶
Memory management: Efficient memory usage
Algorithm optimization: Optimized algorithms
Caching strategies: Runtime caching where appropriate
Profiling: Performance profiling tools
Extensibility Patterns¶
Plugin Architecture¶
Registry pattern: Extensible registry system
Hook system: Plugin hook system
Configuration-driven: Configuration-driven extensions
API stability: Stable extension APIs
Customization Points¶
Template variables: Jinja2 template variables
Conditional generation: Conditional file generation
Custom workflows: Customizable CI/CD workflows
Theme customization: Customizable documentation themes
Implementation Guidelines¶
File Naming Conventions¶
Python files: snake_case for modules and packages
Test files: test_*.py for test modules
Configuration files: kebab-case for configuration files
Documentation files: kebab-case for documentation files
Code Organization¶
Single responsibility: Each module has a single responsibility
Dependency injection: Use dependency injection for flexibility
Interface segregation: Small, focused interfaces
Open/closed principle: Open for extension, closed for modification
Error Handling¶
Exception hierarchy: Well-defined exception hierarchy
Error messages: Clear, actionable error messages
Logging: Comprehensive logging strategy
Recovery mechanisms: Graceful error recovery