-
-
Notifications
You must be signed in to change notification settings - Fork 26
Create basic architecture #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f280c16
215955f
7f7392c
39c46b7
1eca5f7
a707ce9
0289553
a382257
36156f4
bbc21ac
fa32133
5da2429
1494030
8ea43b3
1f899f7
54807be
006ccd1
5ed556f
d48b86c
d8101c4
d41849b
84bf9f9
b4981ed
05ffbab
3d58075
31d0e15
0a91f6b
6653a37
1baf9b7
4cbf9c2
10e8571
7d0829e
45cf1cb
f0f8d5c
727d5e2
57dce97
2c5595c
6859421
607910f
67f12f7
1f4d3c8
33f5fcc
30a7a57
bc83e71
e61a1b7
f0c8645
540e60a
08076bf
afa52ec
e4dce34
c7379ab
831d593
243b2e0
ec1230a
9e3fcd6
b022486
58e0380
d7c2cd3
fb902bc
a39812c
a460b70
7d1a0e9
a43ea65
04c1b13
2cd901d
9993ede
c4fac81
7110c13
5502682
238698a
66f3664
f88fd1c
5529b8d
0ea8f26
3703d87
02ffde1
fb82c1e
e5a6775
256bb38
a15de0b
6c24c39
81d5950
a84e0a3
dfde7ee
abe4809
3ad48a0
044baea
e1ee800
0366dac
8897a41
ec8005f
3a6dfa5
95a1b1d
776086b
59d9484
6bce950
c2c0f86
5cd29c8
4031f28
26acff6
ccbecd4
1e16652
c6e7cd9
43136ed
1af3f0a
8fb8618
6eb86ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Must always set to production | ||
# @see {@link https://www.youtube.com/watch?v=HMM7GJC5E2o} | ||
NODE_ENV=production | ||
|
||
# Database | ||
MYSQL_HOST=localhost | ||
MYSQL_PORT=3306 | ||
MYSQL_DATABASE=test_db | ||
MYSQL_USER=test_user | ||
MYSQL_PASSWORD=test_password | ||
|
||
# Server | ||
FASTIFY_CLOSE_GRACE_DELAY=1000 | ||
LOG_LEVEL=info | ||
|
||
# Security | ||
JWT_SECRET= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
version: 2 | ||
updates: | ||
- package-ecosystem: "github-actions" | ||
directory: "/" | ||
schedule: | ||
interval: "monthly" | ||
open-pull-requests-limit: 10 | ||
|
||
- package-ecosystem: "npm" | ||
directory: "/" | ||
schedule: | ||
interval: "weekly" | ||
open-pull-requests-limit: 10 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Number of days of inactivity before an issue becomes stale | ||
daysUntilStale: 15 | ||
# Number of days of inactivity before a stale issue is closed | ||
daysUntilClose: 7 | ||
# Issues with these labels will never be considered stale | ||
exemptLabels: | ||
- "discussion" | ||
- "feature request" | ||
- "bug" | ||
- "help wanted" | ||
- "plugin suggestion" | ||
- "good first issue" | ||
# Label to use when marking an issue as stale | ||
staleLabel: stale | ||
# Comment to post when marking an issue as stale. Set to `false` to disable | ||
markComment: > | ||
This issue has been automatically marked as stale because it has not had | ||
recent activity. It will be closed if no further activity occurs. Thank you | ||
for your contributions. | ||
# Comment to post when closing a stale issue. Set to `false` to disable | ||
closeComment: false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
- next | ||
- "v*" | ||
paths-ignore: | ||
- "docs/**" | ||
- "*.md" | ||
pull_request: | ||
paths-ignore: | ||
- "docs/**" | ||
- "*.md" | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: [22] | ||
|
||
services: | ||
mysql: | ||
image: mysql:8.4 | ||
ports: | ||
- 3306:3306 | ||
env: | ||
MYSQL_ROOT_PASSWORD: root_password | ||
MYSQL_DATABASE: test_db | ||
MYSQL_USER: test_user | ||
MYSQL_PASSWORD: test_password | ||
options: >- | ||
--health-cmd="mysqladmin ping -u$MYSQL_USER -p$MYSQL_PASSWORD" | ||
--health-interval=10s | ||
--health-timeout=5s | ||
--health-retries=3 | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
|
||
- name: Install dependencies | ||
run: npm i | ||
|
||
- name: Lint Code | ||
run: npm run lint | ||
|
||
- name: Generate JWT Secret | ||
id: gen-jwt | ||
run: | | ||
JWT_SECRET=$(openssl rand -hex 32) | ||
echo "JWT_SECRET=$JWT_SECRET" >> $GITHUB_ENV | ||
|
||
- name: Generate dummy .env for scripts using -env-file=.env flag | ||
run: touch .env | ||
|
||
- name: Test | ||
env: | ||
MYSQL_HOST: localhost | ||
MYSQL_PORT: 3306 | ||
MYSQL_DATABASE: test_db | ||
MYSQL_USER: test_user | ||
MYSQL_PASSWORD: test_password | ||
# JWT_SECRET is dynamically generated and loaded from the environment | ||
run: npm run db:migrate && npm run test |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Auth } from "../../src/schemas/auth.ts"; | ||
|
||
declare module "fastify" { | ||
export interface FastifyRequest { | ||
user: Auth | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
declare global { | ||
namespace NodeJS { | ||
interface ProcessEnv { | ||
PORT: number; | ||
LOG_LEVEL: string; | ||
FASTIFY_CLOSE_GRACE_DELAY: number; | ||
MYSQL_HOST: string | ||
MYSQL_PORT: number | ||
MYSQL_DATABASE: string | ||
MYSQL_USER: string | ||
MYSQL_PASSWORD: string | ||
} | ||
} | ||
} | ||
|
||
export {}; |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will be nice here to develop a bit more about the methodology or decisions made that lead to this repository; that backstory sometimes helps companies to decide wether or not to adopt a given technology (I've faced that in the past) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,39 @@ | ||
# demo | ||
# Fastify Official Demo | ||
|
||
 | ||
[](https://standardjs.com/) | ||
|
||
> :warning: **Please note:** This repository is still under active development. | ||
|
||
The aim of this repository is to provide a concrete example of a Fastify application using what are considered best practices by the Fastify community. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe explain which Fastify plugins are part of this demo? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need to maintain a list of plugins used in the doc. To be honest, I'm not really sure what the documentation should contain, although I'm aware that I should be working on it. IMO, I think it should be very minimalist, explaining the purpose of the demo and how to configure the application. The purpose of the demo is to show concrete code, so people should look at the code and comments. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK then not |
||
**Prerequisites:** You need to have Node.js version 22 or higher installed. | ||
|
||
## Getting started | ||
|
||
Install the dependencies: | ||
|
||
```bash | ||
npm install | ||
``` | ||
|
||
## Available Scripts | ||
|
||
In the project directory, you can run: | ||
|
||
### `npm run dev` | ||
|
||
To start the app in dev mode.\ | ||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser. | ||
|
||
### `npm start` | ||
|
||
For production mode | ||
|
||
### `npm run test` | ||
|
||
Run the test cases. | ||
|
||
## Learn More | ||
|
||
To learn Fastify, check out the [Fastify documentation](https://fastify.dev/docs/latest/). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
services: | ||
db: | ||
image: mysql:8.4 | ||
environment: | ||
MYSQL_DATABASE: ${MYSQL_DATABASE} | ||
MYSQL_USER: ${MYSQL_USER} | ||
MYSQL_PASSWORD: ${MYSQL_PASSWORD} | ||
ports: | ||
- 3306:3306 | ||
volumes: | ||
- db_data:/var/lib/mysql | ||
|
||
volumes: | ||
db_data: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
'use strict' | ||
|
||
import neo from 'neostandard' | ||
|
||
export default [ | ||
...neo({ | ||
ts: true | ||
}), | ||
{ | ||
rules: { | ||
'@stylistic/comma-dangle': ['error', { | ||
arrays: 'never', | ||
objects: 'never', | ||
imports: 'never', | ||
exports: 'never', | ||
functions: 'never' | ||
}] | ||
} | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CREATE TABLE users ( | ||
id INT AUTO_INCREMENT PRIMARY KEY, | ||
username VARCHAR(255) NOT NULL, | ||
password VARCHAR(255) NOT NULL, | ||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE IF EXISTS users; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
CREATE TABLE tasks ( | ||
id INT AUTO_INCREMENT PRIMARY KEY, | ||
name VARCHAR(255) NOT NULL, | ||
author_id INT NOT NULL, | ||
assigned_user_id INT, | ||
status VARCHAR(50) NOT NULL, | ||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | ||
FOREIGN KEY (author_id) REFERENCES users(id), | ||
FOREIGN KEY (assigned_user_id) REFERENCES users(id) | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE IF EXISTS tasks; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CREATE TABLE user_tasks ( | ||
user_id INT NOT NULL, | ||
task_id INT NOT NULL, | ||
PRIMARY KEY (user_id, task_id), | ||
FOREIGN KEY (user_id) REFERENCES users(id), | ||
FOREIGN KEY (task_id) REFERENCES tasks(id) | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE IF EXISTS user_tasks; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{ | ||
"name": "fastify-demo", | ||
"version": "0.0.0", | ||
"description": "The official Fastify demo!", | ||
"main": "app.js", | ||
"type": "module", | ||
"directories": { | ||
"test": "test" | ||
}, | ||
"scripts": { | ||
"build": "rm -rf dist && tsc", | ||
"watch": "npm run build -- --watch", | ||
"test": "npm run db:seed && tap --jobs=1 test/**/*", | ||
"start": "fastify start -l info dist/app.js", | ||
"dev": "fastify start -w -l info -P dist/app.js", | ||
"standalone": "node --env-file=.env dist/server.js", | ||
"lint": "eslint --ignore-pattern=dist", | ||
"lint:fix": "npm run lint -- --fix", | ||
"db:migrate": "node --env-file=.env scripts/migrate.js", | ||
"db:seed": "node --env-file=.env scripts/seed-database.js" | ||
}, | ||
"keywords": [], | ||
"author": "Michelet Jean <[email protected]>", | ||
"license": "MIT", | ||
"dependencies": { | ||
"@fastify/autoload": "^5.10.0", | ||
"@fastify/cors": "^9.0.1", | ||
"@fastify/env": "^4.3.0", | ||
"@fastify/helmet": "^11.1.1", | ||
"@fastify/jwt": "^8.0.1", | ||
"@fastify/mysql": "^4.3.0", | ||
"@fastify/sensible": "^5.0.0", | ||
"@fastify/swagger": "^8.14.0", | ||
"@fastify/swagger-ui": "^3.0.0", | ||
"@fastify/type-provider-typebox": "^4.0.0", | ||
"@fastify/under-pressure": "^8.3.0", | ||
"@sinclair/typebox": "^0.32.31", | ||
"fastify": "^4.26.1", | ||
"fastify-cli": "^6.1.1", | ||
"fastify-plugin": "^4.0.0", | ||
"postgrator": "^7.2.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.14.2", | ||
"eslint": "^9.4.0", | ||
"fastify-tsconfig": "^2.0.0", | ||
"mysql2": "^3.10.1", | ||
"neostandard": "^0.7.0", | ||
"tap": "^19.2.2", | ||
"typescript": "^5.4.5" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import mysql from 'mysql2/promise' | ||
import path from 'path' | ||
import Postgrator from 'postgrator' | ||
|
||
async function doMigration () { | ||
const connection = await mysql.createConnection({ | ||
multipleStatements: true, | ||
host: process.env.MYSQL_HOST, | ||
port: process.env.MYSQL_PORT, | ||
database: process.env.MYSQL_DATABASE, | ||
user: process.env.MYSQL_USER, | ||
password: process.env.MYSQL_PASSWORD | ||
}) | ||
|
||
const postgrator = new Postgrator({ | ||
migrationPattern: path.join(import.meta.dirname, '../migrations', '*'), | ||
driver: 'mysql', | ||
database: process.env.MYSQL_DATABASE, | ||
execQuery: async (query) => { | ||
const [rows, fields] = await connection.query(query) | ||
|
||
return { rows, fields } | ||
}, | ||
schemaTable: 'schemaversion' | ||
}) | ||
|
||
await postgrator.migrate() | ||
|
||
await new Promise((resolve, reject) => { | ||
connection.end((err) => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
resolve() | ||
}) | ||
}) | ||
} | ||
|
||
doMigration().catch(err => console.error(err)) |
Uh oh!
There was an error while loading. Please reload this page.