create-pnpm-custom-app 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +217 -0
  2. package/bin/cli.js +185 -0
  3. package/package.json +39 -0
  4. package/templates/.github/copilot-instructions.md +184 -0
  5. package/templates/.nvmrc +1 -0
  6. package/templates/.vscode/settings.json +51 -0
  7. package/templates/CONTRIBUTING.md +184 -0
  8. package/templates/LICENSE +21 -0
  9. package/templates/README.md +324 -0
  10. package/templates/apps/api/.env.example +36 -0
  11. package/templates/apps/api/.prettierrc.json +7 -0
  12. package/templates/apps/api/eslint.config.js +17 -0
  13. package/templates/apps/api/gitignore +45 -0
  14. package/templates/apps/api/jest.config.ts +22 -0
  15. package/templates/apps/api/package.json +49 -0
  16. package/templates/apps/api/src/app.ts +121 -0
  17. package/templates/apps/api/src/config/config.ts +38 -0
  18. package/templates/apps/api/src/config/logger.ts +57 -0
  19. package/templates/apps/api/src/db/mongo.ts +30 -0
  20. package/templates/apps/api/src/index.ts +40 -0
  21. package/templates/apps/api/src/middlewares/middleware.ts +75 -0
  22. package/templates/apps/api/src/models/example.model.ts +89 -0
  23. package/templates/apps/api/src/routes/routes.ts +54 -0
  24. package/templates/apps/api/src/schemas/swagger.schema.ts +58 -0
  25. package/templates/apps/api/src/services/example.service.ts +63 -0
  26. package/templates/apps/api/src/tests/health.test.ts +90 -0
  27. package/templates/apps/api/src/tests/helpers/test-helpers.ts +40 -0
  28. package/templates/apps/api/src/tests/mocks/mocks.ts +29 -0
  29. package/templates/apps/api/src/tests/setup.ts +11 -0
  30. package/templates/apps/api/src/types/fastify.d.ts +44 -0
  31. package/templates/apps/api/tsconfig.json +24 -0
  32. package/templates/apps/web/.env.example +25 -0
  33. package/templates/apps/web/.prettierignore +7 -0
  34. package/templates/apps/web/.prettierrc +9 -0
  35. package/templates/apps/web/app/ICONS.md +42 -0
  36. package/templates/apps/web/app/[locale]/(routes)/layout.tsx +13 -0
  37. package/templates/apps/web/app/[locale]/(routes)/page.tsx +49 -0
  38. package/templates/apps/web/app/[locale]/[...not-found]/page.tsx +8 -0
  39. package/templates/apps/web/app/[locale]/layout.tsx +35 -0
  40. package/templates/apps/web/app/[locale]/not-found.tsx +12 -0
  41. package/templates/apps/web/app/components/layout/Footer.component.tsx +30 -0
  42. package/templates/apps/web/app/components/layout/Nav.component.tsx +34 -0
  43. package/templates/apps/web/app/components/ui/README.md +39 -0
  44. package/templates/apps/web/app/components/ui/atoms/README.md +55 -0
  45. package/templates/apps/web/app/components/ui/molecules/README.md +51 -0
  46. package/templates/apps/web/app/globals.css +104 -0
  47. package/templates/apps/web/app/icon.svg +5 -0
  48. package/templates/apps/web/app/layout.tsx +37 -0
  49. package/templates/apps/web/app/manifest.json +22 -0
  50. package/templates/apps/web/app/providers.tsx +25 -0
  51. package/templates/apps/web/app/robots.ts +12 -0
  52. package/templates/apps/web/app/sitemap.ts +18 -0
  53. package/templates/apps/web/eslint.config.mjs +16 -0
  54. package/templates/apps/web/gitignore +56 -0
  55. package/templates/apps/web/hooks/README.md +25 -0
  56. package/templates/apps/web/i18n/config.ts +9 -0
  57. package/templates/apps/web/i18n/request.ts +15 -0
  58. package/templates/apps/web/interfaces/README.md +5 -0
  59. package/templates/apps/web/lib/README.md +45 -0
  60. package/templates/apps/web/lib/utils.ts +18 -0
  61. package/templates/apps/web/messages/en.json +34 -0
  62. package/templates/apps/web/messages/es.json +34 -0
  63. package/templates/apps/web/next.config.ts +50 -0
  64. package/templates/apps/web/package.json +34 -0
  65. package/templates/apps/web/postcss.config.mjs +7 -0
  66. package/templates/apps/web/proxy.ts +17 -0
  67. package/templates/apps/web/public/README.md +7 -0
  68. package/templates/apps/web/tsconfig.json +27 -0
  69. package/templates/apps/web/types/README.md +3 -0
  70. package/templates/docs/README.md +13 -0
  71. package/templates/gitignore-root +51 -0
  72. package/templates/package.json +30 -0
  73. package/templates/packages/shared/eslint.config.js +26 -0
  74. package/templates/packages/shared/package.json +22 -0
  75. package/templates/packages/shared/src/index.ts +39 -0
  76. package/templates/packages/shared/tsconfig.json +19 -0
  77. package/templates/pnpm-workspace.yaml +3 -0
package/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # create-pnpm-custom-app
2
+
3
+ > A professional CLI to scaffold full-stack monorepo projects with Next.js, Fastify, and pnpm workspaces
4
+
5
+ ## Features
6
+
7
+ - **Next.js 16**: Latest Next.js with App Router and React 19
8
+ - **Fastify 5**: High-performance backend API
9
+ - **MongoDB**: Mongoose ODM for database operations
10
+ - **JWT Authentication**: Secure authentication out of the box
11
+ - **i18n Ready**: Internationalization with next-intl (English/Spanish)
12
+ - **Tailwind CSS 4**: Modern utility-first styling
13
+ - **Swagger/OpenAPI**: Auto-generated API documentation
14
+ - **Testing Ready**: Jest configured for both frontend and backend
15
+ - **Monorepo**: pnpm workspaces for efficient dependency management
16
+ - **Shared Types**: TypeScript interfaces shared between apps
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ # Using npx (recommended)
22
+ npx create-pnpm-custom-app my-project
23
+
24
+ # Or with pnpm
25
+ pnpm create pnpm-custom-app my-project
26
+
27
+ # Or install globally
28
+ pnpm add -g create-pnpm-custom-app
29
+ create-pnpm-custom-app my-project
30
+ ```
31
+
32
+ ## Project Structure
33
+
34
+ ```txt
35
+ my-project/
36
+ ├── apps/
37
+ │ ├── web/ # Next.js frontend
38
+ │ │ ├── app/
39
+ │ │ ├── i18n/
40
+ │ │ ├── messages/
41
+ │ │ └── package.json
42
+ │ └── api/ # Fastify backend
43
+ │ ├── src/
44
+ │ ├── tests/
45
+ │ └── package.json
46
+ ├── packages/
47
+ │ └── shared/ # Shared types
48
+ ├── docs/
49
+ ├── .github/
50
+ │ └── copilot-instructions.md
51
+ └── package.json
52
+ ```
53
+
54
+ ## What's Included
55
+
56
+ ### Frontend (Next.js)
57
+
58
+ - React 19 with Server Components
59
+ - TypeScript strict mode
60
+ - Tailwind CSS 4 with custom design system
61
+ - i18n with next-intl (Spanish/English)
62
+ - Fully responsive with mobile-first approach
63
+ - Accessibility-first components
64
+
65
+ ### Backend (Fastify)
66
+
67
+ - Fastify 5 with TypeScript
68
+ - MongoDB with Mongoose
69
+ - JWT authentication (@fastify/jwt)
70
+ - Swagger/OpenAPI documentation
71
+ - CORS, rate limiting, multipart support
72
+ - Pino logger (pretty mode in dev)
73
+ - Input validation schemas
74
+ - Jest + Supertest for testing
75
+
76
+ ### Monorepo Setup
77
+
78
+ - pnpm workspaces
79
+ - Shared TypeScript types
80
+ - Consistent linting and formatting
81
+ - Comprehensive documentation
82
+ - GitHub Copilot instructions
83
+
84
+ ## After Creating Your Project
85
+
86
+ 1. **Navigate to your project:**
87
+
88
+ ```bash
89
+ cd my-project
90
+ ```
91
+
92
+ 2. **Configure environment variables:**
93
+
94
+ ```bash
95
+ # Frontend
96
+ cp apps/web/.env.example apps/web/.env.local
97
+
98
+ # Backend
99
+ cp apps/api/.env.example apps/api/.env
100
+ ```
101
+
102
+ 3. **Edit the environment files with your values:**
103
+ - `apps/web/.env.local` - API URL and frontend config
104
+ - `apps/api/.env` - MongoDB URI, JWT secret, CORS origin
105
+
106
+ 4. **Start development servers:**
107
+
108
+ ```bash
109
+ # Terminal 1: Frontend (http://localhost:3000)
110
+ pnpm --filter web dev
111
+
112
+ # Terminal 2: Backend (http://localhost:3002)
113
+ pnpm --filter api dev
114
+ ```
115
+
116
+ 5. **Access Swagger documentation:**
117
+ - Open <http://localhost:3002/docs>
118
+
119
+ ## Available Scripts
120
+
121
+ ### Root Level
122
+
123
+ ```bash
124
+ pnpm install # Install all dependencies
125
+ pnpm run dev # Start both apps in parallel
126
+ pnpm run build # Build all apps
127
+ pnpm run lint # Lint all apps
128
+ pnpm run test # Run all tests
129
+ ```
130
+
131
+ ### Frontend
132
+
133
+ ```bash
134
+ pnpm --filter web dev # Development server
135
+ pnpm --filter web build # Production build
136
+ pnpm --filter web start # Production server
137
+ pnpm --filter web lint # Lint code
138
+ ```
139
+
140
+ ### Backend
141
+
142
+ ```bash
143
+ pnpm --filter api dev # Development server
144
+ pnpm --filter api build # Build TypeScript
145
+ pnpm --filter api start # Production server
146
+ pnpm --filter api test # Run tests
147
+ pnpm --filter api test:watch # Tests in watch mode
148
+ pnpm --filter api lint # Lint code
149
+ ```
150
+
151
+ ## Tech Stack
152
+
153
+ | Category | Technologies |
154
+ | ---------- | ------------- |
155
+ | **Frontend** | Next.js 16, React 19, TypeScript, Tailwind CSS 4, next-intl |
156
+ | **Backend** | Fastify 5, TypeScript, MongoDB, Mongoose, Pino |
157
+ | **Auth** | @fastify/jwt, bcrypt |
158
+ | **Testing** | Jest, Supertest |
159
+ | **Tooling** | pnpm, ESLint, Prettier, TypeScript |
160
+ | **Docs** | Swagger/OpenAPI, JSDoc |
161
+
162
+ ## Requirements
163
+
164
+ - **Node.js** 20.0.0 or higher
165
+ - **pnpm** 9.0.0 or higher
166
+ - **MongoDB** (local or remote instance)
167
+
168
+ ## Documentation
169
+
170
+ After creating your project, check:
171
+
172
+ - `README.md` - Project overview and setup
173
+ - `CONTRIBUTING.md` - Contribution guidelines
174
+ - `.github/copilot-instructions.md` - AI coding assistant guidelines
175
+ - `docs/` - Additional documentation
176
+
177
+ ## Tips
178
+
179
+ ### MongoDB Setup
180
+
181
+ **Local MongoDB:**
182
+
183
+ ```bash
184
+ # macOS (Homebrew)
185
+ brew install mongodb-community
186
+ brew services start mongodb-community
187
+
188
+ # Your connection string:
189
+ MONGODB_URI=mongodb://localhost:27017/your-database
190
+ ```
191
+
192
+ **MongoDB Atlas (Cloud):**
193
+
194
+ 1. Sign up at <https://www.mongodb.com/cloud/atlas>
195
+ 2. Create a cluster
196
+ 3. Get your connection string
197
+ 4. Add to `.env`: `MONGODB_URI=mongodb+srv://...`
198
+
199
+ ### Customization
200
+
201
+ - **Colors**: Edit `apps/web/app/globals.css`
202
+ - **i18n**: Add/edit translations in `apps/web/messages/`
203
+ - **API Routes**: Add routes in `apps/api/src/routes/`
204
+ - **Models**: Create models in `apps/api/src/models/`
205
+ - **Components**: Add to `apps/web/app/components/`
206
+
207
+ ## License
208
+
209
+ MIT
210
+
211
+ ## Author
212
+
213
+ Created by Pelayo Trives
214
+
215
+ ---
216
+
217
+ **Happy coding!**
package/bin/cli.js ADDED
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import prompts from 'prompts';
5
+ import chalk from 'chalk';
6
+ import ora from 'ora';
7
+ import fs from 'fs-extra';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { execSync } from 'child_process';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+
15
+ const program = new Command();
16
+
17
+ program
18
+ .name('create-pnpm-custom-app')
19
+ .description('Scaffold a professional full-stack monorepo with Next.js, Fastify, and pnpm workspaces')
20
+ .version('1.0.0')
21
+ .argument('[project-name]', 'Name of the project')
22
+ .parse(process.argv);
23
+
24
+ const args = program.args;
25
+
26
+ async function main() {
27
+ console.log(chalk.bold.cyan('\n🚀 Create PNPM Custom App\n'));
28
+
29
+ let projectName = args[0];
30
+ let githubUser = '';
31
+
32
+ if (!projectName) {
33
+ const response = await prompts({
34
+ type: 'text',
35
+ name: 'projectName',
36
+ message: 'What is your project name?',
37
+ initial: 'my-app',
38
+ validate: (value) => (value.length > 0 ? true : 'Project name is required'),
39
+ });
40
+
41
+ if (!response.projectName) {
42
+ console.log(chalk.red('\n❌ Project creation cancelled.'));
43
+ process.exit(1);
44
+ }
45
+
46
+ projectName = response.projectName;
47
+ }
48
+
49
+ // Ask for GitHub username
50
+ const githubResponse = await prompts({
51
+ type: 'text',
52
+ name: 'githubUser',
53
+ message: 'What is your GitHub username? (optional, used only for repository links)',
54
+ initial: projectName,
55
+ validate: (value) => true, // Optional field
56
+ });
57
+
58
+ githubUser = githubResponse.githubUser || projectName;
59
+
60
+ const projectPath = path.resolve(process.cwd(), projectName);
61
+
62
+ if (fs.existsSync(projectPath)) {
63
+ console.log(chalk.red(`\n❌ Directory "${projectName}" already exists.`));
64
+ process.exit(1);
65
+ }
66
+
67
+ console.log(chalk.gray(`\n📁 Creating project at: ${projectPath}\n`));
68
+
69
+ const spinner = ora('Creating project structure...').start();
70
+
71
+ try {
72
+ // Create project directory
73
+ fs.mkdirSync(projectPath, { recursive: true });
74
+
75
+ // Copy all templates
76
+ const templatesDir = path.join(__dirname, '../templates');
77
+ fs.copySync(templatesDir, projectPath);
78
+
79
+ // Rename gitignore files (npm publish removes .gitignore)
80
+ const gitignoreRootPath = path.join(projectPath, 'gitignore-root');
81
+ if (fs.existsSync(gitignoreRootPath)) {
82
+ fs.renameSync(gitignoreRootPath, path.join(projectPath, '.gitignore'));
83
+ }
84
+
85
+ const webGitignorePath = path.join(projectPath, 'apps/web/gitignore');
86
+ if (fs.existsSync(webGitignorePath)) {
87
+ fs.renameSync(webGitignorePath, path.join(projectPath, 'apps/web/.gitignore'));
88
+ }
89
+
90
+ const apiGitignorePath = path.join(projectPath, 'apps/api/gitignore');
91
+ if (fs.existsSync(apiGitignorePath)) {
92
+ fs.renameSync(apiGitignorePath, path.join(projectPath, 'apps/api/.gitignore'));
93
+ }
94
+
95
+ // Replace project name in package.json files
96
+ const packageJsonPaths = [
97
+ path.join(projectPath, 'package.json'),
98
+ path.join(projectPath, 'apps/web/package.json'),
99
+ path.join(projectPath, 'apps/api/package.json'),
100
+ path.join(projectPath, 'packages/shared/package.json'),
101
+ ];
102
+
103
+ packageJsonPaths.forEach((pkgPath) => {
104
+ if (fs.existsSync(pkgPath)) {
105
+ const content = fs.readFileSync(pkgPath, 'utf-8');
106
+ const updated = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
107
+ fs.writeFileSync(pkgPath, updated);
108
+ }
109
+ });
110
+
111
+ // Replace project name in all other files (tsx, ts, md, json, etc.)
112
+ const filesToReplace = [
113
+ path.join(projectPath, 'README.md'),
114
+ path.join(projectPath, 'CONTRIBUTING.md'),
115
+ path.join(projectPath, 'apps/web/app/layout.tsx'),
116
+ path.join(projectPath, 'apps/web/app/manifest.json'),
117
+ path.join(projectPath, 'apps/web/app/components/layout/Nav.component.tsx'),
118
+ path.join(projectPath, 'apps/web/app/components/layout/Footer.component.tsx'),
119
+ path.join(projectPath, 'apps/web/app/[locale]/(routes)/page.tsx'),
120
+ path.join(projectPath, 'apps/web/app/opengraph-image.tsx'),
121
+ path.join(projectPath, 'apps/web/app/twitter-image.tsx'),
122
+ path.join(projectPath, 'apps/web/app/apple-icon.tsx'),
123
+ path.join(projectPath, 'apps/web/app/icon.tsx'),
124
+ path.join(projectPath, 'apps/web/messages/en.json'),
125
+ path.join(projectPath, 'apps/web/messages/es.json'),
126
+ path.join(projectPath, 'apps/api/src/app.ts'),
127
+ path.join(projectPath, 'packages/shared/src/index.ts'),
128
+ path.join(projectPath, '.github/copilot-instructions.md'),
129
+ ];
130
+
131
+ filesToReplace.forEach((filePath) => {
132
+ if (fs.existsSync(filePath)) {
133
+ let content = fs.readFileSync(filePath, 'utf-8');
134
+ content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
135
+ content = content.replace(/\{\{GITHUB_USER\}\}/g, githubUser);
136
+ fs.writeFileSync(filePath, content);
137
+ }
138
+ });
139
+
140
+ spinner.succeed(chalk.green('Project structure created!'));
141
+
142
+ // Install dependencies
143
+ spinner.start('Installing dependencies with pnpm... This may take a few minutes.');
144
+
145
+ try {
146
+ execSync('pnpm install', { cwd: projectPath, stdio: 'ignore' });
147
+ spinner.succeed(chalk.green('Dependencies installed successfully!'));
148
+ } catch (error) {
149
+ spinner.warn(chalk.yellow('Could not install dependencies automatically.'));
150
+ console.log(chalk.gray(' Run `pnpm install` manually inside the project.'));
151
+ }
152
+
153
+ // Success message
154
+ console.log(chalk.bold.green(`\n✅ Project "${projectName}" created successfully!\n`));
155
+ console.log(chalk.cyan('📦 Project structure:'));
156
+ console.log(chalk.gray(' ├── apps/'));
157
+ console.log(chalk.gray(' │ ├── web/ (Next.js 16 + TypeScript + Tailwind 4)'));
158
+ console.log(chalk.gray(' │ └── api/ (Fastify + MongoDB + TypeScript)'));
159
+ console.log(chalk.gray(' ├── packages/'));
160
+ console.log(chalk.gray(' │ └── shared/ (Shared types and interfaces)'));
161
+ console.log(chalk.gray(' └── docs/ (Project documentation)\n'));
162
+
163
+ console.log(chalk.cyan('🚀 Next steps:'));
164
+ console.log(chalk.white(` 1. cd ${projectName}`));
165
+ console.log(chalk.white(' 2. Copy .env.example files and configure:'));
166
+ console.log(chalk.gray(' - apps/web/.env.local'));
167
+ console.log(chalk.gray(' - apps/api/.env'));
168
+ console.log(chalk.white(' 3. Start development:'));
169
+ console.log(chalk.gray(' - Frontend: pnpm --filter web dev'));
170
+ console.log(chalk.gray(' - Backend: pnpm --filter api dev'));
171
+ console.log(chalk.white(' 4. Read the README.md for more information\n'));
172
+
173
+ console.log(chalk.bold.magenta('Happy coding! 🎉\n'));
174
+
175
+ } catch (error) {
176
+ spinner.fail(chalk.red('Failed to create project'));
177
+ console.error(error);
178
+ process.exit(1);
179
+ }
180
+ }
181
+
182
+ main().catch((error) => {
183
+ console.error(chalk.red('An error occurred:'), error);
184
+ process.exit(1);
185
+ });
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "create-pnpm-custom-app",
3
+ "version": "1.0.0",
4
+ "description": "A professional CLI to scaffold full-stack monorepo projects with Next.js, Fastify, and pnpm workspaces",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-pnpm-custom-app": "./bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Run: npx create-pnpm-custom-app my-project\" && exit 0"
11
+ },
12
+ "keywords": [
13
+ "cli",
14
+ "scaffold",
15
+ "boilerplate",
16
+ "monorepo",
17
+ "pnpm",
18
+ "nextjs",
19
+ "fastify",
20
+ "typescript",
21
+ "tailwind"
22
+ ],
23
+ "author": "Pelayo Trives",
24
+ "license": "MIT",
25
+ "engines": {
26
+ "node": ">=20.0.0"
27
+ },
28
+ "dependencies": {
29
+ "chalk": "^5.3.0",
30
+ "commander": "^12.1.0",
31
+ "fs-extra": "^11.2.0",
32
+ "ora": "^8.1.1",
33
+ "prompts": "^2.4.2"
34
+ },
35
+ "files": [
36
+ "bin",
37
+ "templates"
38
+ ]
39
+ }
@@ -0,0 +1,184 @@
1
+ # GitHub Copilot Instructions for [Project Name]
2
+
3
+ ## Project Overview
4
+
5
+ [Brief description of your project]
6
+
7
+ **Tech Stack:**
8
+ - **Frontend**: Next.js 16+ (App Router), React 19+, TypeScript
9
+ - **Backend**: Fastify API with MongoDB
10
+ - **Monorepo**: pnpm workspace (apps/web, apps/api, packages/shared)
11
+ - **Styling**: Tailwind CSS 4 with custom design system
12
+ - **i18n**: next-intl (English/Spanish)
13
+
14
+ ---
15
+
16
+ ## Architecture Patterns
17
+
18
+ ### Component Structure (Atomic Design)
19
+
20
+ - **Atoms**: `/app/components/ui/atoms/` - Basic UI elements (Button, Input, etc.)
21
+ - **Molecules**: `/app/components/ui/molecules/` - Composite components
22
+ - **Layout**: `/app/components/layout/` - Navigation, Footer, etc.
23
+
24
+ ### Component Guidelines
25
+
26
+ 1. **All Typography components MUST use `forwardRef`** for animation library compatibility
27
+ 2. **Interactive components MUST have `'use client'`** directive
28
+ 3. **Server components by default** - only add 'use client' when necessary
29
+ 4. Use **TypeScript strictly** - avoid `any` types, define all interfaces
30
+ 5. **Tailwind only** - no inline styles or CSS modules
31
+ 6. Use **cn()** utility for className merging
32
+
33
+ ---
34
+
35
+ ## File Naming Conventions
36
+
37
+ - Components: `ComponentName.component.tsx`
38
+ - Pages: `page.tsx` (Next.js App Router)
39
+ - Layouts: `layout.tsx`
40
+ - Interfaces: `name.interface.ts`
41
+ - Utilities: `name.ts`
42
+
43
+ ---
44
+
45
+ ## Code Style
46
+
47
+ ### TypeScript
48
+
49
+ ```typescript
50
+ // Prefer interfaces over types
51
+ interface ButtonProps {
52
+ variant?: "primary" | "secondary";
53
+ children: React.ReactNode;
54
+ }
55
+
56
+ // Use Record for variant mappings
57
+ const variantClasses: Record<string, string> = {
58
+ primary: "bg-primary",
59
+ secondary: "bg-secondary",
60
+ };
61
+ ```
62
+
63
+ ### React Patterns
64
+
65
+ ```typescript
66
+ // Use forwardRef for components that need refs
67
+ export const Component = forwardRef<HTMLDivElement, Props>(
68
+ ({ children, className, ...props }, ref) => (
69
+ <div ref={ref} className={cn("base-class", className)} {...props}>
70
+ {children}
71
+ </div>
72
+ )
73
+ );
74
+ Component.displayName = "Component";
75
+
76
+ // Use 'use client' for interactive components
77
+ ("use client");
78
+ import { useState } from "react";
79
+ ```
80
+
81
+ ### Tailwind CSS
82
+
83
+ - Use responsive prefixes: `sm:`, `md:`, `lg:`
84
+ - Dark mode support with theme provider
85
+ - Custom colors: Use design tokens (bg-primary, text-muted-foreground, etc.)
86
+ - Spacing: Use Tailwind scale (p-4, gap-6, etc.)
87
+
88
+ ---
89
+
90
+ ## Translations (next-intl)
91
+
92
+ - Files: `/messages/en.json` and `/messages/es.json`
93
+ - Usage: `const t = useTranslations('namespace');`
94
+ - Structure: Nested keys `{ "auth": { "login": { "title": "Sign in" } } }`
95
+ - Always add both English and Spanish translations
96
+
97
+ ---
98
+
99
+ ## API Integration
100
+
101
+ - Services in `/lib/` (e.g., auth.ts, api.ts)
102
+ - Use `fetch` with proper error handling
103
+ - Handle errors with toast notifications
104
+ - Types from `@{{PROJECT_NAME}}/shared` package
105
+
106
+ ---
107
+
108
+ ## State Management
109
+
110
+ - Use React hooks for local state
111
+ - Global state: Context API or state management library of choice
112
+ - Keep state management simple and predictable
113
+
114
+ ---
115
+
116
+ ## Performance
117
+
118
+ - Use `loading.tsx` for loading states
119
+ - Implement proper error boundaries
120
+ - Lazy load heavy components when possible
121
+ - Optimize images with Next.js Image component
122
+
123
+ ---
124
+
125
+ ## Common Mistakes to Avoid
126
+
127
+ ❌ DON'T use inline styles - only Tailwind classes
128
+ ❌ DON'T forget 'use client' on interactive components
129
+ ❌ DON'T use `any` type
130
+ ❌ DON'T mix Spanish and English in same file
131
+ ❌ DON'T create CSS modules - Tailwind only
132
+
133
+ ---
134
+
135
+ ## When Making Changes
136
+
137
+ 1. Read existing file structure first
138
+ 2. Follow established patterns
139
+ 3. Update translations if adding new text
140
+ 4. Run `pnpm run lint` to verify
141
+ 5. Run `pnpm run build` for final verification
142
+ 6. Check for TypeScript errors
143
+ 7. Ensure mobile responsiveness
144
+
145
+ ---
146
+
147
+ ## Priority Order for Edits
148
+
149
+ 1. Fix TypeScript errors
150
+ 2. Fix build errors
151
+ 3. Add missing 'use client' directives
152
+ 4. Improve accessibility
153
+ 5. Optimize performance
154
+ 6. Enhance UX
155
+
156
+ ---
157
+
158
+ ## Documentation & Communication
159
+
160
+ - **All code comments and JSDoc must be in English**
161
+ - Code itself (variable names, function names) in English
162
+ - Translation files (en.json, es.json) in their respective languages
163
+ - Add JSDoc comments for all functions/components:
164
+ - Description of purpose
165
+ - `@param` for each parameter
166
+ - `@returns` for return value
167
+ - `@example` for complex usage
168
+
169
+ ---
170
+
171
+ ## Backend API Guidelines
172
+
173
+ - When creating new API routes, update Swagger documentation
174
+ - Follow existing Swagger schema patterns
175
+ - Include request/response examples
176
+ - Document all query parameters, headers, and body fields
177
+
178
+ ---
179
+
180
+ ## Other Notes
181
+
182
+ - ALWAYS prioritize accessibility (a11y)
183
+ - AVOID using emojis in code comments or documentation
184
+ - Update this file when project standards or patterns change
@@ -0,0 +1 @@
1
+ v20.18.1
@@ -0,0 +1,51 @@
1
+ {
2
+ "editor.formatOnSave": true,
3
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
4
+ "editor.codeActionsOnSave": {
5
+ "source.fixAll.eslint": "explicit"
6
+ },
7
+ "typescript.tsdk": "node_modules/typescript/lib",
8
+ "typescript.enablePromptUseWorkspaceTsdk": true,
9
+ "files.associations": {
10
+ "*.css": "tailwindcss"
11
+ },
12
+ "tailwindCSS.experimental.classRegex": [
13
+ ["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
14
+ ],
15
+ "editor.quickSuggestions": {
16
+ "strings": "on"
17
+ },
18
+ "files.exclude": {
19
+ "**/.git": true,
20
+ "**/.DS_Store": true,
21
+ "**/node_modules": true,
22
+ "**/.next": true,
23
+ "**/dist": true,
24
+ "**/build": true
25
+ },
26
+ "search.exclude": {
27
+ "**/node_modules": true,
28
+ "**/.next": true,
29
+ "**/dist": true,
30
+ "**/build": true,
31
+ "**/pnpm-lock.yaml": true
32
+ },
33
+ "[typescript]": {
34
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
35
+ },
36
+ "[typescriptreact]": {
37
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
38
+ },
39
+ "[javascript]": {
40
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
41
+ },
42
+ "[json]": {
43
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
44
+ },
45
+ "eslint.validate": [
46
+ "javascript",
47
+ "javascriptreact",
48
+ "typescript",
49
+ "typescriptreact"
50
+ ]
51
+ }