create-ely 0.1.1

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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/package.json +60 -0
  4. package/src/index.ts +187 -0
  5. package/templates/monorepo/README.md +75 -0
  6. package/templates/monorepo/apps/backend/.cursor/mcp.json +8 -0
  7. package/templates/monorepo/apps/backend/.dockerignore +60 -0
  8. package/templates/monorepo/apps/backend/.env.example +19 -0
  9. package/templates/monorepo/apps/backend/.github/workflows/lint.yml +31 -0
  10. package/templates/monorepo/apps/backend/.github/workflows/tests.yml +36 -0
  11. package/templates/monorepo/apps/backend/AGENTS.md +79 -0
  12. package/templates/monorepo/apps/backend/CHANGELOG.md +190 -0
  13. package/templates/monorepo/apps/backend/CLAUDE.md +149 -0
  14. package/templates/monorepo/apps/backend/Dockerfile +35 -0
  15. package/templates/monorepo/apps/backend/LICENSE +21 -0
  16. package/templates/monorepo/apps/backend/README.md +274 -0
  17. package/templates/monorepo/apps/backend/biome.json +58 -0
  18. package/templates/monorepo/apps/backend/bun.lock +303 -0
  19. package/templates/monorepo/apps/backend/docker-compose.yml +37 -0
  20. package/templates/monorepo/apps/backend/drizzle.config.ts +14 -0
  21. package/templates/monorepo/apps/backend/package.json +42 -0
  22. package/templates/monorepo/apps/backend/src/common/config.ts +29 -0
  23. package/templates/monorepo/apps/backend/src/common/logger.ts +18 -0
  24. package/templates/monorepo/apps/backend/src/db/index.ts +31 -0
  25. package/templates/monorepo/apps/backend/src/db/migrations/20251111132328_curly_spectrum.sql +8 -0
  26. package/templates/monorepo/apps/backend/src/db/migrations/meta/20251111132328_snapshot.json +70 -0
  27. package/templates/monorepo/apps/backend/src/db/migrations/meta/_journal.json +13 -0
  28. package/templates/monorepo/apps/backend/src/db/schema/users.ts +39 -0
  29. package/templates/monorepo/apps/backend/src/main.ts +67 -0
  30. package/templates/monorepo/apps/backend/src/middleware/error-handler.ts +36 -0
  31. package/templates/monorepo/apps/backend/src/modules/users/index.ts +61 -0
  32. package/templates/monorepo/apps/backend/src/modules/users/model.ts +48 -0
  33. package/templates/monorepo/apps/backend/src/modules/users/service.ts +46 -0
  34. package/templates/monorepo/apps/backend/src/tests/users.test.ts +102 -0
  35. package/templates/monorepo/apps/backend/src/util/graceful-shutdown.ts +37 -0
  36. package/templates/monorepo/apps/backend/tsconfig.json +35 -0
  37. package/templates/monorepo/apps/backend-biome.json.template +14 -0
  38. package/templates/monorepo/apps/frontend/.env.example +1 -0
  39. package/templates/monorepo/apps/frontend/README.md +59 -0
  40. package/templates/monorepo/apps/frontend/biome.json +16 -0
  41. package/templates/monorepo/apps/frontend/components.json +21 -0
  42. package/templates/monorepo/apps/frontend/index.html +15 -0
  43. package/templates/monorepo/apps/frontend/package.json +48 -0
  44. package/templates/monorepo/apps/frontend/public/favicon.ico +0 -0
  45. package/templates/monorepo/apps/frontend/src/assets/fonts/.gitkeep +0 -0
  46. package/templates/monorepo/apps/frontend/src/assets/images/.gitkeep +0 -0
  47. package/templates/monorepo/apps/frontend/src/features/layout/Header.tsx +73 -0
  48. package/templates/monorepo/apps/frontend/src/main.tsx +36 -0
  49. package/templates/monorepo/apps/frontend/src/routeTree.gen.ts +95 -0
  50. package/templates/monorepo/apps/frontend/src/routes/__root.tsx +25 -0
  51. package/templates/monorepo/apps/frontend/src/routes/index.tsx +34 -0
  52. package/templates/monorepo/apps/frontend/src/routes/users/index.tsx +79 -0
  53. package/templates/monorepo/apps/frontend/src/routes/users/new.tsx +148 -0
  54. package/templates/monorepo/apps/frontend/src/shared/api/client.ts +6 -0
  55. package/templates/monorepo/apps/frontend/src/shared/components/.gitkeep +0 -0
  56. package/templates/monorepo/apps/frontend/src/shared/constants/.gitkeep +0 -0
  57. package/templates/monorepo/apps/frontend/src/shared/hooks/.gitkeep +0 -0
  58. package/templates/monorepo/apps/frontend/src/shared/types/.gitkeep +0 -0
  59. package/templates/monorepo/apps/frontend/src/shared/utils/utils.ts +6 -0
  60. package/templates/monorepo/apps/frontend/src/styles.css +138 -0
  61. package/templates/monorepo/apps/frontend/src/vite-env.d.ts +13 -0
  62. package/templates/monorepo/apps/frontend/tsconfig.json +27 -0
  63. package/templates/monorepo/apps/frontend/vite.config.ts +27 -0
  64. package/templates/monorepo/biome.json +65 -0
  65. package/templates/monorepo/bun.lock +1044 -0
  66. package/templates/monorepo/package.json +13 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Create Ely
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # create-ely
2
+
3
+ Scaffold ElysiaJS projects with ease using [Bun](https://bun.sh).
4
+
5
+ ## Usage
6
+
7
+ Create a new ElysiaJS project:
8
+
9
+ ```bash
10
+ bunx create-ely my-project
11
+ ```
12
+
13
+ You'll be prompted to choose between:
14
+
15
+ - **Backend only** - ElysiaJS API with PostgreSQL, Drizzle ORM
16
+ - **Monorepo** - Backend + Frontend (React with TanStack Router)
17
+
18
+ ## Templates
19
+
20
+ ### Backend Only
21
+
22
+ A production-ready ElysiaJS backend with:
23
+
24
+ - PostgreSQL database with Drizzle ORM
25
+ - Type-safe API with OpenAPI documentation
26
+ - Global error handling
27
+ - Structured logging with Pino
28
+ - Docker support
29
+ - Environment validation
30
+
31
+ ### Monorepo
32
+
33
+ Full-stack setup with:
34
+
35
+ - Backend: Everything from Backend Only template
36
+ - Frontend: React + TanStack Router + Vite
37
+ - Workspace configuration with Bun
38
+
39
+ ## Development
40
+
41
+ To test the CLI locally:
42
+
43
+ ```bash
44
+ bun link
45
+ bunx create-ely
46
+ ```
47
+
48
+ ## License
49
+
50
+ MIT
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "create-ely",
3
+ "version": "0.1.1",
4
+ "description": "Scaffold production-ready ElysiaJS projects with ease using Bun - choose between backend-only or full-stack monorepo templates",
5
+ "type": "module",
6
+ "author": {
7
+ "name": "truehazker",
8
+ "url": "https://github.com/truehazker"
9
+ },
10
+ "license": "MIT",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/truehazker/create-ely.git"
14
+ },
15
+ "homepage": "https://github.com/truehazker/create-ely#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/truehazker/create-ely/issues"
18
+ },
19
+ "keywords": [
20
+ "elysiajs",
21
+ "elysia",
22
+ "bun",
23
+ "template",
24
+ "scaffold",
25
+ "cli",
26
+ "create",
27
+ "generator",
28
+ "boilerplate",
29
+ "starter",
30
+ "monorepo",
31
+ "fullstack",
32
+ "backend",
33
+ "drizzle",
34
+ "postgresql",
35
+ "react",
36
+ "tanstack-router"
37
+ ],
38
+ "bin": {
39
+ "create-ely": "./src/index.ts"
40
+ },
41
+ "files": ["src", "templates", "README.md", "LICENSE"],
42
+ "scripts": {
43
+ "dev": "bun run src/index.ts",
44
+ "build": "bun build src/index.ts --compile --outfile dist/create-ely"
45
+ },
46
+ "engines": {
47
+ "bun": ">=1.0.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public",
51
+ "registry": "https://registry.npmjs.org/"
52
+ },
53
+ "dependencies": {
54
+ "@clack/prompts": "^0.11.0"
55
+ },
56
+ "devDependencies": {
57
+ "@biomejs/biome": "2.3.10",
58
+ "@types/bun": "^1.3.5"
59
+ }
60
+ }
package/src/index.ts ADDED
@@ -0,0 +1,187 @@
1
+ #!/usr/bin/env bun
2
+ import {
3
+ copyFileSync,
4
+ existsSync,
5
+ mkdirSync,
6
+ readdirSync,
7
+ rmSync,
8
+ statSync,
9
+ } from 'node:fs';
10
+ import { dirname, join } from 'node:path';
11
+ import * as clack from '@clack/prompts';
12
+
13
+ async function main() {
14
+ console.clear();
15
+
16
+ clack.intro('create-ely');
17
+
18
+ // Check if project name was passed as argument
19
+ const args = process.argv.slice(2);
20
+ const projectNameArg = args[0];
21
+
22
+ const projectType = await clack.select({
23
+ message: 'What would you like to create?',
24
+ options: [
25
+ {
26
+ value: 'backend',
27
+ label: 'Backend only',
28
+ hint: 'ElysiaJS API with PostgreSQL',
29
+ },
30
+ {
31
+ value: 'monorepo',
32
+ label: 'Monorepo',
33
+ hint: 'Backend + Frontend (React + TanStack Router)',
34
+ },
35
+ ],
36
+ });
37
+
38
+ if (clack.isCancel(projectType)) {
39
+ clack.cancel('Operation cancelled');
40
+ process.exit(0);
41
+ }
42
+
43
+ let projectName: string | symbol;
44
+
45
+ // If project name was provided as argument and is valid, use it
46
+ if (projectNameArg && /^[a-z0-9-]+$/.test(projectNameArg)) {
47
+ projectName = projectNameArg;
48
+ } else {
49
+ // Otherwise, prompt for it
50
+ projectName = await clack.text({
51
+ message: 'Project name:',
52
+ placeholder: 'my-elysia-app',
53
+ validate: (value) => {
54
+ if (!value) return 'Project name is required';
55
+ if (!/^[a-z0-9-]+$/.test(value))
56
+ return 'Project name must contain only lowercase letters, numbers, and hyphens';
57
+ return undefined;
58
+ },
59
+ });
60
+
61
+ if (clack.isCancel(projectName)) {
62
+ clack.cancel('Operation cancelled');
63
+ process.exit(0);
64
+ }
65
+ }
66
+
67
+ const targetDir = join(process.cwd(), projectName as string);
68
+
69
+ if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {
70
+ const shouldOverwrite = await clack.confirm({
71
+ message: `Directory "${String(projectName)}" already exists and is not empty. Overwrite it?`,
72
+ initialValue: false,
73
+ });
74
+
75
+ if (clack.isCancel(shouldOverwrite) || !shouldOverwrite) {
76
+ clack.cancel('Operation cancelled');
77
+ process.exit(0);
78
+ }
79
+
80
+ rmSync(targetDir, { recursive: true, force: true });
81
+ }
82
+
83
+ const spinner = clack.spinner();
84
+ spinner.start('Creating project...');
85
+
86
+ try {
87
+ const templateDir = join(
88
+ import.meta.dir,
89
+ '..',
90
+ 'templates',
91
+ projectType as string,
92
+ );
93
+
94
+ // Cross-platform recursive copy function
95
+ function copyRecursive(src: string, dest: string, exclude: string[] = []) {
96
+ const stats = statSync(src);
97
+
98
+ if (stats.isDirectory()) {
99
+ if (!existsSync(dest)) {
100
+ mkdirSync(dest, { recursive: true });
101
+ }
102
+
103
+ for (const entry of readdirSync(src)) {
104
+ if (exclude.includes(entry) || entry.endsWith('.template')) continue;
105
+
106
+ const srcPath = join(src, entry);
107
+ const destPath = join(dest, entry);
108
+ copyRecursive(srcPath, destPath, exclude);
109
+ }
110
+ } else {
111
+ const destDir = dirname(dest);
112
+ if (!existsSync(destDir)) {
113
+ mkdirSync(destDir, { recursive: true });
114
+ }
115
+ copyFileSync(src, dest);
116
+ }
117
+ }
118
+
119
+ copyRecursive(templateDir, targetDir, ['node_modules', '.git']);
120
+
121
+ // Handle template files: copy them to their intended locations
122
+ if (projectType === 'monorepo') {
123
+ const backendBiomeTemplate = join(
124
+ templateDir,
125
+ 'apps',
126
+ 'backend-biome.json.template',
127
+ );
128
+ const backendBiomeTarget = join(
129
+ targetDir,
130
+ 'apps',
131
+ 'backend',
132
+ 'biome.json',
133
+ );
134
+
135
+ if (existsSync(backendBiomeTemplate)) {
136
+ copyFileSync(backendBiomeTemplate, backendBiomeTarget);
137
+ }
138
+ }
139
+
140
+ spinner.stop('Project created successfully!');
141
+
142
+ const s = clack.spinner();
143
+ s.start('Installing dependencies...');
144
+
145
+ // Install dependencies
146
+ const installProc = Bun.spawn(['bun', 'install'], {
147
+ cwd: targetDir,
148
+ stdout: 'inherit',
149
+ stderr: 'inherit',
150
+ });
151
+ await installProc.exited;
152
+
153
+ if (installProc.exitCode !== 0) {
154
+ throw new Error('Failed to install dependencies');
155
+ }
156
+
157
+ s.stop('Dependencies installed!');
158
+
159
+ const nextSteps =
160
+ projectType === 'monorepo'
161
+ ? ` cd ${String(projectName)}
162
+ bun run dev:backend # Start backend on http://localhost:3000
163
+ bun run dev:frontend # Start frontend on http://localhost:5173`
164
+ : ` cd ${String(projectName)}
165
+ bun run dev # Start backend on http://localhost:3000`;
166
+
167
+ clack.outro(`
168
+ Success! Your ElysiaJS project is ready.
169
+
170
+ Next steps:
171
+ ${nextSteps}
172
+
173
+ Check out the README.md for more information.
174
+ `);
175
+ } catch (error) {
176
+ spinner.stop('Failed to create project');
177
+ clack.cancel(
178
+ error instanceof Error ? error.message : 'Unknown error occurred',
179
+ );
180
+ process.exit(1);
181
+ }
182
+ }
183
+
184
+ main().catch((error) => {
185
+ console.error('Fatal error:', error);
186
+ process.exit(1);
187
+ });
@@ -0,0 +1,75 @@
1
+ # Monorepo Template
2
+
3
+ This is a monorepo template containing a full-stack application with a backend (ElysiaJS) and frontend (React) application.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - [Bun](https://bun.sh) (latest version)
10
+ - [Podman](https://podman.io) (for running auxiliary services)
11
+
12
+ ### Setup Steps
13
+
14
+ 1. **Install dependencies**
15
+
16
+ ```bash
17
+ bun install
18
+ ```
19
+
20
+ 2. **Configure environment variables**
21
+
22
+ Each app requires its own `.env` file. Please check each app's README for specific environment variable requirements:
23
+
24
+ - **Backend**: See [apps/backend/README.md](./apps/backend/README.md) for required environment variables (e.g., `DATABASE_URL`, `SERVER_PORT`, etc.)
25
+ - **Frontend**: See [apps/frontend/README.md](./apps/frontend/README.md) for required environment variables (e.g., `VITE_API_URL`)
26
+
27
+ 3. **Start auxiliary services with Podman**
28
+
29
+ The backend requires a PostgreSQL database. You can start it using Podman or Docker:
30
+
31
+ ```bash
32
+ cd apps/backend
33
+ podman compose up -d elysia-boilerplate-postgres
34
+ ```
35
+
36
+ This will start a PostgreSQL database container that the backend application can connect to.
37
+
38
+ 4. **Run database migrations**
39
+
40
+ ```bash
41
+ cd apps/backend
42
+ bun run db:migrate
43
+ ```
44
+
45
+ 5. **Start the applications**
46
+
47
+ In separate terminals:
48
+
49
+ ```bash
50
+ # Terminal 1: Start backend
51
+ cd apps/backend
52
+ bun run dev
53
+
54
+ # Terminal 2: Start frontend
55
+ cd apps/frontend
56
+ bun run dev
57
+ ```
58
+
59
+ ## Project Structure
60
+
61
+ ```text
62
+ .
63
+ ├── apps/
64
+ │ ├── backend/ # ElysiaJS API server
65
+ │ └── frontend/ # React frontend application
66
+ ├── package.json # Root package.json for workspace management
67
+ └── README.md # This file
68
+ ```
69
+
70
+ ## Additional Information
71
+
72
+ For more detailed information about each application, please refer to their respective README files:
73
+
74
+ - [Backend README](./apps/backend/README.md)
75
+ - [Frontend README](./apps/frontend/README.md)
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "context7": {
4
+ "command": "npx",
5
+ "args": ["-y", "@upstash/context7-mcp"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,60 @@
1
+ # Ignore files that shouldn't be in the Docker build context
2
+ # Following best practices from Dejan Gegić's optimization guide
3
+
4
+ # Version control
5
+ .git
6
+ .gitignore
7
+
8
+ # Dependencies (will be installed in container)
9
+ node_modules
10
+ npm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+
14
+ # Environment and secrets
15
+ .env
16
+ .env.local
17
+ .env.*.local
18
+ *.pem
19
+
20
+ # Build outputs (except what we explicitly copy)
21
+ build
22
+ dist
23
+ coverage
24
+
25
+ # IDE and editor files
26
+ .vscode
27
+ .idea
28
+ *.swp
29
+ *.swo
30
+ *~
31
+
32
+ # OS generated files
33
+ .DS_Store
34
+ .DS_Store?
35
+ ._*
36
+ .Spotlight-V100
37
+ .Trashes
38
+ ehthumbs.db
39
+ Thumbs.db
40
+
41
+ # Documentation
42
+ README.md
43
+ CHANGELOG.md
44
+ LICENSE
45
+ *.md
46
+
47
+ # Docker files
48
+ Dockerfile*
49
+ docker-compose*.yml
50
+
51
+ # Test files
52
+ **/*.test.*
53
+ **/*.spec.*
54
+ tests/
55
+ test/
56
+
57
+ # Logs
58
+ logs
59
+ *.log
60
+
@@ -0,0 +1,19 @@
1
+ # Application Environment
2
+ NODE_ENV=development
3
+
4
+ # Logging Configuration
5
+ LOG_LEVEL=debug
6
+
7
+ # Server Configuration
8
+ SERVER_HOSTNAME=localhost
9
+ SERVER_PORT=3000
10
+
11
+ # Database Configuration
12
+ # Replace with your actual PostgreSQL connection details
13
+ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/elysia-boilerplate
14
+
15
+ # Enable migrations on server startup
16
+ DB_AUTO_MIGRATE=false
17
+
18
+ # Enable OpenAPI documentation to be available on /openapi route
19
+ ENABLE_OPENAPI=true
@@ -0,0 +1,31 @@
1
+ name: Lint
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - develop
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ - develop
12
+
13
+ jobs:
14
+ lint:
15
+ name: Biome Lint Check
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Setup Bun
23
+ uses: oven-sh/setup-bun@v2
24
+ with:
25
+ bun-version: latest
26
+
27
+ - name: Install dependencies
28
+ run: bun install --frozen-lockfile
29
+
30
+ - name: Run Biome linter
31
+ run: bun run lint
@@ -0,0 +1,36 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - develop
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ - develop
12
+
13
+ jobs:
14
+ test:
15
+ name: Run Tests
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Setup Bun
23
+ uses: oven-sh/setup-bun@v2
24
+ with:
25
+ bun-version: latest
26
+
27
+ - name: Install dependencies
28
+ run: bun install --frozen-lockfile
29
+
30
+ - name: Prepare environment variables
31
+ run: |
32
+ echo "NODE_ENV=test" >> $GITHUB_ENV
33
+ echo "DATABASE_URL=${{ secrets.DATABASE_URL }}" >> $GITHUB_ENV
34
+
35
+ - name: Run tests
36
+ run: bun test
@@ -0,0 +1,79 @@
1
+ # AGENTS.md
2
+
3
+ ## Project Overview
4
+
5
+ This is an ElysiaJS boilerplate project using Bun, PostgreSQL, and Drizzle ORM.
6
+ It follows a modular architecture with strict TypeScript configuration.
7
+
8
+ ## Tech Stack
9
+
10
+ - **Runtime**: Bun
11
+ - **Framework**: ElysiaJS
12
+ - **Database**: PostgreSQL
13
+ - **ORM**: Drizzle ORM
14
+ - **Linter/Formatter**: Biome
15
+ - **Testing**: Bun Test
16
+ - **Containerization**: Docker
17
+
18
+ ## Recommended Tools
19
+
20
+ - **VS Code Extensions**:
21
+ - `biomejs.biome` (Formatter & Linter)
22
+ - `vivaxy.vscode-conventional-commits` (Commit messages)
23
+ - `ms-vscode.cmake-tools` (Build tools)
24
+ - **MCP Services**:
25
+ - PostgreSQL MCP (for database context)
26
+ - GitHub MCP (for PR/Issue context)
27
+
28
+ ## Setup & Commands
29
+
30
+ - **Install dependencies**: `bun install`
31
+ - **Start dev server**: `bun run dev`
32
+ - **Build for production**: `bun run build`
33
+ - **Start production server**: `bun run start`
34
+ - **Run tests**: `bun test`
35
+ - **Lint code**: `bun run lint`
36
+ - **Format code**: `bun run format`
37
+
38
+ ## Database Operations
39
+
40
+ - **Generate migrations**: `bun run db:generate` (Run after modifying schema in `src/db/schema`)
41
+ - **Apply migrations**: `bun run db:migrate`
42
+ - **Open Database Studio**: `bun run db:studio`
43
+
44
+ ## Code Style & Conventions
45
+
46
+ - **Linter**: Strictly follow Biome rules. Run `bun run lint:fix` to auto-fix issues.
47
+ - **TypeScript**: Strict mode is enabled. No `any` types unless absolutely necessary.
48
+ - **Architecture**:
49
+ - Modular structure in `src/modules/`.
50
+ - Each module should have `index.ts` (routes), `service.ts` (logic), `model.ts` (data).
51
+ - Shared utilities in `src/common/`.
52
+ - Database schema in `src/db/schema/`.
53
+ - **Environment**: Use `src/common/config.ts` for env vars (Envalid). Do not use `process.env` directly.
54
+ - **Imports**: Use explicit imports.
55
+
56
+ ## Testing Instructions
57
+
58
+ - **Runner**: Use `bun test`.
59
+ - **Location**: Tests are located in `src/tests/`.
60
+ - **Convention**: Name test files `*.test.ts`.
61
+ - **Requirement**: All new features must include unit/integration tests.
62
+ - **Coverage**: Run `bun test --coverage` to check coverage.
63
+
64
+ ## PR Instructions
65
+
66
+ - **Branches**: Target `develop` for features, `main` for releases.
67
+ - **Checks**:
68
+ - Ensure `bun run lint` and `bun test` pass locally before requesting review.
69
+ - **CI/CD**: A GitHub Action workflow ("Lint") automatically runs `bun run lint` on every Push and PR to `main` and `develop`. This check must pass for merging.
70
+ - **Title**: Follow conventional commits (e.g., `feat: add user module`, `fix: resolve login bug`).
71
+
72
+ ## Directory Structure
73
+
74
+ - `src/common`: Shared configuration and utilities.
75
+ - `src/db`: Database setup, migrations, and schemas.
76
+ - `src/modules`: Business logic modules.
77
+ - `src/tests`: Test files.
78
+ - `src/main.ts`: Application entry point.
79
+