Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 0 additions & 56 deletions docker-compose.yml

This file was deleted.

233 changes: 228 additions & 5 deletions docs/BOILERPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,232 @@ my-service/

## Flask Projects
```bash
# Flask + PostgreSQL
athena init flask my-app --with-postgresql
# Flask + PostgreSQL (default)
athena init flask my-app

# Flask + MongoDB
athena init flask my-app --with-mongodb
```
# Flask + MySQL
athena init flask my-app --with-mysql

# Without Docker files
athena init flask my-app --no-docker
```

**Generated Flask Structure:**
```
my-app/
├── app/
│ ├── __init__.py # Flask application factory
│ ├── core/
│ │ ├── config.py # Configuration management
│ │ ├── extensions.py # Flask extensions
│ │ └── logging.py # Structured logging
│ ├── api/
│ │ ├── health.py # Health check endpoints
│ │ └── v1/ # API versioning
│ │ ├── auth.py # JWT authentication
│ │ └── users.py # User management
│ ├── models/ # SQLAlchemy models
│ ├── schemas/ # Marshmallow schemas
│ └── services/ # Business logic layer
├── tests/ # Comprehensive test suite
├── nginx/ # Reverse proxy config
├── requirements.txt # Python dependencies
├── Dockerfile # Multi-stage production build
├── docker-compose.yml # Full stack deployment
└── .env.example # Environment template
```

## Laravel Projects (Clean Architecture)
```bash
# Laravel + PostgreSQL (default)
athena init laravel my-project

# Laravel + MySQL
athena init laravel my-project --with-mysql

# Without Docker files
athena init laravel my-project --no-docker
```

**Generated Laravel Structure:**
```
my-project/
├── app/
│ ├── Domain/ # Domain layer (Clean Architecture)
│ │ └── User/
│ │ ├── Entities/ # Domain entities
│ │ │ └── User.php # User entity with business logic
│ │ ├── Repositories/ # Repository interfaces
│ │ └── Services/ # Domain services
│ ├── Application/ # Application layer
│ │ └── User/
│ │ ├── UseCases/ # Use cases (business logic)
│ │ ├── DTOs/ # Data Transfer Objects
│ │ └── Services/ # Application services
│ └── Infrastructure/ # Infrastructure layer
│ ├── Http/
│ │ ├── Controllers/ # API controllers
│ │ └── Middleware/ # Custom middleware
│ ├── Persistence/ # Data persistence
│ │ ├── Eloquent/ # Eloquent models
│ │ └── Repositories/ # Repository implementations
│ └── Providers/ # Service providers
├── config/ # Laravel configuration
├── database/
│ ├── migrations/ # Database migrations
│ └── seeders/ # Data seeders
├── tests/ # Feature & Unit tests
├── docker/ # Docker configurations
├── nginx/ # Nginx configuration
├── composer.json # PHP dependencies (Laravel 11, PHP 8.2)
├── Dockerfile # Multi-stage production build
├── docker-compose.yml # Full stack deployment
└── .env.example # Environment template
```

## Symfony Projects (Hexagonal Architecture)
```bash
# Symfony + PostgreSQL (default)
athena init symfony my-api

# Symfony + MySQL
athena init symfony my-api --with-mysql

# Without Docker files
athena init symfony my-api --no-docker
```

**Generated Symfony Structure:**
```
my-api/
├── src/
│ ├── Domain/ # Domain layer (Hexagonal Architecture)
│ │ └── User/
│ │ ├── Entities/ # Domain entities
│ │ │ └── User.php # Pure domain entity
│ │ ├── ValueObjects/ # Value objects
│ │ │ ├── UserId.php # User ID value object
│ │ │ ├── Email.php # Email value object
│ │ │ ├── UserName.php # User name value object
│ │ │ └── HashedPassword.php
│ │ └── Repositories/ # Repository interfaces
│ │ └── UserRepositoryInterface.php
│ ├── Application/ # Application layer
│ │ └── User/
│ │ ├── Commands/ # CQRS Commands
│ │ │ ├── CreateUserCommand.php
│ │ │ └── LoginCommand.php
│ │ ├── Queries/ # CQRS Queries
│ │ │ └── GetUserQuery.php
│ │ ├── Handlers/ # Command/Query handlers
│ │ │ ├── UserHandler.php
│ │ │ └── AuthHandler.php
│ │ └── Services/ # Application services
│ │ ├── UserService.php
│ │ └── AuthService.php
│ └── Infrastructure/ # Infrastructure layer
│ ├── Http/
│ │ └── Controllers/ # API controllers
│ │ └── UserController.php
│ └── Persistence/
│ └── Doctrine/
│ ├── Entities/ # Doctrine entities
│ │ └── User.php # Infrastructure User entity
│ └── Repositories/ # Repository implementations
│ └── DoctrineUserRepository.php
├── config/ # Symfony configuration
├── migrations/ # Doctrine migrations
├── tests/ # Functional & Unit tests
├── docker/ # Docker configurations
├── nginx/ # Nginx configuration
├── composer.json # PHP dependencies (Symfony 7, PHP 8.2)
├── Dockerfile # Multi-stage production build
├── docker-compose.yml # Full stack deployment
└── .env.example # Environment template
```

## Features & Best Practices 2025

### **Architecture Patterns**
- **Laravel**: Clean Architecture with Domain/Application/Infrastructure layers
- **Symfony**: Hexagonal Architecture with CQRS pattern
- **FastAPI**: Async-first architecture with dependency injection
- **Flask**: Layered architecture with factory pattern
- **Go**: Clean architecture with interfaces and dependency injection

### **Security & Authentication**
- **JWT Authentication** with refresh tokens
- **Password hashing** with modern algorithms (bcrypt/argon2)
- **CORS configuration** for cross-origin requests
- **Input validation** and sanitization
- **Security headers** in Nginx configuration
- **Environment-based secrets** management

### **Modern Language Features**
- **PHP 8.2+**: Strict types, readonly properties, attributes
- **Python 3.12+**: Type hints, async/await, dataclasses
- **Go 1.22+**: Generics, structured logging with slog
- **Dependency injection** and inversion of control
- **Value objects** and domain-driven design

### **Production-Ready Infrastructure**
- **Multi-stage Dockerfiles** for optimized builds
- **Nginx reverse proxy** with caching and compression
- **Health checks** and monitoring endpoints
- **Structured logging** with correlation IDs
- **Database migrations** and seeding
- **Redis caching** integration

### **Testing & Quality**
- **Comprehensive test suites** (unit, integration, functional)
- **PHPUnit 10** / **pytest** / **testify** frameworks
- **Code quality tools**: PHPStan, mypy, golangci-lint
- **Code formatting**: PHP-CS-Fixer, black, gofmt
- **Test coverage** reporting
- **CI/CD ready** configurations

### **Development Experience**
- **Hot reload** in development environments
- **Environment-based configuration** (.env files)
- **Database GUI tools** (Adminer/phpMyAdmin)
- **API documentation** with OpenAPI/Swagger
- **Pre-commit hooks** for code quality
- **Development scripts** and automation

## Quick Start Example

```bash
# Create a modern Laravel API
athena init laravel my-laravel-api
cd my-laravel-api
cp .env.example .env

# Start with Docker
docker-compose up --build

# Install dependencies and migrate
docker-compose exec app composer install
docker-compose exec app php artisan migrate

# Test the API
curl http://localhost/api/health
```

```bash
# Create a Symfony hexagonal API
athena init symfony my-symfony-api --with-mysql
cd my-symfony-api
cp .env.example .env

# Start with Docker
docker-compose up --build

# Install dependencies and migrate
docker-compose exec app composer install
docker-compose exec app php bin/console doctrine:migrations:migrate

# Test the API
curl http://localhost/api/health
```

All generated projects include comprehensive README files with setup instructions, API documentation, and deployment guides.
81 changes: 77 additions & 4 deletions src/boilerplate/fastapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ impl FastAPIGenerator {
let security_content = replace_template_vars_string(SECURITY_PY, &vars);
write_file(base_path.join("app/core/security.py"), &security_content)?;

// Structured logging module (new in 2025)
let logging_content = replace_template_vars_string(crate::boilerplate::templates::LOGGING_PY, &vars);
write_file(base_path.join("app/core/logging.py"), &logging_content)?;

// Rate limiting module (new in 2025)
let rate_limiting_content = replace_template_vars_string(crate::boilerplate::templates::RATE_LIMITING_PY, &vars);
write_file(base_path.join("app/core/rate_limiting.py"), &rate_limiting_content)?;

Ok(())
}

Expand All @@ -100,14 +108,79 @@ impl FastAPIGenerator {
write_file(base_path.join("app/api/__init__.py"), "")?;
write_file(base_path.join("app/api/v1/__init__.py"), "")?;

// Health endpoint (at root level)
let health_py = r#"from fastapi import APIRouter
// Enhanced health endpoint with readiness and liveness (2025 best practices)
let health_py = r#"from __future__ import annotations

from typing import Dict, Any
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
import structlog
import time
from datetime import datetime, timezone

from app.core.config import settings
from app.database.connection import get_async_session

router = APIRouter()
logger = structlog.get_logger()

# Store start time for uptime calculation
start_time = time.time()

# Health check dependencies
async def check_database(db: AsyncSession = Depends(get_async_session)) -> bool:
"""Check database connectivity"""
try:
await db.execute("SELECT 1")
return True
except Exception as e:
logger.error("Database health check failed", error=str(e))
return False

@router.get("/health")
async def health_check():
return {"status": "healthy", "service": "{{project_name}} API"}
async def health_check() -> Dict[str, Any]:
"""Basic health check endpoint"""
return {
"status": "healthy",
"service": "{{project_name}} API",
"version": "1.0.0",
"timestamp": datetime.now(timezone.utc).isoformat(),
"environment": settings.ENVIRONMENT
}

@router.get("/health/ready")
async def readiness_check(db_healthy: bool = Depends(check_database)) -> Dict[str, Any]:
"""Readiness check - can the service handle requests?"""
checks = {
"database": db_healthy,
"service": True # Add more checks as needed
}

all_healthy = all(checks.values())

if not all_healthy:
logger.warning("Readiness check failed", checks=checks)
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail={"status": "not ready", "checks": checks}
)

return {
"status": "ready",
"service": "{{project_name}} API",
"checks": checks,
"timestamp": datetime.now(timezone.utc).isoformat()
}

@router.get("/health/live")
async def liveness_check() -> Dict[str, Any]:
"""Liveness check - is the service alive?"""
return {
"status": "alive",
"service": "{{project_name}} API",
"timestamp": datetime.now(timezone.utc).isoformat(),
"uptime_seconds": time.time() - start_time
}
"#;
let health_content = replace_template_vars_string(health_py, &vars);
write_file(base_path.join("app/api/health.py"), &health_content)?;
Expand Down
Loading