Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:29:07 +08:00
commit 8b4a1b1a99
75 changed files with 18583 additions and 0 deletions

View File

@@ -0,0 +1,203 @@
# Project Scaffolder Reference
Complete reference for Grey Haven project scaffolding - conventions, specifications, and tooling.
---
## Navigation
| Reference | Description |
|-----------|-------------|
| [Grey Haven Conventions](grey-haven-conventions.md) | Naming, structure, and code standards |
| [Scaffold Specifications](scaffold-specifications.md) | Technical specs for each scaffold type |
| [Tooling Configurations](tooling-configurations.md) | Config files for Vite, Wrangler, pytest, etc. |
---
## Quick Reference
### Grey Haven Stack
| Layer | Technology | Use Case |
|-------|------------|----------|
| **Frontend** | React + Vite + TanStack | Web applications |
| **Backend** | Cloudflare Workers + Hono | REST/GraphQL APIs |
| **Database** | PlanetScale PostgreSQL (or D1) | Relational data |
| **Validation** | Zod (TS), Pydantic (Python) | Type-safe validation |
| **Testing** | Vitest (TS), pytest (Python) | Unit & integration tests |
| **Deployment** | Cloudflare Pages + Workers | Global edge deployment |
### Naming Conventions
```
Components: PascalCase (Button, UserProfile)
Files: kebab-case (user-profile.tsx, api-client.ts)
Variables: camelCase (userId, isActive)
Constants: UPPER_SNAKE (API_URL, MAX_RETRIES)
Database: snake_case (user_profiles, api_keys)
Routes: kebab-case (/api/user-profiles)
```
### Folder Structure
```
src/
├── routes/ # API endpoints or page routes
├── components/ # Reusable UI components
├── services/ # Business logic
├── utils/ # Pure helper functions
├── types/ # TypeScript type definitions
└── lib/ # Third-party integrations
tests/ # Mirror src/ structure
├── routes/
├── components/
└── services/
```
### Configuration Standards
**TypeScript Projects**:
- Strict mode enabled
- ESLint with recommended rules
- Prettier for formatting
- Vitest for testing
- Path aliases (`@/` for src/)
**Python Projects**:
- Python 3.11+
- uv for package management
- Ruff for linting
- mypy for type checking
- pytest for testing
---
## Scaffold Templates
### Minimum Files Required
**Cloudflare Worker**:
- wrangler.toml
- package.json
- tsconfig.json
- src/index.ts
- tests/
**React App**:
- package.json
- vite.config.ts
- tsconfig.json
- src/main.tsx
- src/routes/
- tests/
**Python API**:
- pyproject.toml
- app/main.py
- app/schemas/
- app/models/
- tests/
---
## Tooling Versions
### Recommended Versions (2024)
```json
{
"typescript": "^5.3.0",
"vite": "^5.0.0",
"react": "^18.2.0",
"hono": "^4.0.0",
"wrangler": "^3.25.0",
"vitest": "^1.2.0"
}
```
```toml
# Python (pyproject.toml)
[project]
requires-python = ">=3.11"
dependencies = [
"fastapi[standard]>=0.109.0",
"pydantic>=2.5.0",
"uvicorn>=0.27.0"
]
```
---
## Best Practices
### DO
- ✅ Use TypeScript strict mode
- ✅ Include tests in scaffold
- ✅ Configure linting and formatting
- ✅ Add .gitignore
- ✅ Include README with setup instructions
- ✅ Add CI/CD configuration
- ✅ Use environment variables for secrets
- ✅ Include health check endpoint
### DON'T
- ❌ Commit node_modules or .venv
- ❌ Hard-code secrets or API keys
- ❌ Skip type definitions
- ❌ Omit error handling
- ❌ Forget database migrations
- ❌ Skip documentation
---
## Deployment Checklist
### Pre-Deployment
- [ ] All tests passing
- [ ] TypeScript/mypy checks pass
- [ ] Linting passes
- [ ] Environment variables configured
- [ ] Database migrations applied
- [ ] Secrets set in production
- [ ] Build succeeds
- [ ] Health check endpoint working
### Post-Deployment
- [ ] Health check returns 200
- [ ] API endpoints accessible
- [ ] Database connections working
- [ ] Authentication functioning
- [ ] Monitoring enabled
- [ ] Error tracking active
- [ ] Logs accessible
---
## Common Issues
### Issue: TypeScript errors after scaffold
**Solution**: Run `npm install` and ensure tsconfig.json is correct
### Issue: Wrangler fails to deploy
**Solution**: Check wrangler.toml config and Cloudflare authentication
### Issue: Database connection fails
**Solution**: Verify connection string and database credentials
### Issue: Tests fail after scaffold
**Solution**: Check test setup and mock configuration
---
**Total References**: 3 comprehensive guides
**Coverage**: Conventions, specifications, configurations
**Standards**: Production-ready Grey Haven stack

View File

@@ -0,0 +1,373 @@
# Grey Haven Conventions
Complete style guide for Grey Haven projects - naming, structure, patterns, and standards.
---
## Naming Conventions
### Code Elements
| Element | Convention | Examples |
|---------|------------|----------|
| **Components** | PascalCase | `Button`, `UserProfile`, `DataTable` |
| **Functions** | camelCase | `getUserById`, `calculateTotal` |
| **Variables** | camelCase | `userId`, `isActive`, `firstName` |
| **Constants** | UPPER_SNAKE_CASE | `API_URL`, `MAX_RETRIES`, `DEFAULT_TIMEOUT` |
| **Types/Interfaces** | PascalCase | `User`, `ApiResponse`, `Config` |
| **Enums** | PascalCase | `Status`, `UserRole`, `HttpMethod` |
### Files and Directories
| Type | Convention | Examples |
|------|------------|----------|
| **Components** | PascalCase | `Button.tsx`, `UserProfile.tsx` |
| **Routes** | kebab-case | `user-profile.tsx`, `api-client.ts` |
| **Utilities** | kebab-case | `string-utils.ts`, `date-helpers.ts` |
| **Tests** | Match source + `.test` | `Button.test.tsx`, `api-client.test.ts` |
| **Stories** | Match source + `.stories` | `Button.stories.tsx` |
| **Directories** | kebab-case | `user-management/`, `api-routes/` |
### Database Schema
```sql
-- Tables: snake_case (plural)
CREATE TABLE user_profiles (...);
CREATE TABLE api_keys (...);
-- Columns: snake_case
user_id, first_name, created_at
-- Indexes: table_column_idx
CREATE INDEX user_profiles_email_idx ON user_profiles(email);
-- Foreign keys: table_column_fkey
FOREIGN KEY (user_id) REFERENCES users(id)
```
### API Endpoints
```
GET /api/users # List (plural)
GET /api/users/:id # Get single
POST /api/users # Create
PUT /api/users/:id # Update
DELETE /api/users/:id # Delete
GET /api/user-profiles # kebab-case for multi-word
POST /api/auth/login # Nested resources
```
---
## Project Structure
### Frontend (React + Vite)
```
frontend/
├── src/
│ ├── main.tsx # Entry point
│ ├── App.tsx # Root component
│ ├── routes/ # TanStack Router routes
│ │ ├── index.tsx # Home route
│ │ ├── users/
│ │ │ ├── index.tsx # /users
│ │ │ └── $id.tsx # /users/:id
│ │ └── __root.tsx # Root layout
│ ├── components/ # Reusable components
│ │ ├── ui/ # Generic UI (Button, Input)
│ │ ├── forms/ # Form components
│ │ └── layout/ # Layout components
│ ├── services/ # API clients, integrations
│ │ ├── api.ts # API client
│ │ └── auth.ts # Auth service
│ ├── lib/ # Third-party setup
│ │ ├── query-client.ts # TanStack Query config
│ │ └── router.ts # Router config
│ ├── utils/ # Pure utility functions
│ │ ├── string-utils.ts
│ │ └── date-utils.ts
│ ├── types/ # TypeScript types
│ │ ├── api.ts # API types
│ │ └── models.ts # Domain models
│ └── assets/ # Static assets
│ ├── images/
│ └── styles/
├── tests/ # Mirror src/ structure
│ ├── routes/
│ ├── components/
│ └── services/
├── public/ # Static files (favicon, etc.)
├── package.json
├── vite.config.ts
├── tsconfig.json
└── .env.example
```
### Backend (Cloudflare Worker)
```
backend/
├── src/
│ ├── index.ts # Entry point
│ ├── routes/ # API route handlers
│ │ ├── health.ts # Health check
│ │ ├── users.ts # User routes
│ │ └── auth.ts # Auth routes
│ ├── middleware/ # Request middleware
│ │ ├── auth.ts # Authentication
│ │ ├── cors.ts # CORS config
│ │ ├── logger.ts # Logging
│ │ └── error-handler.ts # Error handling
│ ├── services/ # Business logic
│ │ ├── user-service.ts
│ │ └── auth-service.ts
│ ├── utils/ # Helper functions
│ │ ├── db.ts # Database helpers
│ │ └── jwt.ts # JWT utilities
│ └── types/ # TypeScript types
│ └── environment.d.ts # Env types
├── tests/ # Mirror src/
├── wrangler.toml # Cloudflare config
├── package.json
└── tsconfig.json
```
### Python API (FastAPI)
```
backend/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app
│ ├── config.py # Configuration
│ ├── dependencies.py # Dependency injection
│ ├── api/ # API routes
│ │ ├── __init__.py
│ │ ├── health.py
│ │ └── users.py
│ ├── models/ # SQLAlchemy models
│ │ ├── __init__.py
│ │ └── user.py
│ ├── schemas/ # Pydantic schemas
│ │ ├── __init__.py
│ │ └── user.py
│ ├── services/ # Business logic
│ │ ├── __init__.py
│ │ └── user_service.py
│ └── db/ # Database
│ ├── __init__.py
│ ├── base.py
│ └── session.py
├── tests/ # Mirror app/
├── alembic/ # Migrations
├── pyproject.toml # uv config
└── .env.example
```
---
## Code Style
### TypeScript
```typescript
// Imports: grouped and sorted
import { useState, useEffect } from 'react'; // React
import { useQuery } from '@tanstack/react-query'; // Third-party
import { Button } from '@/components/ui/Button'; // Internal
import type { User } from '@/types/models'; // Types
// Interfaces: PascalCase, descriptive
export interface UserProfileProps {
userId: string;
onUpdate?: (user: User) => void;
}
// Components: PascalCase, typed props
export const UserProfile: React.FC<UserProfileProps> = ({ userId, onUpdate }) => {
// Hooks first
const { data: user, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: () => api.users.get(userId),
});
// Early returns
if (isLoading) return <div>Loading...</div>;
if (!user) return <div>User not found</div>;
// JSX
return (
<div>
<h1>{user.name}</h1>
<Button onClick={() => onUpdate?.(user)}>Update</Button>
</div>
);
};
```
### Python
```python
# Imports: grouped and sorted
from datetime import datetime # Standard library
from uuid import UUID
from fastapi import APIRouter, Depends # Third-party
from pydantic import BaseModel, EmailStr
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.session import get_db # Internal
from app.services.user_service import UserService
# Type hints: Always use
router = APIRouter()
# Functions: snake_case, typed
@router.get("/users/{user_id}")
async def get_user(
user_id: UUID,
db: AsyncSession = Depends(get_db),
) -> dict:
"""Get user by ID.
Args:
user_id: User UUID
db: Database session
Returns:
User data dictionary
Raises:
HTTPException: If user not found
"""
service = UserService(db)
user = await service.get_user(user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user.model_dump()
```
---
## Testing Conventions
### Test File Organization
```
tests/
├── unit/ # Unit tests (isolated)
│ ├── components/
│ ├── services/
│ └── utils/
├── integration/ # Integration tests
│ ├── api/
│ └── database/
└── e2e/ # End-to-end tests
└── user-flow.test.ts
```
### Test Naming
```typescript
// Describe: Component/function name
describe('Button', () => {
// It: Should + behavior
it('should render with label', () => {
render(<Button label="Click me" />);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('should call onClick when clicked', () => {
const handleClick = vi.fn();
render(<Button label="Click" onClick={handleClick} />);
fireEvent.click(screen.getByText('Click'));
expect(handleClick).toHaveBeenCalledOnce();
});
});
```
```python
# Class: Test + ClassName
class TestUserService:
"""Test suite for UserService."""
# Method: test_ + behavior
async def test_get_user_returns_user_when_exists(self, db_session):
"""Should return user when user exists."""
service = UserService(db_session)
user = await service.get_user(user_id)
assert user is not None
assert user.email == "test@example.com"
async def test_get_user_returns_none_when_not_exists(self, db_session):
"""Should return None when user doesn't exist."""
service = UserService(db_session)
user = await service.get_user(UUID4())
assert user is None
```
---
## Git Conventions
### Branch Naming
```
feature/user-authentication # New feature
fix/login-button-crash # Bug fix
refactor/api-client # Code refactoring
docs/api-documentation # Documentation
chore/update-dependencies # Maintenance
```
### Commit Messages
```
feat: add user authentication system
fix: resolve login button crash on mobile
refactor: extract API client into separate module
docs: add API endpoint documentation
chore: update dependencies to latest versions
# Format: type: description (lowercase, no period)
# Types: feat, fix, refactor, docs, chore, test, style
```
---
## Environment Variables
### Naming
```bash
# Format: UPPER_SNAKE_CASE with prefix
DATABASE_URL=postgresql://...
API_URL=https://api.example.com
JWT_SECRET=...
# Cloudflare-specific
CLOUDFLARE_API_TOKEN=...
CLOUDFLARE_ACCOUNT_ID=...
# Feature flags
FEATURE_NEW_UI=true
```
### Management
- Use `.env.example` for template
- Never commit `.env` files
- Use Wrangler secrets for Cloudflare
- Use environment-specific configs
---
**Version**: 1.0
**Last Updated**: 2024-01-15

View File

@@ -0,0 +1,138 @@
# Scaffold Specifications
Technical specifications for each Grey Haven scaffold type.
---
## Cloudflare Worker API Specification
**Purpose**: Production REST/GraphQL API on Cloudflare edge network
**Minimum Files** (18):
- wrangler.toml, package.json, tsconfig.json
- src/index.ts (entry), routes/ (3 files), middleware/ (4 files)
- services/ (2 files), types/ (1 file), utils/ (1 file)
- tests/ (3 files), .github/workflows/, README.md
**Dependencies**:
```json
{
"dependencies": {
"hono": "^4.0.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240117.0",
"typescript": "^5.3.3",
"vitest": "^1.2.0",
"wrangler": "^3.25.0"
}
}
```
**Features**:
- Hono framework
- D1 database binding
- JWT authentication middleware
- CORS configuration
- Request logging
- Error handling
- Health check endpoint
- Vitest tests
---
## React Component Specification
**Purpose**: Reusable UI component with tests and stories
**Minimum Files** (6):
- Component.tsx, Component.test.tsx, Component.stories.tsx
- Component.module.css, index.ts, README.md
**Dependencies**:
```json
{
"devDependencies": {
"@testing-library/react": "^14.1.0",
"@testing-library/user-event": "^14.5.0",
"@storybook/react-vite": "^7.6.0",
"vitest": "^1.2.0"
}
}
```
**Features**:
- TypeScript prop types
- CSS modules styling
- Vitest + Testing Library tests
- Storybook stories
- Accessible markup
- JSDoc documentation
---
## Python API Specification
**Purpose**: Production-ready FastAPI with async PostgreSQL
**Minimum Files** (22):
- pyproject.toml, alembic.ini, .env.example
- app/main.py, config.py, dependencies.py
- app/api/ (3 files), models/ (2 files), schemas/ (2 files)
- app/services/ (2 files), db/ (3 files)
- tests/ (4 files), alembic/versions/, README.md
**Dependencies**:
```toml
[project]
dependencies = [
"fastapi[standard]>=0.109.0",
"pydantic>=2.5.0",
"sqlalchemy[asyncio]>=2.0.25",
"alembic>=1.13.0",
"asyncpg>=0.29.0",
]
```
**Features**:
- FastAPI with async
- Pydantic v2 validation
- SQLAlchemy 2.0 async
- Alembic migrations
- pytest with asyncio
- uv package manager
- Ruff linting
- mypy type checking
---
## Full-Stack Specification
**Purpose**: Complete monorepo with frontend and backend
**Minimum Files** (35):
- package.json (root), pnpm-workspace.yaml
- frontend/ (15 files), backend/ (12 files)
- packages/types/ (4 files), docs/ (4 files)
**Structure**:
```
my-app/
├── frontend/ # React + Vite + TanStack
├── backend/ # Cloudflare Worker + D1
├── packages/ # Shared TypeScript types
└── docs/ # Architecture docs
```
**Features**:
- pnpm workspaces
- Shared types package
- TanStack Router + Query
- Cloudflare deployment
- CI/CD pipeline
- Monorepo scripts
---
**Total Specs**: 4 scaffold types
**Coverage**: Frontend, backend, component, full-stack