Skip to content

Commit 21753e7

Browse files
authored
Merge pull request #2 from truehazker/freature/linter
feat: Add biome linter configuration, CI workflow, and code style improvements
2 parents 5ee5f74 + 9223ac9 commit 21753e7

File tree

22 files changed

+520
-232
lines changed

22 files changed

+520
-232
lines changed

.cursor/mcp.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mcpServers": {
3+
"context7": {
4+
"command": "npx",
5+
"args": ["-y", "@upstash/context7-mcp"]
6+
}
7+
}
8+
}

.github/workflows/lint.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
lint:
11+
name: Biome Lint Check
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Bun
19+
uses: oven-sh/setup-bun@v2
20+
with:
21+
bun-version: latest
22+
23+
- name: Install dependencies
24+
run: bun install --frozen-lockfile
25+
26+
- name: Run Biome linter
27+
run: bun run lint

.vscode/extensions.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"recommendations": [
3+
"biomejs.biome",
4+
"ms-vscode.cmake-tools",
5+
"vivaxy.vscode-conventional-commits"
6+
]
7+
}

.vscode/settings.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"biome.enabled": true,
3+
"biome.requireConfiguration": true,
4+
"biome.lsp.trace.server": "off",
5+
6+
"editor.formatOnSave": true,
7+
"editor.defaultFormatter": "biomejs.biome",
8+
9+
"editor.codeActionsOnSave": {
10+
"source.fixAll.biome": "explicit",
11+
"source.organizeImports.biome": "explicit"
12+
},
13+
14+
"[javascript]": {
15+
"editor.defaultFormatter": "biomejs.biome"
16+
},
17+
"[javascriptreact]": {
18+
"editor.defaultFormatter": "biomejs.biome"
19+
},
20+
"[typescript]": {
21+
"editor.defaultFormatter": "biomejs.biome"
22+
},
23+
"[typescriptreact]": {
24+
"editor.defaultFormatter": "biomejs.biome"
25+
},
26+
"[json]": {
27+
"editor.defaultFormatter": "biomejs.biome"
28+
},
29+
"[jsonc]": {
30+
"editor.defaultFormatter": "biomejs.biome"
31+
}
32+
}

AGENTS.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Added local MCP server configuration
13+
- Added CI lint workflow
14+
- Added Biome-based formatting/linting
15+
- Added VS Code recommendations/settings included
16+
- Added project guidelines and updated changelog
17+
18+
### Fixed
19+
20+
- Improved user-creation error handling with clearer 422 responses and more robust failure checks
21+
22+
### Changed
23+
24+
- Updated dependencies to the latest version
25+
- Updated tests for consistent formatting and interaction patterns
26+
1027
## [0.1.6] - 2025-11-11
1128

1229
### Changed
30+
1331
- Dependencies updated to the latest version
1432
- Fixed the way we define models
1533
- Moved database-related files to `src/db`
1634
- Moved common files to `src/common`
1735
- Removed aliases from `tsconfig.json` as it may interfere with monorepo setups
1836

1937
### Added
38+
2039
- Added `timestamp` prefix to migrations
2140

2241
## [0.1.5] - 2025-09-30
@@ -30,30 +49,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3049
## [0.1.4] - 2025-09-16
3150

3251
### Changed
52+
3353
- Updated packages to the latest version
3454
- Improved `Dockerfile`
3555

3656
## [0.1.2] - 2025-09-14
3757

3858
### Added
59+
3960
- Added test directory to `bunfig.toml`
4061
- Added users test file
4162

4263
### Fixed
64+
4365
- Fixed `LOG_LEVEL` type in `config.ts`
4466
- Fixed mistaken comment in `users/index.ts`
4567

4668
### Changed
69+
4770
- Updated `README.md` with testing information and some badges
4871

4972
## [0.1.1] - 2025-09-14
5073

5174
### Changed
75+
5276
- Removed invalid parameters from `bunfig.toml` and disabled telemetry
5377

5478
## [0.1.0] - 2025-09-14
5579

5680
### Added
81+
5782
- Elysia web framework with TypeScript and Bun runtime
5883
- PostgreSQL database with Drizzle ORM
5984
- User management API endpoints
@@ -66,4 +91,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6691
- Initial users table schema
6792

6893
### Changed
94+
6995
- Updated OpenAPI documentation URLs from `/swagger` to `/openapi`

biome.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.3.6/schema.json",
3+
4+
"vcs": {
5+
"enabled": true,
6+
"clientKind": "git",
7+
"useIgnoreFile": true
8+
},
9+
10+
"files": {
11+
"ignoreUnknown": false
12+
},
13+
14+
"formatter": {
15+
"enabled": true,
16+
"formatWithErrors": false,
17+
"indentStyle": "space",
18+
"indentWidth": 2,
19+
"lineEnding": "lf",
20+
"lineWidth": 80,
21+
"attributePosition": "auto",
22+
"bracketSpacing": true,
23+
"expand": "auto"
24+
},
25+
26+
"linter": {
27+
"enabled": true,
28+
"rules": {
29+
"recommended": true,
30+
"complexity": {
31+
"noStaticOnlyClass": "off"
32+
}
33+
}
34+
},
35+
36+
"javascript": {
37+
"formatter": {
38+
"quoteStyle": "single",
39+
"jsxQuoteStyle": "double",
40+
"quoteProperties": "asNeeded",
41+
"trailingCommas": "all",
42+
"semicolons": "always",
43+
"arrowParentheses": "always",
44+
"bracketSameLine": false,
45+
"attributePosition": "auto",
46+
"expand": "auto"
47+
}
48+
},
49+
50+
"assist": {
51+
"enabled": true,
52+
"actions": {
53+
"source": {
54+
"organizeImports": "on"
55+
}
56+
}
57+
}
58+
}

bun.lock

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,37 @@
1010
"@elysiajs/openapi": "^1.4.11",
1111
"drizzle-orm": "^0.44.7",
1212
"drizzle-typebox": "^0.3.3",
13-
"elysia": "^1.4.15",
13+
"elysia": "^1.4.16",
1414
"envalid": "^8.1.1",
1515
"pg": "^8.16.3",
1616
},
1717
"devDependencies": {
18+
"@biomejs/biome": "2.3.6",
1819
"@types/bun": "^1.3.2",
19-
"drizzle-kit": "^0.31.6",
20+
"drizzle-kit": "^0.31.7",
2021
"pino-pretty": "^13.1.2",
2122
},
2223
},
2324
},
2425
"packages": {
26+
"@biomejs/biome": ["@biomejs/[email protected]", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.6", "@biomejs/cli-darwin-x64": "2.3.6", "@biomejs/cli-linux-arm64": "2.3.6", "@biomejs/cli-linux-arm64-musl": "2.3.6", "@biomejs/cli-linux-x64": "2.3.6", "@biomejs/cli-linux-x64-musl": "2.3.6", "@biomejs/cli-win32-arm64": "2.3.6", "@biomejs/cli-win32-x64": "2.3.6" }, "bin": { "biome": "bin/biome" } }, "sha512-oqUhWyU6tae0MFsr/7iLe++QWRg+6jtUhlx9/0GmCWDYFFrK366sBLamNM7D9Y+c7YSynUFKr8lpEp1r6Sk7eA=="],
27+
28+
"@biomejs/cli-darwin-arm64": ["@biomejs/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P4JWE5d8UayBxYe197QJwyW4ZHp0B+zvRIGCusOm1WbxmlhpAQA1zEqQuunHgSIzvyEEp4TVxiKGXNFZPg7r9Q=="],
29+
30+
"@biomejs/cli-darwin-x64": ["@biomejs/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-I4rTebj+F/L9K93IU7yTFs8nQ6EhaCOivxduRha4w4WEZK80yoZ8OAdR1F33m4yJ/NfUuTUbP/Wjs+vKjlCoWA=="],
31+
32+
"@biomejs/cli-linux-arm64": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-JjYy83eVBnvuINZiqyFO7xx72v8Srh4hsgaacSBCjC22DwM6+ZvnX1/fj8/SBiLuUOfZ8YhU2pfq2Dzakeyg1A=="],
33+
34+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-oK1NpIXIixbJ/4Tcx40cwiieqah6rRUtMGOHDeK2ToT7yUFVEvXUGRKqH0O4hqZ9tW8TcXNZKfgRH6xrsjVtGg=="],
35+
36+
"@biomejs/cli-linux-x64": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-ZjPXzy5yN9wusIoX+8Zp4p6cL8r0NzJCXg/4r1KLVveIPXd2jKVlqZ6ZyzEq385WwU3OX5KOwQYLQsOc788waQ=="],
37+
38+
"@biomejs/cli-linux-x64-musl": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-QvxB8GHQeaO4FCtwJpJjCgJkbHBbWxRHUxQlod+xeaYE6gtJdSkYkuxdKAQUZEOIsec+PeaDAhW9xjzYbwmOFA=="],
39+
40+
"@biomejs/cli-win32-arm64": ["@biomejs/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-YM7hLHpwjdt8R7+O2zS1Vo2cKgqEeptiXB1tWW1rgjN5LlpZovBVKtg7zfwfRrFx3i08aNZThYpTcowpTlczug=="],
41+
42+
"@biomejs/cli-win32-x64": ["@biomejs/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-psgNEYgMAobY5h+QHRBVR9xvg2KocFuBKm6axZWB/aD12NWhQjiVFQUjV6wMXhlH4iT0Q9c3yK5JFRiDC/rzHA=="],
43+
2544
"@bogeychan/elysia-logger": ["@bogeychan/[email protected]", "", { "peerDependencies": { "elysia": ">= 1.2.10", "pino": ">= 9.6.0" } }, "sha512-wFp3KUCNIkCV4zcbo70gifHH99ch7e4LNrP5Xa5e2MRO2MDyPgM92SWQmrzkng6PsSZk13+UKJskGNQ+ZuDZkQ=="],
2645

2746
"@borewit/text-codec": ["@borewit/[email protected]", "", {}, "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA=="],
@@ -118,13 +137,13 @@
118137

119138
"debug": ["[email protected]", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
120139

121-
"drizzle-kit": ["[email protected].6", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-/B4e/4pwnx25QwD5xXgdpo1S+077a2VZdosXbItE/oNmUgQwZydGDz9qJYmnQl/b+5IX0rLfwRhrPnroGtrg8Q=="],
140+
"drizzle-kit": ["[email protected].7", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-hOzRGSdyKIU4FcTSFYGKdXEjFsncVwHZ43gY3WU5Bz9j5Iadp6Rh6hxLSQ1IWXpKLBKt/d5y1cpSPcV+FcoQ1A=="],
122141

123142
"drizzle-orm": ["[email protected]", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ=="],
124143

125144
"drizzle-typebox": ["[email protected]", "", { "peerDependencies": { "@sinclair/typebox": ">=0.34.8", "drizzle-orm": ">=0.36.0" } }, "sha512-iJpW9K+BaP8+s/ImHxOFVjoZk9G5N/KXFTOpWcFdz9SugAOWv2fyGaH7FmqgdPo+bVNYQW0OOI3U9dkFIVY41w=="],
126145

127-
"elysia": ["[email protected].15", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.2.2", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-RaDqqZdLuC4UJetfVRQ4Z5aVpGgEtQ+pZnsbI4ZzEaf3l/MzuHcqSVoL/Fue3d6qE4RV9HMB2rAZaHyPIxkyzg=="],
146+
"elysia": ["[email protected].16", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.2.3", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-KZtKN160/bdWVKg2hEgyoNXY8jRRquc+m6PboyisaLZL891I+Ufb7Ja6lDAD7vMQur8sLEWIcidZOzj5lWw9UA=="],
128147

129148
"end-of-stream": ["[email protected]", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
130149

@@ -134,7 +153,7 @@
134153

135154
"esbuild-register": ["[email protected]", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "esbuild": ">=0.12 <1" } }, "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg=="],
136155

137-
"exact-mirror": ["[email protected].2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-CrGe+4QzHZlnrXZVlo/WbUZ4qQZq8C0uATQVGVgXIrNXgHDBBNFD1VRfssRA2C9t3RYvh3MadZSdg2Wy7HBoQA=="],
156+
"exact-mirror": ["[email protected].3", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-aLdARfO0W0ntufjDyytUJQMbNXoB9g+BbA8KcgIq4XOOTYRw48yUGON/Pr64iDrYNZKcKvKbqE0MPW56FF2BXA=="],
138157

139158
"fast-copy": ["[email protected]", "", {}, "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ=="],
140159

drizzle.config.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import config from "./src/common/config";
2-
import { defineConfig } from "drizzle-kit";
1+
import { defineConfig } from 'drizzle-kit';
2+
import config from './src/common/config';
33

44
export default defineConfig({
55
dialect: 'postgresql',
66
schema: './src/db/schema',
77
out: './src/db/migrations',
88
migrations: {
9-
prefix: 'timestamp'
9+
prefix: 'timestamp',
1010
},
1111
dbCredentials: {
12-
url: config.DATABASE_URL
13-
}
14-
})
12+
url: config.DATABASE_URL,
13+
},
14+
});

0 commit comments

Comments
 (0)