Skip to content

Development Guide

Development workflows and best practices.

Development Workflow

Daily Workflow

Bash
1
2
3
4
5
6
7
8
# Terminal 1: Backend
task run-backend

# Terminal 2: Frontend  
task run-frontend

# Terminal 3: Database (if not running)
task db:docker-start

After Backend API Changes

Bash
1
2
3
4
# CRITICAL: Regenerate TypeScript client
task frontend:generate-client

# Frontend now has updated types

Database Changes

Bash
1
2
3
4
5
6
7
# 1. Update model in app/models.py
# 2. Create migration
task db:migrate-create -- "add new field"

# 3. Review migration in migrations/versions/
# 4. Apply migration
task db:migrate-up

Clean Architecture Pattern

Always follow: Controllers → Services → Models

1. Define Schema

Python
1
2
3
4
5
# app/schemas/article.py
class ArticleCreate(SQLModel):
    title: str
    content: str
    is_published: bool = False

2. Implement Service

Python
1
2
3
4
5
6
7
# app/services/article_service.py
class ArticleService:
    async def create_article(self, data: ArticleCreate):
        article = Article(**data.model_dump())
        self.db.add(article)
        await self.db.commit()
        return article

3. Create Controller

Python
1
2
3
4
5
6
7
# app/controllers/article.py
@router.post("")
async def create_article(
    data: ArticleCreate,
    service: ArticleService = Depends(get_article_service)
):
    return await service.create_article(data)

4. Register Router

Python
# main.py
app.include_router(article_router, prefix="/api/articles")

5. Generate Client

Bash
task frontend:generate-client

6. Create React Hook

TypeScript
1
2
3
4
5
6
// frontend/src/hooks/api/useArticles.ts
export const useCreateArticle = () => {
  return useMutation({
    mutationFn: ArticlesService.createArticle,
  });
};

7. Use in Component

TypeScript
1
2
3
4
const Component = () => {
  const createMutation = useCreateArticle();
  return <Button onClick={() => createMutation.mutate(data)}>Create</Button>;
};

Code Style

Python (Backend)

Naming: - snake_case for functions, variables - PascalCase for classes - UPPER_CASE for constants

Type Hints:

Python
async def create_article(self, data: ArticleCreate) -> ArticleRead:
    # Always use type hints

Async/Await:

Python
1
2
3
4
# Always use async for route handlers
@router.get("/")
async def get_items():
    return await service.get_items()

TypeScript (Frontend)

Naming: - PascalCase for components, interfaces - camelCase for functions, variables - UPPER_CASE for constants

Components:

TypeScript
1
2
3
4
5
6
7
8
9
interface Props {
  title: string;
}

const Component: React.FC<Props> = ({ title }) => {
  return <div>{title}</div>;
};

export default Component;

Hooks First:

TypeScript
const Component = () => {
  // 1. Hooks at top
  const { data } = useQuery();
  const { handleError } = useErrorHandler();

  // 2. Event handlers
  const handleClick = () => {};

  // 3. Early returns
  if (!data) return null;

  // 4. Render
  return <div>Content</div>;
};

Testing

Backend Tests

Bash
1
2
3
4
5
6
7
8
# Run all tests
poetry run pytest

# Run specific test
poetry run pytest tests/unit/test_auth.py

# With coverage
poetry run pytest --cov=app

Frontend Tests

Bash
cd frontend

# Run all tests
npm run test

# Watch mode
npm run test -- --watch

# Coverage
npm run test -- --coverage

Common Commands

Bash
# Development
task run-backend
task run-frontend
task frontend:generate-client

# Database
task db:migrate-up
task db:migrate-create -- "description"
task db:docker-start

# Testing
task quality:test
task quality:lint

# Payments (Top G+)
task payments:setup

# Admin (Top G+)
task db:user-create

All commands available via task --list

Project Structure

Text Only
app/
├── controllers/   # HTTP endpoints
├── services/      # Business logic
├── models.py      # Database models
├── schemas/       # Request/response models
├── config/        # Configuration
└── core/          # Utilities

frontend/src/
├── pages/         # Route components
├── components/    # Reusable UI
├── hooks/api/     # API hooks
├── client/        # Generated API client
└── theme/         # MUI theme

See project files directly in app/ and frontend/src/

Best Practices

Backend

  • Use AsyncSession for database
  • Validate in service layer
  • Handle errors in controllers
  • Never commit sensitive data
  • Always use type hints

Frontend

  • Use unified components from @/components/ui
  • Handle errors with useErrorHandler
  • Use React Query for API calls
  • Regenerate client after API changes
  • Use TypeScript strict mode

Database

  • Create migrations for model changes
  • Review auto-generated migrations
  • Test migrations in development
  • Back up before production migration

External Resources