Initial commit
This commit is contained in:
711
skills/project-scaffolding/checklists/project-setup-checklist.md
Normal file
711
skills/project-scaffolding/checklists/project-setup-checklist.md
Normal file
@@ -0,0 +1,711 @@
|
||||
# Grey Haven Project Setup Checklist
|
||||
|
||||
Comprehensive checklist for scaffolding new Grey Haven projects with TanStack Start, FastAPI, or both.
|
||||
|
||||
## Pre-Project Planning
|
||||
|
||||
- [ ] **Define project scope** (MVP features, future roadmap)
|
||||
- [ ] **Choose architecture**:
|
||||
- [ ] TanStack Start only (frontend + BFF)
|
||||
- [ ] FastAPI only (backend API)
|
||||
- [ ] Full-stack (TanStack Start + FastAPI)
|
||||
- [ ] Monorepo or separate repos
|
||||
|
||||
- [ ] **Define multi-tenant strategy**:
|
||||
- [ ] Single-tenant (one customer)
|
||||
- [ ] Multi-tenant (multiple customers)
|
||||
- [ ] Tenant isolation: subdomain, custom domain, path-based
|
||||
|
||||
- [ ] **Plan authentication**:
|
||||
- [ ] Better Auth (recommended for Grey Haven)
|
||||
- [ ] OAuth providers (Google, GitHub, etc.)
|
||||
- [ ] Email/password
|
||||
- [ ] Magic links
|
||||
|
||||
- [ ] **Database choice**:
|
||||
- [ ] PostgreSQL (recommended for Grey Haven)
|
||||
- [ ] MySQL
|
||||
- [ ] SQLite (development only)
|
||||
|
||||
- [ ] **Hosting platform**:
|
||||
- [ ] Vercel (TanStack Start)
|
||||
- [ ] Railway (FastAPI)
|
||||
- [ ] AWS (ECS, Lambda)
|
||||
- [ ] Self-hosted
|
||||
|
||||
## Repository Setup
|
||||
|
||||
### Initialize Git
|
||||
|
||||
- [ ] **Create repository** (GitHub, GitLab, Bitbucket)
|
||||
- [ ] **Initialize git**: `git init`
|
||||
- [ ] **Add .gitignore**:
|
||||
```
|
||||
node_modules/
|
||||
.env
|
||||
.env.local
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
dist/
|
||||
.output/
|
||||
.vercel/
|
||||
.DS_Store
|
||||
```
|
||||
|
||||
- [ ] **Initial commit**: `git commit -m "Initial commit"`
|
||||
- [ ] **Create dev branch**: `git checkout -b dev`
|
||||
- [ ] **Set up branch protection** (require PRs for main)
|
||||
|
||||
### Project Structure
|
||||
|
||||
- [ ] **Create standard directories**:
|
||||
```
|
||||
.
|
||||
├── .claude/ # Claude Code config (optional)
|
||||
├── apps/ # Monorepo applications
|
||||
│ ├── web/ # TanStack Start app
|
||||
│ └── api/ # FastAPI app
|
||||
├── packages/ # Shared packages (monorepo)
|
||||
│ ├── shared-types/ # TypeScript types
|
||||
│ ├── ui/ # Shared UI components
|
||||
│ └── utils/ # Shared utilities
|
||||
├── docs/ # Documentation
|
||||
├── scripts/ # Automation scripts
|
||||
└── .github/ # GitHub workflows
|
||||
└── workflows/
|
||||
```
|
||||
|
||||
- [ ] **Add README.md** with:
|
||||
- [ ] Project description
|
||||
- [ ] Tech stack
|
||||
- [ ] Getting started guide
|
||||
- [ ] Environment variables
|
||||
- [ ] Deployment instructions
|
||||
|
||||
## TanStack Start Setup
|
||||
|
||||
### Installation
|
||||
|
||||
- [ ] **Create Vite project**:
|
||||
```bash
|
||||
npm create vite@latest my-app -- --template react-ts
|
||||
cd my-app
|
||||
```
|
||||
|
||||
- [ ] **Install TanStack Start**:
|
||||
```bash
|
||||
npm install @tanstack/react-router @tanstack/react-query
|
||||
npm install -D @tanstack/router-vite-plugin @tanstack/router-devtools
|
||||
```
|
||||
|
||||
- [ ] **Install dependencies**:
|
||||
```bash
|
||||
npm install zod drizzle-orm @better-auth/react
|
||||
npm install -D drizzle-kit tailwindcss postcss autoprefixer
|
||||
```
|
||||
|
||||
### Configure Vite
|
||||
|
||||
- [ ] **Update vite.config.ts**:
|
||||
```typescript
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
TanStackRouterVite()
|
||||
],
|
||||
server: {
|
||||
port: 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8000',
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Configure TailwindCSS
|
||||
|
||||
- [ ] **Initialize Tailwind**:
|
||||
```bash
|
||||
npx tailwindcss init -p
|
||||
```
|
||||
|
||||
- [ ] **Update tailwind.config.js**:
|
||||
```javascript
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Add Tailwind directives** to `src/index.css`:
|
||||
```css
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
```
|
||||
|
||||
### Setup Drizzle (Database)
|
||||
|
||||
- [ ] **Install Drizzle**:
|
||||
```bash
|
||||
npm install drizzle-orm postgres
|
||||
npm install -D drizzle-kit
|
||||
```
|
||||
|
||||
- [ ] **Create drizzle.config.ts**:
|
||||
```typescript
|
||||
import { defineConfig } from 'drizzle-kit'
|
||||
|
||||
export default defineConfig({
|
||||
schema: './src/db/schema.ts',
|
||||
out: './drizzle',
|
||||
dialect: 'postgresql',
|
||||
dbCredentials: {
|
||||
url: process.env.DATABASE_URL!
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Create schema file** `src/db/schema.ts`:
|
||||
```typescript
|
||||
import { pgTable, uuid, text, timestamp } from 'drizzle-orm/pg-core'
|
||||
|
||||
export const users = pgTable('users', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
email: text('email').notNull().unique(),
|
||||
name: text('name').notNull(),
|
||||
tenantId: uuid('tenant_id').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow(),
|
||||
updatedAt: timestamp('updated_at').defaultNow()
|
||||
})
|
||||
|
||||
export const tenants = pgTable('tenants', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
name: text('name').notNull(),
|
||||
slug: text('slug').notNull().unique(),
|
||||
createdAt: timestamp('created_at').defaultNow()
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Create migration**: `npx drizzle-kit generate`
|
||||
- [ ] **Run migration**: `npx drizzle-kit migrate`
|
||||
|
||||
### Setup Better Auth
|
||||
|
||||
- [ ] **Install Better Auth**:
|
||||
```bash
|
||||
npm install better-auth @better-auth/react
|
||||
```
|
||||
|
||||
- [ ] **Create auth config** `src/lib/auth.ts`:
|
||||
```typescript
|
||||
import { betterAuth } from 'better-auth'
|
||||
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
provider: 'pg'
|
||||
}),
|
||||
emailAndPassword: {
|
||||
enabled: true
|
||||
},
|
||||
socialProviders: {
|
||||
google: {
|
||||
clientId: process.env.GOOGLE_CLIENT_ID!,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET!
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Create auth context** for React
|
||||
- [ ] **Add protected route wrapper**
|
||||
|
||||
### Router Setup
|
||||
|
||||
- [ ] **Create routes directory** `src/routes/`
|
||||
- [ ] **Create index route** `src/routes/index.tsx`
|
||||
- [ ] **Create auth routes** (login, register, logout)
|
||||
- [ ] **Create protected routes** (dashboard, settings)
|
||||
- [ ] **Configure router** in `src/main.tsx`
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- [ ] **Create .env.local**:
|
||||
```
|
||||
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
|
||||
BETTER_AUTH_SECRET=generate-with-openssl-rand-base64-32
|
||||
GOOGLE_CLIENT_ID=your-google-client-id
|
||||
GOOGLE_CLIENT_SECRET=your-google-client-secret
|
||||
VITE_API_URL=http://localhost:8000
|
||||
```
|
||||
|
||||
- [ ] **Create .env.example** (without secrets)
|
||||
- [ ] **Add to .gitignore**: `.env.local`
|
||||
|
||||
## FastAPI Setup
|
||||
|
||||
### Installation
|
||||
|
||||
- [ ] **Create project directory**:
|
||||
```bash
|
||||
mkdir my-api && cd my-api
|
||||
```
|
||||
|
||||
- [ ] **Setup Python virtual environment**:
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
||||
```
|
||||
|
||||
- [ ] **Install FastAPI and dependencies**:
|
||||
```bash
|
||||
pip install fastapi uvicorn sqlmodel psycopg2-binary pydantic python-dotenv
|
||||
pip install pytest pytest-asyncio httpx # Testing
|
||||
```
|
||||
|
||||
- [ ] **Create requirements.txt**:
|
||||
```bash
|
||||
pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
- [ ] **Create standard structure**:
|
||||
```
|
||||
my-api/
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # FastAPI app
|
||||
│ ├── models/ # SQLModel models
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── user.py
|
||||
│ │ └── tenant.py
|
||||
│ ├── repositories/ # Data access layer
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── base.py
|
||||
│ │ └── user_repository.py
|
||||
│ ├── services/ # Business logic
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── user_service.py
|
||||
│ ├── api/ # API routes
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── deps.py # Dependencies
|
||||
│ │ └── v1/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── users.py
|
||||
│ │ └── auth.py
|
||||
│ ├── core/ # Config, security
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── config.py
|
||||
│ │ └── security.py
|
||||
│ └── db/ # Database
|
||||
│ ├── __init__.py
|
||||
│ └── session.py
|
||||
├── tests/
|
||||
│ ├── __init__.py
|
||||
│ ├── conftest.py
|
||||
│ └── test_users.py
|
||||
├── alembic/ # Migrations
|
||||
├── .env
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
### Database Setup (SQLModel)
|
||||
|
||||
- [ ] **Create SQLModel models** `app/models/user.py`:
|
||||
```python
|
||||
from sqlmodel import SQLModel, Field
|
||||
from uuid import UUID, uuid4
|
||||
from datetime import datetime
|
||||
|
||||
class User(SQLModel, table=True):
|
||||
__tablename__ = "users"
|
||||
|
||||
id: UUID = Field(default_factory=uuid4, primary_key=True)
|
||||
email: str = Field(unique=True, index=True)
|
||||
name: str
|
||||
tenant_id: UUID = Field(foreign_key="tenants.id", index=True)
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
updated_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
```
|
||||
|
||||
- [ ] **Create database session** `app/db/session.py`:
|
||||
```python
|
||||
from sqlmodel import create_engine, Session
|
||||
from app.core.config import settings
|
||||
|
||||
engine = create_engine(settings.DATABASE_URL, echo=True)
|
||||
|
||||
def get_session():
|
||||
with Session(engine) as session:
|
||||
yield session
|
||||
```
|
||||
|
||||
- [ ] **Create tables**: `SQLModel.metadata.create_all(engine)`
|
||||
|
||||
### Repository Pattern
|
||||
|
||||
- [ ] **Create base repository** `app/repositories/base.py`:
|
||||
```python
|
||||
from typing import Generic, TypeVar, Type, Optional, List
|
||||
from sqlmodel import Session, select
|
||||
from uuid import UUID
|
||||
|
||||
ModelType = TypeVar("ModelType", bound=SQLModel)
|
||||
|
||||
class BaseRepository(Generic[ModelType]):
|
||||
def __init__(self, model: Type[ModelType], session: Session):
|
||||
self.model = model
|
||||
self.session = session
|
||||
|
||||
def get(self, id: UUID) -> Optional[ModelType]:
|
||||
return self.session.get(self.model, id)
|
||||
|
||||
def get_all(self, tenant_id: UUID) -> List[ModelType]:
|
||||
statement = select(self.model).where(
|
||||
self.model.tenant_id == tenant_id
|
||||
)
|
||||
return self.session.exec(statement).all()
|
||||
|
||||
def create(self, obj: ModelType) -> ModelType:
|
||||
self.session.add(obj)
|
||||
self.session.commit()
|
||||
self.session.refresh(obj)
|
||||
return obj
|
||||
```
|
||||
|
||||
- [ ] **Create specific repositories** (UserRepository, TenantRepository)
|
||||
|
||||
### API Routes
|
||||
|
||||
- [ ] **Create main app** `app/main.py`:
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from app.api.v1 import users, auth
|
||||
|
||||
app = FastAPI(title="My API", version="1.0.0")
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["http://localhost:3000"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app.include_router(auth.router, prefix="/api/v1/auth", tags=["auth"])
|
||||
app.include_router(users.router, prefix="/api/v1/users", tags=["users"])
|
||||
|
||||
@app.get("/health")
|
||||
def health_check():
|
||||
return {"status": "healthy"}
|
||||
```
|
||||
|
||||
- [ ] **Create route handlers** `app/api/v1/users.py`
|
||||
- [ ] **Add dependency injection** for tenant_id, user auth
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- [ ] **Create .env**:
|
||||
```
|
||||
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
|
||||
SECRET_KEY=generate-with-openssl-rand-hex-32
|
||||
ALGORITHM=HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
CORS_ORIGINS=http://localhost:3000
|
||||
```
|
||||
|
||||
- [ ] **Create config** `app/core/config.py`:
|
||||
```python
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
class Settings(BaseSettings):
|
||||
DATABASE_URL: str
|
||||
SECRET_KEY: str
|
||||
ALGORITHM: str = "HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
|
||||
settings = Settings()
|
||||
```
|
||||
|
||||
## Testing Setup
|
||||
|
||||
### TypeScript/Vitest (Frontend)
|
||||
|
||||
- [ ] **Install Vitest**:
|
||||
```bash
|
||||
npm install -D vitest @vitest/ui @testing-library/react @testing-library/jest-dom
|
||||
```
|
||||
|
||||
- [ ] **Create vitest.config.ts**:
|
||||
```typescript
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: './src/test/setup.ts'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Add test script** to package.json: `"test": "vitest"`
|
||||
- [ ] **Create sample test** `src/test/example.test.ts`
|
||||
|
||||
### Pytest (Backend)
|
||||
|
||||
- [ ] **Create conftest.py** with test fixtures:
|
||||
```python
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlmodel import Session, create_engine, SQLModel
|
||||
from app.main import app
|
||||
from app.db.session import get_session
|
||||
|
||||
@pytest.fixture(name="session")
|
||||
def session_fixture():
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
SQLModel.metadata.create_all(engine)
|
||||
with Session(engine) as session:
|
||||
yield session
|
||||
|
||||
@pytest.fixture(name="client")
|
||||
def client_fixture(session: Session):
|
||||
def get_session_override():
|
||||
return session
|
||||
app.dependency_overrides[get_session] = get_session_override
|
||||
client = TestClient(app)
|
||||
yield client
|
||||
app.dependency_overrides.clear()
|
||||
```
|
||||
|
||||
- [ ] **Add test script**: `pytest tests/ -v`
|
||||
- [ ] **Create sample test** `tests/test_users.py`
|
||||
|
||||
## Linting & Formatting
|
||||
|
||||
### TypeScript (ESLint + Prettier)
|
||||
|
||||
- [ ] **Install ESLint**:
|
||||
```bash
|
||||
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
|
||||
```
|
||||
|
||||
- [ ] **Install Prettier**:
|
||||
```bash
|
||||
npm install -D prettier eslint-config-prettier
|
||||
```
|
||||
|
||||
- [ ] **Create .eslintrc.json**
|
||||
- [ ] **Create .prettierrc**
|
||||
- [ ] **Add scripts** to package.json:
|
||||
```json
|
||||
"lint": "eslint src --ext ts,tsx",
|
||||
"format": "prettier --write src"
|
||||
```
|
||||
|
||||
### Python (Ruff + Black)
|
||||
|
||||
- [ ] **Install Ruff and Black**:
|
||||
```bash
|
||||
pip install ruff black
|
||||
```
|
||||
|
||||
- [ ] **Create pyproject.toml**:
|
||||
```toml
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
select = ["E", "F", "I"]
|
||||
```
|
||||
|
||||
- [ ] **Add to requirements.txt** (dev dependencies)
|
||||
|
||||
## CI/CD Setup
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
- [ ] **Create workflow** `.github/workflows/ci.yml`:
|
||||
```yaml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
pull_request:
|
||||
branches: [main, dev]
|
||||
|
||||
jobs:
|
||||
test-frontend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
- run: npm ci
|
||||
- run: npm run lint
|
||||
- run: npm test
|
||||
- run: npm run build
|
||||
|
||||
test-backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- run: pip install -r requirements.txt
|
||||
- run: pytest tests/ -v
|
||||
```
|
||||
|
||||
- [ ] **Add deployment workflow** (Vercel, Railway, AWS)
|
||||
|
||||
## Database Migrations
|
||||
|
||||
- [ ] **Setup Drizzle migrations** (TanStack Start):
|
||||
- [ ] `npx drizzle-kit generate` to create migrations
|
||||
- [ ] `npx drizzle-kit migrate` to apply migrations
|
||||
|
||||
- [ ] **Setup Alembic** (FastAPI):
|
||||
```bash
|
||||
pip install alembic
|
||||
alembic init alembic
|
||||
```
|
||||
- [ ] Configure alembic.ini with DATABASE_URL
|
||||
- [ ] Create migration: `alembic revision --autogenerate -m "message"`
|
||||
- [ ] Apply migration: `alembic upgrade head`
|
||||
|
||||
## Secrets Management
|
||||
|
||||
- [ ] **Choose secrets manager**:
|
||||
- [ ] Doppler (recommended for Grey Haven)
|
||||
- [ ] AWS Secrets Manager
|
||||
- [ ] Environment variables (for local dev only)
|
||||
|
||||
- [ ] **Install Doppler CLI** (if using Doppler):
|
||||
```bash
|
||||
# Install: https://docs.doppler.com/docs/install-cli
|
||||
doppler login
|
||||
doppler setup
|
||||
```
|
||||
|
||||
- [ ] **Never commit secrets** to git
|
||||
- [ ] **Use .env.example** for documentation
|
||||
|
||||
## Deployment
|
||||
|
||||
### Vercel (TanStack Start)
|
||||
|
||||
- [ ] **Install Vercel CLI**: `npm i -g vercel`
|
||||
- [ ] **Connect to Vercel**: `vercel link`
|
||||
- [ ] **Configure environment variables** in Vercel dashboard
|
||||
- [ ] **Deploy**: `vercel --prod`
|
||||
- [ ] **Setup custom domain** (if needed)
|
||||
|
||||
### Railway (FastAPI)
|
||||
|
||||
- [ ] **Install Railway CLI**: `npm i -g @railway/cli`
|
||||
- [ ] **Login**: `railway login`
|
||||
- [ ] **Initialize**: `railway init`
|
||||
- [ ] **Add environment variables**: `railway variables`
|
||||
- [ ] **Deploy**: `railway up`
|
||||
|
||||
## Multi-Tenant Configuration
|
||||
|
||||
- [ ] **Add tenant_id** to all relevant tables
|
||||
- [ ] **Create RLS policies** (if using PostgreSQL RLS)
|
||||
- [ ] **Repository pattern** enforces tenant filtering
|
||||
- [ ] **Subdomain routing** (if applicable):
|
||||
- [ ] tenant1.myapp.com → tenant_id = uuid1
|
||||
- [ ] tenant2.myapp.com → tenant_id = uuid2
|
||||
|
||||
- [ ] **Tenant signup flow**:
|
||||
- [ ] Create tenant record
|
||||
- [ ] Create owner user
|
||||
- [ ] Associate user with tenant
|
||||
- [ ] Generate invitation links
|
||||
|
||||
## Monitoring & Observability
|
||||
|
||||
- [ ] **Setup error tracking** (Sentry, Datadog)
|
||||
- [ ] **Add structured logging** (Pino for Node, structlog for Python)
|
||||
- [ ] **Setup metrics** (Prometheus, Datadog)
|
||||
- [ ] **Create health check endpoint** (`/health`)
|
||||
- [ ] **Setup uptime monitoring** (Pingdom, UptimeRobot)
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ ] **README.md** with setup instructions
|
||||
- [ ] **API documentation** (auto-generated with FastAPI `/docs`)
|
||||
- [ ] **Architecture diagram** (optional, but recommended)
|
||||
- [ ] **Environment variables** documented in .env.example
|
||||
- [ ] **Contributing guide** (if open-source or team project)
|
||||
|
||||
## Scoring
|
||||
|
||||
- **80+ items checked**: Excellent - Production-ready setup ✅
|
||||
- **60-79 items**: Good - Most setup complete ⚠️
|
||||
- **40-59 items**: Fair - Missing important pieces 🔴
|
||||
- **<40 items**: Poor - Not ready for development ❌
|
||||
|
||||
## Priority Items
|
||||
|
||||
Complete these first:
|
||||
1. **Repository setup** - Git, structure, README
|
||||
2. **Database schema** - Models, migrations
|
||||
3. **Authentication** - Better Auth, protected routes
|
||||
4. **Testing setup** - Vitest, pytest
|
||||
5. **CI/CD** - GitHub Actions, deployment
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
❌ **Don't:**
|
||||
- Commit .env files (use .env.example instead)
|
||||
- Skip testing setup (add it from day one)
|
||||
- Ignore linting (consistent code quality matters)
|
||||
- Deploy without health checks
|
||||
- Skip multi-tenant isolation (add tenant_id early)
|
||||
|
||||
✅ **Do:**
|
||||
- Use repository pattern for data access
|
||||
- Set up CI/CD early (automate testing)
|
||||
- Document environment variables
|
||||
- Test authentication thoroughly
|
||||
- Plan for scale (database indexes, caching)
|
||||
|
||||
## Related Resources
|
||||
|
||||
- [TanStack Start Documentation](https://tanstack.com/start)
|
||||
- [FastAPI Documentation](https://fastapi.tiangolo.com)
|
||||
- [Better Auth Documentation](https://better-auth.com)
|
||||
- [Drizzle ORM Documentation](https://orm.drizzle.team)
|
||||
- [project-scaffolding skill](../SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
**Total Items**: 130+ setup checks
|
||||
**Critical Items**: Repository, Database, Auth, Testing, Deployment
|
||||
**Coverage**: TanStack Start, FastAPI, Multi-tenant, Testing, CI/CD
|
||||
**Last Updated**: 2025-11-10
|
||||
@@ -0,0 +1,272 @@
|
||||
# Scaffold Quality Checklist
|
||||
|
||||
Comprehensive checklist for validating generated scaffolds before delivery.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Files
|
||||
|
||||
### TypeScript Projects
|
||||
|
||||
- [ ] **package.json** present with correct project name
|
||||
- [ ] **tsconfig.json** with strict mode enabled
|
||||
- [ ] **Scripts** configured (dev, build, test, deploy)
|
||||
- [ ] **Dependencies** at correct versions
|
||||
- [ ] **devDependencies** include linting/testing tools
|
||||
|
||||
### Python Projects
|
||||
|
||||
- [ ] **pyproject.toml** present with project metadata
|
||||
- [ ] **Dependencies** specified with version ranges
|
||||
- [ ] **Dev dependencies** include pytest, ruff, mypy
|
||||
- [ ] **Tool configurations** (ruff, mypy, pytest) configured
|
||||
|
||||
### All Projects
|
||||
|
||||
- [ ] **.gitignore** includes node_modules, .env, build artifacts
|
||||
- [ ] **.env.example** provided for environment variables
|
||||
- [ ] **README.md** with setup instructions
|
||||
- [ ] **License file** (if applicable)
|
||||
|
||||
---
|
||||
|
||||
## Source Code Structure
|
||||
|
||||
### Directory Organization
|
||||
|
||||
- [ ] **src/** directory exists
|
||||
- [ ] **routes/** for API endpoints or pages
|
||||
- [ ] **components/** for UI components (frontend)
|
||||
- [ ] **services/** for business logic
|
||||
- [ ] **utils/** for helper functions
|
||||
- [ ] **types/** for TypeScript definitions
|
||||
|
||||
### Entry Points
|
||||
|
||||
- [ ] **Main file** exists (index.ts, main.py, App.tsx)
|
||||
- [ ] **Exports** correctly configured
|
||||
- [ ] **Health check endpoint** implemented
|
||||
- [ ] **Error handling** middleware included
|
||||
|
||||
---
|
||||
|
||||
## Code Quality
|
||||
|
||||
### TypeScript
|
||||
|
||||
- [ ] **Strict mode** enabled in tsconfig.json
|
||||
- [ ] **Type annotations** on all functions
|
||||
- [ ] **Interfaces** defined for props/config
|
||||
- [ ] **ESLint** configuration present
|
||||
- [ ] **Prettier** configuration present
|
||||
- [ ] **No `any` types** (except explicit)
|
||||
|
||||
### Python
|
||||
|
||||
- [ ] **Type hints** on all functions
|
||||
- [ ] **Pydantic models** for validation
|
||||
- [ ] **Async/await** used correctly
|
||||
- [ ] **Docstrings** on public functions
|
||||
- [ ] **Ruff configuration** present
|
||||
- [ ] **mypy strict mode** enabled
|
||||
|
||||
### All Languages
|
||||
|
||||
- [ ] **Consistent naming** (camelCase, snake_case)
|
||||
- [ ] **No hard-coded secrets** or API keys
|
||||
- [ ] **Environment variables** used correctly
|
||||
- [ ] **Error handling** implemented
|
||||
- [ ] **Logging** configured
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Files
|
||||
|
||||
- [ ] **tests/** directory exists
|
||||
- [ ] **Test files** mirror src/ structure
|
||||
- [ ] **Test fixtures** configured (conftest.py, setup.ts)
|
||||
- [ ] **Coverage** configuration present
|
||||
|
||||
### Test Quality
|
||||
|
||||
- [ ] **Sample tests** included
|
||||
- [ ] **Tests pass** out of the box
|
||||
- [ ] **Health check test** present
|
||||
- [ ] **Test commands** in package.json/pyproject.toml
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### Cloudflare Workers
|
||||
|
||||
- [ ] **wrangler.toml** configured
|
||||
- [ ] **Database bindings** defined (if D1)
|
||||
- [ ] **Environment** sections (production, staging)
|
||||
- [ ] **Secrets** documented in README
|
||||
|
||||
### Cloudflare Pages
|
||||
|
||||
- [ ] **Build command** configured
|
||||
- [ ] **Output directory** specified
|
||||
- [ ] **Environment variables** documented
|
||||
|
||||
### Python
|
||||
|
||||
- [ ] **Dockerfile** (if containerized)
|
||||
- [ ] **Requirements** frozen
|
||||
- [ ] **Database migrations** configured (Alembic)
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
### README.md
|
||||
|
||||
- [ ] **Project description** clear
|
||||
- [ ] **Quick start** instructions
|
||||
- [ ] **Setup steps** documented
|
||||
- [ ] **Development** commands listed
|
||||
- [ ] **Deployment** instructions
|
||||
- [ ] **Environment variables** documented
|
||||
- [ ] **API endpoints** listed (if API)
|
||||
|
||||
### Additional Docs
|
||||
|
||||
- [ ] **Architecture** diagram/description (full-stack)
|
||||
- [ ] **API documentation** (FastAPI auto-docs, etc.)
|
||||
- [ ] **Contributing** guidelines (if open source)
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
### Secrets Management
|
||||
|
||||
- [ ] **No secrets** committed to git
|
||||
- [ ] **.env** in .gitignore
|
||||
- [ ] **.env.example** provided
|
||||
- [ ] **Secret management** documented
|
||||
|
||||
### Authentication
|
||||
|
||||
- [ ] **Auth middleware** included (if applicable)
|
||||
- [ ] **JWT handling** implemented correctly
|
||||
- [ ] **CORS** configured properly
|
||||
|
||||
### Input Validation
|
||||
|
||||
- [ ] **Zod/Pydantic** validation on inputs
|
||||
- [ ] **SQL injection** prevention (parameterized queries)
|
||||
- [ ] **XSS prevention** (sanitized outputs)
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Version Management
|
||||
|
||||
- [ ] **Package versions** pinned or ranged appropriately
|
||||
- [ ] **No deprecated** packages
|
||||
- [ ] **Security** vulnerabilities checked
|
||||
- [ ] **License** compatibility verified
|
||||
|
||||
### Peer Dependencies
|
||||
|
||||
- [ ] **React version** compatible (if React)
|
||||
- [ ] **Node version** specified (engines field)
|
||||
- [ ] **Python version** specified (requires-python)
|
||||
|
||||
---
|
||||
|
||||
## CI/CD
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
- [ ] **.github/workflows/** directory exists
|
||||
- [ ] **Test workflow** configured
|
||||
- [ ] **Deploy workflow** configured
|
||||
- [ ] **Lint workflow** configured
|
||||
|
||||
### Workflow Quality
|
||||
|
||||
- [ ] **Tests run** on PR
|
||||
- [ ] **Deployment** on main branch
|
||||
- [ ] **Secrets** properly configured
|
||||
- [ ] **Environment variables** set
|
||||
|
||||
---
|
||||
|
||||
## User Experience
|
||||
|
||||
### Developer Experience
|
||||
|
||||
- [ ] **Setup time** < 5 minutes
|
||||
- [ ] **All commands work** (dev, test, build)
|
||||
- [ ] **Hot reload** functional
|
||||
- [ ] **Error messages** helpful
|
||||
|
||||
### Production Readiness
|
||||
|
||||
- [ ] **Health endpoint** returns 200
|
||||
- [ ] **Error handling** doesn't expose internals
|
||||
- [ ] **Logging** configured
|
||||
- [ ] **Monitoring** hooks present
|
||||
|
||||
---
|
||||
|
||||
## Checklist Summary
|
||||
|
||||
### Must Have (Critical)
|
||||
|
||||
- ✅ Configuration files present and correct
|
||||
- ✅ Source code structure follows Grey Haven conventions
|
||||
- ✅ Tests included and passing
|
||||
- ✅ README with setup instructions
|
||||
- ✅ No secrets committed
|
||||
|
||||
### Should Have (Important)
|
||||
|
||||
- ✅ Type safety (TypeScript strict, Python type hints)
|
||||
- ✅ Linting and formatting configured
|
||||
- ✅ CI/CD pipeline included
|
||||
- ✅ Health check endpoint
|
||||
- ✅ Error handling
|
||||
|
||||
### Nice to Have (Optional)
|
||||
|
||||
- ✅ Architecture documentation
|
||||
- ✅ API documentation
|
||||
- ✅ Storybook (components)
|
||||
- ✅ Database migrations
|
||||
- ✅ Monitoring setup
|
||||
|
||||
---
|
||||
|
||||
## Quick Validation Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Quick scaffold validation
|
||||
|
||||
echo "Checking scaffold quality..."
|
||||
|
||||
# Check files exist
|
||||
test -f package.json && echo "✅ package.json" || echo "❌ package.json"
|
||||
test -f README.md && echo "✅ README.md" || echo "✅ README.md"
|
||||
test -d src && echo "✅ src/" || echo "❌ src/"
|
||||
test -d tests && echo "✅ tests/" || echo "❌ tests/"
|
||||
|
||||
# Check no secrets
|
||||
! grep -r "api[_-]key" . && echo "✅ No API keys" || echo "⚠️ API key found"
|
||||
|
||||
# Install and test
|
||||
npm install && npm test && echo "✅ Tests pass" || echo "❌ Tests fail"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Version**: 1.0
|
||||
**Last Updated**: 2024-01-15
|
||||
Reference in New Issue
Block a user