8 tasks covering: root workspace files, shared TypeScript config, shared ESLint config, placeholder packages, placeholder apps, Docker Compose, dependency installation + verification, test dirs.
966 lines
22 KiB
Markdown
966 lines
22 KiB
Markdown
# Plan 1: Monorepo Foundation — Implementation Plan
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** Scaffold a Turborepo + pnpm monorepo with shared TypeScript and ESLint configs, placeholder packages for all planned workspaces, and Docker Compose for local development.
|
|
|
|
**Architecture:** Turborepo orchestrates builds across pnpm workspaces. Shared config packages (`@repo/typescript-config`, `@repo/eslint-config`) provide consistent tooling. All apps and packages are created as empty placeholders with correct `package.json` files so the workspace graph is valid from the start. Docker Compose provides PostgreSQL for local development.
|
|
|
|
**Tech Stack:** Turborepo 2.x, pnpm 9.x, TypeScript 5.x, ESLint 9.x (flat config), Vitest, Docker Compose, PostgreSQL 16
|
|
|
|
---
|
|
|
|
## File Map
|
|
|
|
| File | Responsibility |
|
|
|---|---|
|
|
| `package.json` | Root workspace manifest, delegates to turbo |
|
|
| `pnpm-workspace.yaml` | Declares workspace packages |
|
|
| `turbo.json` | Task pipeline (build, dev, lint, test, typecheck) |
|
|
| `.npmrc` | pnpm workspace settings |
|
|
| `.gitignore` | Ignore patterns for Turborepo + pnpm + Node.js |
|
|
| `packages/typescript-config/package.json` | Shared TS config package manifest |
|
|
| `packages/typescript-config/base.json` | Base TypeScript config |
|
|
| `packages/typescript-config/nextjs.json` | Next.js TypeScript config |
|
|
| `packages/typescript-config/react-library.json` | React library TypeScript config |
|
|
| `packages/eslint-config/package.json` | Shared ESLint config package manifest |
|
|
| `packages/eslint-config/base.js` | Base ESLint flat config |
|
|
| `packages/eslint-config/next.js` | Next.js ESLint config |
|
|
| `packages/eslint-config/react-internal.js` | React library ESLint config |
|
|
| `packages/core/package.json` | Placeholder — clean architecture core |
|
|
| `packages/core/tsconfig.json` | Extends @repo/typescript-config/base |
|
|
| `packages/api/package.json` | Placeholder — tRPC routers |
|
|
| `packages/api/tsconfig.json` | Extends @repo/typescript-config/base |
|
|
| `packages/api-client/package.json` | Placeholder — React Query hooks |
|
|
| `packages/api-client/tsconfig.json` | Extends @repo/typescript-config/react-library |
|
|
| `packages/cms-core/package.json` | Placeholder — Payload CMS definition |
|
|
| `packages/cms-core/tsconfig.json` | Extends @repo/typescript-config/base |
|
|
| `packages/cms-client/package.json` | Placeholder — Dual-mode Payload client |
|
|
| `packages/cms-client/tsconfig.json` | Extends @repo/typescript-config/base |
|
|
| `packages/ui/package.json` | Placeholder — shadcn/ui + Atomic Design |
|
|
| `packages/ui/tsconfig.json` | Extends @repo/typescript-config/react-library |
|
|
| `apps/web-next/package.json` | Placeholder — Next.js reference app |
|
|
| `apps/web-next/tsconfig.json` | Extends @repo/typescript-config/nextjs |
|
|
| `apps/web-tanstack/package.json` | Placeholder — TanStack Start reference app |
|
|
| `apps/web-tanstack/tsconfig.json` | Extends @repo/typescript-config/base |
|
|
| `apps/cms/package.json` | Placeholder — Payload admin shell |
|
|
| `apps/cms/tsconfig.json` | Extends @repo/typescript-config/nextjs |
|
|
| `apps/storybook/package.json` | Placeholder — Storybook instance |
|
|
| `apps/storybook/tsconfig.json` | Extends @repo/typescript-config/react-library |
|
|
| `docker-compose.yml` | PostgreSQL service for local dev |
|
|
| `.env.example` | Environment variable template |
|
|
|
|
---
|
|
|
|
### Task 1: Root workspace files
|
|
|
|
**Files:**
|
|
- Create: `package.json`
|
|
- Create: `pnpm-workspace.yaml`
|
|
- Create: `turbo.json`
|
|
- Create: `.npmrc`
|
|
- Create: `.gitignore`
|
|
- Create: `.env.example`
|
|
|
|
- [ ] **Step 1: Create root package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "template",
|
|
"private": true,
|
|
"packageManager": "pnpm@9.15.4",
|
|
"engines": {
|
|
"node": ">=20"
|
|
},
|
|
"scripts": {
|
|
"build": "turbo run build",
|
|
"dev": "turbo run dev",
|
|
"lint": "turbo run lint",
|
|
"test": "turbo run test",
|
|
"typecheck": "turbo run typecheck",
|
|
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\""
|
|
},
|
|
"devDependencies": {
|
|
"prettier": "^3.5.0",
|
|
"turbo": "^2.4.0",
|
|
"typescript": "^5.8.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 2: Create pnpm-workspace.yaml**
|
|
|
|
```yaml
|
|
packages:
|
|
- "apps/*"
|
|
- "packages/*"
|
|
```
|
|
|
|
- [ ] **Step 3: Create turbo.json**
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://turborepo.dev/schema.json",
|
|
"tasks": {
|
|
"build": {
|
|
"dependsOn": ["^build"],
|
|
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
|
|
},
|
|
"dev": {
|
|
"cache": false,
|
|
"persistent": true
|
|
},
|
|
"lint": {
|
|
"dependsOn": ["^lint"]
|
|
},
|
|
"test": {
|
|
"dependsOn": ["^build"]
|
|
},
|
|
"typecheck": {
|
|
"dependsOn": ["^typecheck"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 4: Create .npmrc**
|
|
|
|
```
|
|
auto-install-peers=true
|
|
enable-pre-post-scripts=true
|
|
```
|
|
|
|
- [ ] **Step 5: Create .gitignore**
|
|
|
|
```
|
|
# Dependencies
|
|
node_modules
|
|
|
|
# Turbo
|
|
.turbo
|
|
|
|
# Build outputs
|
|
dist
|
|
build
|
|
.next
|
|
out
|
|
storybook-static
|
|
|
|
# Environment
|
|
.env
|
|
.env.local
|
|
.env.*.local
|
|
|
|
# Testing
|
|
coverage
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# IDE
|
|
.vscode
|
|
.idea
|
|
*.swp
|
|
|
|
# Debug
|
|
npm-debug.log*
|
|
pnpm-debug.log*
|
|
|
|
# Superpowers brainstorm sessions
|
|
.superpowers/
|
|
```
|
|
|
|
- [ ] **Step 6: Create .env.example**
|
|
|
|
```
|
|
# Database
|
|
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/template
|
|
|
|
# Payload CMS
|
|
PAYLOAD_SECRET=your-secret-here
|
|
|
|
# App URLs
|
|
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
CMS_URL=http://localhost:3001
|
|
```
|
|
|
|
- [ ] **Step 7: Commit**
|
|
|
|
```bash
|
|
git add package.json pnpm-workspace.yaml turbo.json .npmrc .gitignore .env.example
|
|
git commit -m "feat: scaffold root workspace files (Turborepo + pnpm)"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 2: Shared TypeScript config package
|
|
|
|
**Files:**
|
|
- Create: `packages/typescript-config/package.json`
|
|
- Create: `packages/typescript-config/base.json`
|
|
- Create: `packages/typescript-config/nextjs.json`
|
|
- Create: `packages/typescript-config/react-library.json`
|
|
|
|
- [ ] **Step 1: Create package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/typescript-config",
|
|
"private": true,
|
|
"version": "0.0.0"
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 2: Create base.json**
|
|
|
|
This is the base TypeScript config used by all packages. Includes `experimentalDecorators` and `emitDecoratorMetadata` required by InversifyJS.
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://json.schemastore.org/tsconfig",
|
|
"compilerOptions": {
|
|
"target": "ES2022",
|
|
"lib": ["ES2022"],
|
|
"module": "ESNext",
|
|
"moduleResolution": "bundler",
|
|
"strict": true,
|
|
"declaration": true,
|
|
"declarationMap": true,
|
|
"isolatedModules": true,
|
|
"esModuleInterop": true,
|
|
"resolveJsonModule": true,
|
|
"skipLibCheck": true,
|
|
"forceConsistentCasingInFileNames": true,
|
|
"noUncheckedIndexedAccess": true,
|
|
"experimentalDecorators": true,
|
|
"emitDecoratorMetadata": true
|
|
},
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 3: Create nextjs.json**
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://json.schemastore.org/tsconfig",
|
|
"extends": "./base.json",
|
|
"compilerOptions": {
|
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
"jsx": "preserve",
|
|
"module": "ESNext",
|
|
"moduleResolution": "bundler",
|
|
"noEmit": true,
|
|
"incremental": true,
|
|
"plugins": [{ "name": "next" }]
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 4: Create react-library.json**
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://json.schemastore.org/tsconfig",
|
|
"extends": "./base.json",
|
|
"compilerOptions": {
|
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
"jsx": "react-jsx"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add packages/typescript-config/
|
|
git commit -m "feat: add shared TypeScript config package (@repo/typescript-config)"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 3: Shared ESLint config package
|
|
|
|
**Files:**
|
|
- Create: `packages/eslint-config/package.json`
|
|
- Create: `packages/eslint-config/base.js`
|
|
- Create: `packages/eslint-config/next.js`
|
|
- Create: `packages/eslint-config/react-internal.js`
|
|
|
|
- [ ] **Step 1: Create package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/eslint-config",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"exports": {
|
|
"./base": "./base.js",
|
|
"./next": "./next.js",
|
|
"./react-internal": "./react-internal.js"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/js": "^9.20.0",
|
|
"@typescript-eslint/eslint-plugin": "^8.25.0",
|
|
"@typescript-eslint/parser": "^8.25.0",
|
|
"eslint": "^9.20.0",
|
|
"eslint-config-prettier": "^10.1.0",
|
|
"eslint-plugin-turbo": "^2.4.0",
|
|
"typescript-eslint": "^8.25.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 2: Create base.js**
|
|
|
|
```javascript
|
|
import js from "@eslint/js";
|
|
import eslintConfigPrettier from "eslint-config-prettier";
|
|
import tseslint from "typescript-eslint";
|
|
import turboPlugin from "eslint-plugin-turbo";
|
|
|
|
export default [
|
|
{ ignores: ["dist/**", "node_modules/**"] },
|
|
js.configs.recommended,
|
|
...tseslint.configs.recommended,
|
|
eslintConfigPrettier,
|
|
{
|
|
plugins: { turbo: turboPlugin },
|
|
rules: {
|
|
"turbo/no-undeclared-env-vars": "warn",
|
|
},
|
|
},
|
|
];
|
|
```
|
|
|
|
- [ ] **Step 3: Create next.js**
|
|
|
|
```javascript
|
|
import baseConfig from "./base.js";
|
|
|
|
export default [
|
|
...baseConfig,
|
|
{ ignores: [".next/**", "out/**"] },
|
|
];
|
|
```
|
|
|
|
- [ ] **Step 4: Create react-internal.js**
|
|
|
|
```javascript
|
|
import baseConfig from "./base.js";
|
|
|
|
export default [...baseConfig];
|
|
```
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add packages/eslint-config/
|
|
git commit -m "feat: add shared ESLint config package (@repo/eslint-config)"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 4: Placeholder packages (core, api, api-client, cms-core, cms-client, ui)
|
|
|
|
**Files:**
|
|
- Create: `packages/core/package.json`
|
|
- Create: `packages/core/tsconfig.json`
|
|
- Create: `packages/core/src/index.ts`
|
|
- Create: `packages/api/package.json`
|
|
- Create: `packages/api/tsconfig.json`
|
|
- Create: `packages/api/src/index.ts`
|
|
- Create: `packages/api-client/package.json`
|
|
- Create: `packages/api-client/tsconfig.json`
|
|
- Create: `packages/api-client/src/index.ts`
|
|
- Create: `packages/cms-core/package.json`
|
|
- Create: `packages/cms-core/tsconfig.json`
|
|
- Create: `packages/cms-core/src/index.ts`
|
|
- Create: `packages/cms-client/package.json`
|
|
- Create: `packages/cms-client/tsconfig.json`
|
|
- Create: `packages/cms-client/src/index.ts`
|
|
- Create: `packages/ui/package.json`
|
|
- Create: `packages/ui/tsconfig.json`
|
|
- Create: `packages/ui/src/index.ts`
|
|
|
|
- [ ] **Step 1: Create packages/core/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/core",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"lint": "eslint .",
|
|
"test": "vitest run",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 2: Create packages/core/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/base.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
},
|
|
"types": ["reflect-metadata"]
|
|
},
|
|
"include": ["src/**/*.ts"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 3: Create packages/core/src/index.ts**
|
|
|
|
```typescript
|
|
// @repo/core — Clean Architecture core package
|
|
// Layers: entities, application, infrastructure, interface-adapters, di
|
|
export {};
|
|
```
|
|
|
|
- [ ] **Step 4: Create packages/api/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/api",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 5: Create packages/api/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/base.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 6: Create packages/api/src/index.ts**
|
|
|
|
```typescript
|
|
// @repo/api — tRPC router definitions
|
|
export {};
|
|
```
|
|
|
|
- [ ] **Step 7: Create packages/api-client/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/api-client",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 8: Create packages/api-client/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/react-library.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 9: Create packages/api-client/src/index.ts**
|
|
|
|
```typescript
|
|
// @repo/api-client — Shared React Query hooks
|
|
export {};
|
|
```
|
|
|
|
- [ ] **Step 10: Create packages/cms-core/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/cms-core",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 11: Create packages/cms-core/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/base.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 12: Create packages/cms-core/src/index.ts**
|
|
|
|
```typescript
|
|
// @repo/cms-core — Payload CMS config, collections, hooks, globals
|
|
export {};
|
|
```
|
|
|
|
- [ ] **Step 13: Create packages/cms-client/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/cms-client",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 14: Create packages/cms-client/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/base.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 15: Create packages/cms-client/src/index.ts**
|
|
|
|
```typescript
|
|
// @repo/cms-client — Dual-mode Payload client (local + HTTP)
|
|
export {};
|
|
```
|
|
|
|
- [ ] **Step 16: Create packages/ui/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/ui",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"lint": "eslint .",
|
|
"test": "vitest run",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 17: Create packages/ui/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/react-library.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
"exclude": ["node_modules", "dist"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 18: Create packages/ui/src/index.ts**
|
|
|
|
```typescript
|
|
// @repo/ui — shadcn/ui + Atomic Design component library
|
|
export {};
|
|
```
|
|
|
|
- [ ] **Step 19: Commit**
|
|
|
|
```bash
|
|
git add packages/core/ packages/api/ packages/api-client/ packages/cms-core/ packages/cms-client/ packages/ui/
|
|
git commit -m "feat: add placeholder packages (core, api, api-client, cms-core, cms-client, ui)"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 5: Placeholder apps (web-next, web-tanstack, cms, storybook)
|
|
|
|
**Files:**
|
|
- Create: `apps/web-next/package.json`
|
|
- Create: `apps/web-next/tsconfig.json`
|
|
- Create: `apps/web-tanstack/package.json`
|
|
- Create: `apps/web-tanstack/tsconfig.json`
|
|
- Create: `apps/cms/package.json`
|
|
- Create: `apps/cms/tsconfig.json`
|
|
- Create: `apps/storybook/package.json`
|
|
- Create: `apps/storybook/tsconfig.json`
|
|
|
|
- [ ] **Step 1: Create apps/web-next/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/web-next",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"scripts": {
|
|
"build": "echo 'placeholder'",
|
|
"dev": "echo 'placeholder'",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"@repo/api-client": "workspace:*",
|
|
"@repo/ui": "workspace:*"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 2: Create apps/web-next/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/nextjs.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts", "src/**/*.tsx", "next-env.d.ts"],
|
|
"exclude": ["node_modules"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 3: Create apps/web-tanstack/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/web-tanstack",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"scripts": {
|
|
"build": "echo 'placeholder'",
|
|
"dev": "echo 'placeholder'",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"@repo/api-client": "workspace:*",
|
|
"@repo/ui": "workspace:*"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 4: Create apps/web-tanstack/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/base.json",
|
|
"compilerOptions": {
|
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
"jsx": "react-jsx",
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
"exclude": ["node_modules"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 5: Create apps/cms/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/cms",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"scripts": {
|
|
"build": "echo 'placeholder'",
|
|
"dev": "echo 'placeholder'",
|
|
"lint": "eslint .",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"@repo/cms-core": "workspace:*"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 6: Create apps/cms/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/nextjs.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts", "src/**/*.tsx", "next-env.d.ts"],
|
|
"exclude": ["node_modules"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 7: Create apps/storybook/package.json**
|
|
|
|
```json
|
|
{
|
|
"name": "@repo/storybook",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"scripts": {
|
|
"build": "echo 'placeholder'",
|
|
"dev": "echo 'placeholder'",
|
|
"lint": "eslint ."
|
|
},
|
|
"dependencies": {
|
|
"@repo/ui": "workspace:*"
|
|
},
|
|
"devDependencies": {
|
|
"@repo/eslint-config": "workspace:*",
|
|
"@repo/typescript-config": "workspace:*"
|
|
}
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 8: Create apps/storybook/tsconfig.json**
|
|
|
|
```json
|
|
{
|
|
"extends": "@repo/typescript-config/react-library.json",
|
|
"compilerOptions": {
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"]
|
|
}
|
|
},
|
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
"exclude": ["node_modules"]
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 9: Commit**
|
|
|
|
```bash
|
|
git add apps/
|
|
git commit -m "feat: add placeholder apps (web-next, web-tanstack, cms, storybook)"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 6: Docker Compose
|
|
|
|
**Files:**
|
|
- Create: `docker-compose.yml`
|
|
|
|
- [ ] **Step 1: Create docker-compose.yml**
|
|
|
|
```yaml
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
restart: unless-stopped
|
|
ports:
|
|
- "5432:5432"
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: template
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
volumes:
|
|
postgres_data:
|
|
```
|
|
|
|
- [ ] **Step 2: Commit**
|
|
|
|
```bash
|
|
git add docker-compose.yml
|
|
git commit -m "feat: add Docker Compose with PostgreSQL for local dev"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 7: Install dependencies and verify workspace
|
|
|
|
- [ ] **Step 1: Install pnpm if not available**
|
|
|
|
Run: `corepack enable && corepack prepare pnpm@9.15.4 --activate`
|
|
Expected: pnpm is available
|
|
|
|
- [ ] **Step 2: Run pnpm install**
|
|
|
|
Run: `pnpm install`
|
|
Expected: Installs all workspace dependencies, creates `pnpm-lock.yaml`, no errors.
|
|
|
|
- [ ] **Step 3: Verify Turborepo sees all workspaces**
|
|
|
|
Run: `pnpm turbo run build --dry`
|
|
Expected: Output lists all 10 packages/apps:
|
|
- `@repo/typescript-config`
|
|
- `@repo/eslint-config`
|
|
- `@repo/core`
|
|
- `@repo/api`
|
|
- `@repo/api-client`
|
|
- `@repo/cms-core`
|
|
- `@repo/cms-client`
|
|
- `@repo/ui`
|
|
- `@repo/web-next`
|
|
- `@repo/web-tanstack`
|
|
- `@repo/cms`
|
|
- `@repo/storybook`
|
|
|
|
- [ ] **Step 4: Run turbo build**
|
|
|
|
Run: `pnpm build`
|
|
Expected: All workspaces build successfully (placeholder builds echo 'placeholder' or tsc --noEmit with no errors on empty src/index.ts).
|
|
|
|
- [ ] **Step 5: Verify Docker Compose**
|
|
|
|
Run: `docker compose up -d postgres && docker compose ps`
|
|
Expected: PostgreSQL container running, healthy.
|
|
|
|
Run: `docker compose down`
|
|
Expected: Clean shutdown.
|
|
|
|
- [ ] **Step 6: Commit lockfile**
|
|
|
|
```bash
|
|
git add pnpm-lock.yaml
|
|
git commit -m "chore: add pnpm lockfile"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 8: Create test directory structure
|
|
|
|
**Files:**
|
|
- Create: `tests/unit/.gitkeep`
|
|
- Create: `tests/integration/.gitkeep`
|
|
- Create: `tests/e2e/.gitkeep`
|
|
|
|
- [ ] **Step 1: Create test directories**
|
|
|
|
```bash
|
|
mkdir -p tests/unit tests/integration tests/e2e
|
|
touch tests/unit/.gitkeep tests/integration/.gitkeep tests/e2e/.gitkeep
|
|
```
|
|
|
|
- [ ] **Step 2: Commit**
|
|
|
|
```bash
|
|
git add tests/
|
|
git commit -m "feat: add test directory structure (unit, integration, e2e)"
|
|
```
|