Automatically triggered when designing system architecture, planning new projects, creating implementation plans, conducting architecture reviews, or auditing existing codebases for consistency. Applies when discussing: system design, technology choices, architectural patterns, infrastructure decisions, API design, testing strategies, CI/CD pipelines, security architecture, or code organization. Works for Python web APIs, infrastructure/DevOps, Garmin/embedded systems, and frontend projects. Distinguishes between personal projects (strict standards) and client work (adaptive approach).
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Automatically triggered when designing system architecture, planning new projects, creating implementation plans, conducting architecture reviews, or auditing existing codebases for consistency. Applies when discussing: system design, technology choices, architectural patterns, infrastructure decisions, API design, testing strategies, CI/CD pipelines, security architecture, or code organization. Works for Python web APIs, infrastructure/DevOps, Garmin/embedded systems, and frontend projects. Distinguishes between personal projects (strict standards) and client work (adaptive approach).
Sam's Architecture Standards
This skill codifies Sam's mature architectural patterns developed across 31+ personal projects and several client projects. It automatically applies during project planning, architecture reviews, and codebase audits.
CRITICAL: Zero-Tolerance Anti-Patterns
These are NEVER acceptable in Sam's personal projects. Flag immediately if detected:
Over-Engineering Anti-Patterns
❌ Premature Microservices: Breaking into microservices before you understand the domain boundaries
Sam's rule: Start monolithic with clear module boundaries, split only when you have operational pain
Example: Don't create separate services for "user-service", "auth-service", "notification-service" in a new project
❌ YAGNI Violations: Building features "because we might need them later"
Sam's rule: Build what you need now, refactor when you need more
Example: Don't add multi-tenancy support to a single-user API
❌ Abstraction Astronauts: Creating generic frameworks when specific solutions work
Sam's rule: Three uses before abstracting. Copy-paste twice, abstract on third use
Example: Don't create a "BaseAPIClient" with complex inheritance when you have one API client
❌ Configuration Complexity: Making everything configurable "for flexibility"
Sam's rule: Hard-code sensible defaults, make configurable only when you need to change it
Example: Don't create config files for things that never change per environment
Under-Engineering Anti-Patterns
❌ No Tests: "We'll add tests later" (narrator: they never did)
Sam's rule: 80% coverage minimum on personal projects, tests written with code
❌ Missing CI/CD: Manual deployments, no automation
Sam's rule: CI/CD setup is part of project initialization, not a "nice to have"
❌ Security as Afterthought: No authentication, secrets in code, no input validation
Sam's rule: Security is non-negotiable from day one
❌ No Documentation: "The code is self-documenting"
Sam's rule: CLAUDE.md + README.md are mandatory for all personal projects
Common Bad Practices
❌ Secrets in Code: API keys, passwords, tokens committed to git
Sam's rule: Environment variables + .env.example template, use Snyk scanning
❌ Missing Error Handling: No try/catch, no logging, silent failures
from pydantic import BaseModel, Field, validator
classUserCreate(BaseModel):
email: str = Field(..., regex=r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$')
password: str = Field(..., min_length=8, max_length=100)
age: int = Field(..., ge=0, le=150)
@validator('password')defpassword_strength(cls, v):
ifnotany(c.isupper() for c in v):
raise ValueError('Password must contain uppercase')
ifnotany(c.isdigit() for c in v):
raise ValueError('Password must contain digit')
return v
Fix all HIGH and CRITICAL vulnerabilities before merging.
5. Secrets Management
Rules:
Never commit secrets to git
Use environment variables
Use .env.example templates (without real secrets)
Add .env to .gitignore
Use secrets management for production (AWS Secrets Manager, K8s Secrets)
Check on every project:
# Audit for potential secrets in git history
git log -p | grep -i "password\|api_key\|secret"
Containerization
Multi-stage Dockerfile for optimal size and security:
# Build stage
FROM python:3.12-slim as builder
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# Runtime stage
FROM python:3.12-slim
WORKDIR /app
# Copy Python dependencies from builder
COPY --from=builder /root/.local /root/.local
# Create non-root user
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
# Copy application code
COPY --chown=appuser:appuser . .
# Make sure scripts are executable
ENV PATH=/root/.local/bin:$PATH
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:8000/health')"
EXPOSE 8000
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
Reference: See /Users/sam/Code/perso/musicgen-api/Dockerfile for production example
docker-compose.yml for local development:
version:'3.8'services:api:build:.ports:-"8000:8000"environment:-DATABASE_URL=postgresql://postgres:postgres@db:5432/myappdepends_on:-dbvolumes:-./src:/app/src# Hot reload for developmentdb:image:postgres:15-alpineenvironment:-POSTGRES_USER=postgres-POSTGRES_PASSWORD=postgres-POSTGRES_DB=myappports:-"5432:5432"volumes:-postgres_data:/var/lib/postgresql/datavolumes:postgres_data:
Key Points:
Multi-stage build (smaller final image)
Python slim base images (not alpine - has issues with some packages)
Non-root user (security)
Health check endpoint
.dockerignore to exclude unnecessary files
Database & Migrations
Default: PostgreSQL
Use PostgreSQL unless you have a specific reason not to:
Mature, reliable, battle-tested
Excellent JSON support (if you need document features)
Reference: See /Users/sam/Code/perso/rancher-cluster/ for Kubernetes patterns
For Local Development: Use Docker Compose instead of Kubernetes (simpler, faster)
CI/CD for Infrastructure
Automate everything:
Terraform plan on PR
Terraform apply on merge to main
Kubernetes manifests validated before apply
No manual changes to infrastructure
Garmin Connect IQ / Embedded Architecture
This section is critical for client work (Darefore, microoled, Stryd).
Memory Management (CRITICAL for MonkeyC)
MonkeyC has severe memory constraints. Memory optimization is not optional.
Profile Early and Often
// Add memory profiling during development
System.println("Memory: " + System.getSystemStats().usedMemory + "/" + System.getSystemStats().totalMemory);
Profile on target devices:
Start with most memory-constrained device
Check memory after each major feature
Monitor for leaks during long runs
Object Allocation Patterns
❌ BAD: Allocate in loops
function onUpdate(dc) {
for (var i = 0; i < data.size(); i++) {
var point = new [data[i].x, data[i].y]; // Allocates every frame!
dc.drawCircle(point[0], point[1], 5);
}
}
✅ GOOD: Reuse buffers
var pointBuffer = new [2]; // Allocate once
function onUpdate(dc) {
for (var i = 0; i < data.size(); i++) {
pointBuffer[0] = data[i].x;
pointBuffer[1] = data[i].y;
dc.drawCircle(pointBuffer[0], pointBuffer[1], 5);
}
}
String Handling
❌ BAD: String concatenation in loops
var result = "";
for (var i = 0; i < items.size(); i++) {
result += items[i] + ", "; // Creates new string each iteration
}
✅ GOOD: Use format or build once
var parts = new [items.size()];
for (var i = 0; i < items.size(); i++) {
parts[i] = items[i];
}
var result = parts.toString(); // Format once
Watch for Memory Leaks
Common leak sources:
Timer callbacks that never get cleaned up
Listener registrations without unregister
Circular references in data structures
Large cached data that's never freed
Reference: See /Users/sam/Code/clients/Darefore/movesense-firmware/ for memory optimization patterns
BLE Protocol Design
For Garmin↔Device BLE communication:
Service/Characteristic Hierarchy
Service: Custom Device Service (UUID: xxx)
├── Characteristic: Command (Write)
│ └── Send commands to device
├── Characteristic: Response (Read/Notify)
│ └── Receive responses from device
├── Characteristic: Data Stream (Notify)
│ └── Continuous data from device
└── Characteristic: Battery (Read)
└── Battery level
Design Principles:
One characteristic per logical function
Use notifications for continuous data (not polling)
Keep packet sizes small (20 bytes for BLE 4.0)
Handle fragmentation for larger messages
Connection Reliability
Handle connection loss gracefully:
function onConnectionLost() {
// Clear any pending operations
clearPendingCommands();
// Update UI to show disconnected
updateConnectionStatus(false);
// Don't crash - keep app running
}
function onConnectionRestored() {
// Re-sync state with device
resyncDeviceState();
// Update UI
updateConnectionStatus(true);
}
Reference: Darefore projects use BLE extensively for Movesense↔Garmin communication
Multi-Device Support
Challenge: Garmin devices have vastly different capabilities
Device Type
Memory
Screen
Notes
Forerunner 945
High
240x240
Full features
Fenix 6
High
260x260
Full features
Vivoactive 3
Medium
240x240
Limited memory
Forerunner 245
Low
240x240
Very constrained
Strategy:
Test on most constrained device first
If it works on FR245, it works everywhere
If you test on Fenix 6 first, you'll be surprised by crashes on FR245
Device-specific asset optimization
<!-- resources/drawables/drawables.xml --><drawables><bitmapid="Logo"filename="logo_240.png"><device>fenix6</device><device>fr945</device></bitmap><bitmapid="Logo"filename="logo_small.png"><device>fr245</device><!-- Smaller image for constrained device --></bitmap></drawables>
Graceful feature degradation
if (System.getSystemStats().totalMemory > 100000) {
// Enable advanced features on high-memory devices
enableAdvancedGraphs();
} else {
// Basic features only on constrained devices
enableBasicDisplay();
}
Memory budgets per device class
High-end (Fenix, FR945): Can use 80% of available memory
Mid-range (Vivoactive): Use max 60% of available memory
Low-end (FR245): Use max 40% of available memory (leave headroom for system)
Reference: See /Users/sam/Code/clients/Darefore/Datafield/ for multi-device MonkeyC patterns
Testing for Embedded
Simulator testing is insufficient. You MUST test on real hardware.
Testing Checklist:
Test on lowest-memory target device
Profile memory usage during typical session
Test BLE connection/disconnection scenarios
Battery life testing (run for hours, measure drain)
Test with actual sensor hardware (if BLE device)
Test all user interactions on physical buttons
Test in sunlight (screen visibility)
Test during actual activity (running/cycling)
Memory Profiling:
// Add debug overlay during development
function onUpdate(dc) {
// ... normal rendering ...
if (DEBUG) {
var stats = System.getSystemStats();
var memText = "Mem: " + stats.usedMemory + "/" + stats.totalMemory;
dc.drawText(10, 10, Graphics.FONT_TINY, memText, Graphics.TEXT_JUSTIFY_LEFT);
}
}
Battery Testing Protocol:
Full charge device
Run app for 2 hours during activity
Measure battery drain
Compare to baseline (device without app)
Target: < 10% additional drain over 2 hours
Frontend / Static Site Architecture
Framework Choice
Static Sites: Astro (default)
Rationale: Fast, excellent DX, brings your own framework
Use for: Documentation, blogs, marketing sites
Example: Personal website, project documentation
Mobile Apps: React Native with Expo
Rationale: Cross-platform, large ecosystem, fast development
Use for: iOS/Android apps
Example: Companion apps for Garmin devices
Web Apps: React or Next.js
React: For SPAs with separate backend
Next.js: For SSR or SSG with API routes
Use for: Complex interactive web apps
State Management
Simple apps (< 5 components with shared state):
React Context API
No external library needed
Complex apps (> 5 components, complex state):
Zustand (lightweight) or Redux Toolkit (if you need middleware)
Don't use Redux for simple apps (overkill)
Example:
// Using Zustand for simple global stateimport create from'zustand';
interfaceAppState {
user: User | null;
setUser: (user: User) =>void;
isLoading: boolean;
setLoading: (loading: boolean) =>void;
}
exportconst useAppStore = create<AppState>((set) => ({
user: null,
setUser: (user) =>set({ user }),
isLoading: false,
setLoading: (loading) =>set({ isLoading: loading }),
}));
MANDATORY for all personal projects. No exceptions.
1. CLAUDE.md (REQUIRED)
Every personal project MUST have a CLAUDE.md file at the root. This is the primary documentation for AI assistants and future maintainers.
Template:
# [Project Name]## Purpose
[1-2 paragraphs: What problem does this solve? Why does it exist?]
## Architecture Overview### Technology Stack- Language: Python 3.12
- Framework: FastAPI
- Database: PostgreSQL
- ORM: SQLAlchemy
- Testing: pytest
- CI/CD: GitHub Actions
### Architectural Pattern
This project follows the Service→Repository→Database pattern:
-**Routes** (`src/api/routes/`): HTTP handling, validation
-**Services** (`src/services/`): Business logic, orchestration
-**Repositories** (`src/repositories/`): Data access abstraction
-**Models** (`src/models/`): SQLAlchemy ORM models
[Include architecture diagram if complex]
## Key Architectural Decisions### Why FastAPI instead of Flask?
[Rationale for framework choice]
### Why PostgreSQL?
[Rationale for database choice]
### Why Service→Repository→Database pattern?
[Explain testability, maintainability benefits]
## Development Workflow### Initial Setup```bash
# Clone and install
git clone [repo-url]
cd [project-name]
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-dev.txt
# Set up environment
cp .env.example .env
# Edit .env with your values
# Set up database
alembic upgrade head
# Run tests
pytest
Running Locally
# Start database
docker-compose up -d db
# Run API
uvicorn src.main:app --reload
# API available at http://localhost:8000# Docs at http://localhost:8000/docs
Running Tests
# All tests with coverage
pytest --cov=src --cov-report=term
# Specific test file
pytest tests/unit/services/test_user_service.py
# With verbose output
pytest -v
See CLAUDE.md for detailed development documentation.
Testing
pytest --cov=src
Deployment
[Brief deployment instructions or link to deployment docs]
License
[License information]
### 3. Architecture Decision Records (ADRs)
**REQUIRED** for significant architectural decisions.
**When to create an ADR**:
- Framework or language changes
- Major refactoring decisions
- Security architecture decisions
- Infrastructure changes
- Breaking changes to APIs
**Format**: `docs/adr/YYYYMMDD-decision-title.md`
**Template**:
```markdown
# [Number]. [Title]
Date: YYYY-MM-DD
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXX]
## Context
[What is the issue that we're seeing that is motivating this decision or change?]
## Decision
[What is the change that we're proposing and/or doing?]
## Consequences
### Positive
- [What becomes easier or better?]
### Negative
- [What becomes harder or worse?]
### Neutral
- [What changes but is neither better nor worse?]
## Alternatives Considered
### Alternative 1: [Name]
[Why we didn't choose this]
### Alternative 2: [Name]
[Why we didn't choose this]
Example ADR:
# 1. Use FastAPI instead of Flask for new API projects
Date: 2024-11-15
## Status
Accepted
## Context
We need to choose a web framework for new Python API projects. Historically, we've used Flask, but FastAPI has gained significant traction and offers several advantages for modern API development.
## Decision
We will use FastAPI as the default framework for all new Python API projects. Existing Flask projects will remain Flask unless a major refactor makes migration worthwhile.
## Consequences### Positive- Automatic OpenAPI documentation generation (no manual Swagger setup)
- Native async/await support for better performance on I/O-bound operations
- Built-in request validation with Pydantic (type safety)
- Better IDE support due to type hints
- Modern Python 3.10+ features encouraged
### Negative- Team needs to learn new framework
- Some Flask extensions don't have FastAPI equivalents
- Existing Flask projects create a two-framework codebase
### Neutral- Migration path exists for Flask apps if needed
- Both frameworks use similar routing patterns
## Alternatives Considered### Alternative 1: Continue using Flask- Pros: Team familiarity, large ecosystem
- Cons: No automatic docs, no native async, manual validation setup
- Why rejected: FastAPI advantages outweigh learning cost
### Alternative 2: Use Django REST Framework- Pros: Batteries included, Django ORM
- Cons: Heavy for simple APIs, opinionated structure
- Why rejected: Too much overhead for typical API projects
User: "I want to build a new API for tracking weather data"
Assistant Response:
- Project Type: Python Web API
- Stack: FastAPI + PostgreSQL + Service→Repository→Database
- Authentication: Bearer token (since it's tracking data, needs auth)
- Testing: pytest with 80% coverage
- CI/CD: GitHub Actions with multi-Python testing, Snyk, Docker
Let me help you set up the project structure:
1. First, I'll create the initial directory structure following the Service→Repository→Database pattern
2. Set up FastAPI with a /health endpoint
3. Configure PostgreSQL with SQLAlchemy
4. Set up pytest with coverage
5. Create GitHub Actions workflow
6. Add CLAUDE.md and README.md documentation
7. Create .env.example template
Let's start with the project structure...
When Auditing Existing Projects
Audit Checklist:
1. Architectural Pattern Compliance
Python APIs: Using Service→Repository→Database pattern?
### When Integrating with Client Projects
**Assessment Process**:
1. **Determine Ownership Level**
- Full architectural control? (e.g., Darefore/Datafield)
- Collaborative? (e.g., Stryd/Stryd-Zones)
- Support role? (e.g., microoled/activelook-garmin-app)
2. **Understand Existing Patterns**
- What's their current architecture?
- What patterns do they use?
- What constraints do they have?
- What's their tech stack?
3. **Adapt Recommendations**
- **Full Control**: Apply Sam's patterns fully
- **Collaborative**: Suggest improvements, align with team
- **Support**: Follow their patterns strictly
4. **Document Deviations**
- If patterns differ from Sam's standards, document why in CLAUDE.md
- Explain constraints that led to different choices
- Note what you'd do differently if you had full control
**Example: Full Control (Darefore)**:
Context: New Garmin data field for Darefore's Movesense device
Approach:
Apply full Sam architecture standards
Memory optimization from day one
Comprehensive BLE protocol design
Multi-device support strategy
Complete documentation (CLAUDE.md)
Testing on real hardware throughout
ADRs for major decisions
**Example: Collaborative (Stryd)**:
Context: Contributing to Stryd's existing Garmin app
Approach:
Understand their existing code patterns
Follow their naming conventions
Use their testing approach
Suggest improvements diplomatically ("Have you considered X?")
Document shared decisions in PR descriptions
Don't force Sam's patterns if they conflict with team norms
**Example: Support (microoled)**:
Context: Bug fixes and minor features for microoled's ActiveLook app
Approach:
Follow existing patterns strictly
Don't introduce major architectural changes
Focus on minimal, targeted fixes
Match their code style
Don't add "improvements" beyond what's requested
---
## What Sam Does NOT Do
Comprehensive exclusion list - flag these immediately:
### APIs Without Authentication
❌ "It's just internal" - **NO**. Every API gets authentication.
❌ "We'll add auth later" - **NO**. Auth from day one.
### Testing Shortcuts
❌ "We'll add tests later" - **NO**. Tests written with code.
❌ Coverage below 80% on personal projects - **UNACCEPTABLE**.
❌ "Manual testing is enough" - **NO**. Automated tests required.
### CI/CD Shortcuts
❌ "Too much setup overhead" - **NO**. CI/CD is part of project init.
❌ Manual deployments without automation - **NO**. Automate everything.
❌ Skipping security scanning - **NO**. Snyk in pipeline.
### Architecture Mistakes
❌ Fat controllers with business logic - **NO**. Service→Repository→Database.
❌ Database queries in routes - **NO**. Repository abstraction required.
❌ Monolithic single file - **NO**. Clear module separation.
❌ Premature microservices - **NO**. Start monolithic.
### Framework Choices
❌ Using Flask for new projects - **NO**. FastAPI is the standard.
❌ Using MongoDB for relational data - **NO**. PostgreSQL default.
❌ Rolling custom auth instead of OAuth2/JWT - **NO**. Use standards.
### Documentation Avoidance
❌ Missing CLAUDE.md - **UNACCEPTABLE** for personal projects.
❌ No README - **UNACCEPTABLE**.
❌ No .env.example - **UNACCEPTABLE**.
❌ "Code is self-documenting" - **NO**. Document decisions.
### Security Negligence
❌ Secrets committed to git - **ZERO TOLERANCE**.
❌ No input validation - **UNACCEPTABLE**.
❌ No environment variable validation - **UNACCEPTABLE**.
❌ Docker containers running as root - **NO**. Create non-root user.
❌ Missing health check endpoints - **NO**. /health required.
### Code Quality Issues
❌ No error handling - **NO**. Explicit error handling required.
❌ No logging - **NO**. Structured logging required.
❌ Silent failures - **NO**. Fail loudly or handle explicitly.
❌ No type hints (Python) - **NO**. Type hints everywhere.
### Embedded/Garmin Mistakes
❌ Not testing on real hardware - **NO**. Simulator insufficient.
❌ Ignoring memory constraints - **CRITICAL**. Profile memory always.
❌ Allocating in loops - **NO**. Reuse buffers.
❌ Not testing on constrained devices - **NO**. Test on FR245 first.
### Infrastructure Shortcuts
❌ Manual infrastructure changes - **NO**. Use Terraform.
❌ No remote state for Terraform - **NO**. S3 + DynamoDB.
❌ No environment separation - **NO**. dev/staging/prod distinct.
---
## Key Success Patterns
These are patterns Sam consistently applies across mature projects:
### 1. Service→Repository→Database Pattern (Python APIs)
**Always** separate concerns:
- Routes handle HTTP
- Services handle business logic
- Repositories handle data access
### 2. 80% Test Coverage (Personal Projects)
**Always** maintain high coverage with comprehensive test pyramid.
### 3. Comprehensive CI/CD
**Always** automate: testing, security scanning, building, versioning, deployment.
### 4. Security First
**Always** include: authentication, input validation, secrets management, vulnerability scanning.
### 5. Memory Optimization (Embedded)
**Always** profile early, minimize allocations, test on constrained devices.
### 6. Complete Documentation
**Always** provide: CLAUDE.md, README.md, .env.example, ADRs for major decisions.
### 7. Containerization Standards
**Always** use: multi-stage builds, non-root users, health checks.
### 8. Pragmatic Technology Choices
**Always** choose: FastAPI (not Flask for new projects), PostgreSQL (not MongoDB), Terraform (not manual), K8s (for production).
---
## Activation Context
This skill automatically activates when you:
- Plan a new project
- Design system architecture
- Conduct architecture reviews
- Audit existing codebases
- Make technology choices
- Set up CI/CD pipelines
- Design security architecture
- Organize code structure
- Create implementation plans
- Discuss testing strategies
Use this skill to ensure consistency with Sam's mature architectural patterns across all project types.