Initial commit: Complete project-bootstrap tool

- Bootstrap script for creating monorepo projects
- FastAPI backend templates with uv, ruff, mypy, pytest
- React frontend templates with TypeScript, ESLint, Prettier
- Docker Compose setup with backend, frontend, and database
- 9 development and CI scripts
- Gitea Actions CI/CD workflows
- Comprehensive documentation (8 files)
- 45 template files for complete project structure
- Automated verification script (all tests pass)
- Based on coding-agent-rules standards
This commit is contained in:
2025-10-15 21:34:08 -04:00
commit 8dd4f0ca63
56 changed files with 3979 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
"""Application configuration."""
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""Application settings."""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
extra="ignore",
)
# Application
app_name: str = "backend"
app_version: str = "0.1.0"
debug: bool = False
log_level: str = "INFO"
# API
api_host: str = "0.0.0.0"
api_port: int = 8000
api_prefix: str = "/api/v1"
# CORS
cors_origins: list[str] = ["http://localhost:3000"]
@lru_cache
def get_settings() -> Settings:
"""Get cached settings instance."""
return Settings()

View File

@@ -0,0 +1,58 @@
"""Error handling utilities."""
from typing import Any
from fastapi import HTTPException, status
class AppException(Exception):
"""Base application exception."""
def __init__(self, message: str, details: dict[str, Any] | None = None) -> None:
"""Initialize exception."""
self.message = message
self.details = details or {}
super().__init__(self.message)
class NotFoundError(AppException):
"""Resource not found error."""
pass
class ValidationError(AppException):
"""Validation error."""
pass
class AuthenticationError(AppException):
"""Authentication error."""
pass
def raise_not_found(resource: str, identifier: str | int) -> None:
"""Raise HTTP 404 exception."""
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"{resource} with id '{identifier}' not found",
)
def raise_validation_error(message: str) -> None:
"""Raise HTTP 422 exception."""
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=message,
)
def raise_unauthorized(message: str = "Unauthorized") -> None:
"""Raise HTTP 401 exception."""
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=message,
headers={"WWW-Authenticate": "Bearer"},
)

View File

@@ -0,0 +1,35 @@
"""FastAPI application entry point."""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.core.config import get_settings
settings = get_settings()
app = FastAPI(
title=settings.app_name,
version=settings.app_version,
debug=settings.debug,
)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def root() -> dict[str, str]:
"""Root endpoint."""
return {"message": "Welcome to the API", "version": settings.app_version}
@app.get("/health")
async def health() -> dict[str, str]:
"""Health check endpoint."""
return {"status": "healthy"}