Skip to content

Commit 1ba51d3

Browse files
committed
Add prisma and a fake new user route
1 parent 19b72f0 commit 1ba51d3

File tree

11 files changed

+144
-14
lines changed

11 files changed

+144
-14
lines changed

.github/workflows/jest-tests.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ jobs:
1616
run:
1717
working-directory: ./api
1818

19+
services:
20+
postgres:
21+
image: postgres:14
22+
env:
23+
POSTGRES_USER: postgres
24+
POSTGRES_PASSWORD: postgres
25+
POSTGRES_DB: testing
26+
ports:
27+
- 5432:5432
28+
options: >-
29+
--health-cmd pg_isready
30+
--health-interval 10s
31+
--health-timeout 5s
32+
--health-retries 5
33+
1934
steps:
2035
- name: Checkout code
2136
uses: actions/checkout@v3
@@ -28,5 +43,15 @@ jobs:
2843
- name: Install dependencies
2944
run: npm install
3045

46+
- name: Generate Prisma Client
47+
run: npx prisma generate
48+
49+
- name: Run Prisma Migrations
50+
run: npx prisma migrate deploy
51+
env:
52+
DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/testing?schema=public'
53+
3154
- name: Run Jest tests
3255
run: npm test
56+
env:
57+
DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/testing?schema=public'

api/package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"license": "ISC",
2323
"dependencies": {
2424
"@aws-sdk/client-ec2": "^3.699.0",
25+
"@faker-js/faker": "^9.2.0",
2526
"@fastify/autoload": "^6.0.0",
2627
"@fastify/sensible": "^6.0.0",
2728
"@prisma/client": "^5.22.0",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
Warnings:
3+
4+
- Added the required column `password` to the `User` table without a default value. This is not possible if the table is not empty.
5+
- Made the column `name` on table `User` required. This step will fail if there are existing NULL values in that column.
6+
7+
*/
8+
-- AlterTable
9+
ALTER TABLE "User" ADD COLUMN "password" TEXT NOT NULL,
10+
ALTER COLUMN "name" SET NOT NULL;

api/prisma/schema.prisma

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ datasource db {
1414
}
1515

1616
model User {
17-
id Int @id @default(autoincrement())
18-
email String @unique
19-
name String?
17+
id Int @id @default(autoincrement())
18+
email String @unique
19+
name String
20+
password String
2021
}

api/src/app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module.exports.options = options;
3636

3737
// Start the Fastify server
3838
const start = async () => {
39+
// Set logger options based on environment
3940
const envToLogger: EnvToLogger = {
4041
development: {
4142
transport: {
@@ -51,6 +52,7 @@ const start = async () => {
5152
};
5253
const fastify = require('fastify')({
5354
logger: envToLogger[process.env.NODE_ENV || 'development'],
55+
ignoreTrailingSlash: true, // Ignore trailing slashes at the end of URLs
5456
});
5557

5658
try {

api/src/handlers/user.handler.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { FastifyReply, FastifyRequest } from 'fastify';
2+
import { getAllUserNames } from '../services/user.service';
3+
import { createUser } from '../services/user.service';
4+
5+
export async function getUsersHandler(
6+
request: FastifyRequest,
7+
reply: FastifyReply,
8+
) {
9+
try {
10+
reply.send(await getAllUserNames());
11+
} catch (error) {
12+
reply.status(500).send({ error: 'An error occurred' });
13+
}
14+
}
15+
export async function createUserHandler(
16+
request: FastifyRequest,
17+
reply: FastifyReply,
18+
) {
19+
try {
20+
const user = await createUser();
21+
reply.status(201).send(user);
22+
} catch (error) {
23+
reply.status(500).send({ error: 'An error occurred' });
24+
}
25+
}

api/src/lib/prisma.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { PrismaClient } from '@prisma/client';
2+
3+
// Prevent multiple instances in development due to hot reloading
4+
declare global {
5+
var prisma: PrismaClient | undefined;
6+
}
7+
8+
// Create singleton instance
9+
export const prisma = global.prisma || new PrismaClient();
10+
11+
if (process.env.NODE_ENV !== 'production') {
12+
global.prisma = prisma;
13+
}

api/src/routes/user.route.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { FastifyInstance } from 'fastify';
2+
import { createUserHandler, getUsersHandler } from '../handlers/user.handler';
3+
4+
export default async function userRoutes(fastify: FastifyInstance) {
5+
fastify.route({
6+
method: 'GET',
7+
url: '/user',
8+
handler: getUsersHandler,
9+
});
10+
fastify.route({
11+
method: 'POST',
12+
url: '/user',
13+
handler: createUserHandler,
14+
});
15+
}

api/src/services/user.service.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { prisma } from '../lib/prisma';
2+
import { faker } from '@faker-js/faker';
3+
4+
export async function getAllUserNames() {
5+
const users = await prisma.user.findMany({
6+
select: {
7+
name: true,
8+
},
9+
});
10+
return users.map((user) => user.name);
11+
}
12+
export async function createUser() {
13+
const user = await prisma.user.create({
14+
data: {
15+
name: faker.person.fullName(),
16+
email: faker.internet.email(),
17+
password: faker.internet.password(),
18+
},
19+
});
20+
return user;
21+
}

0 commit comments

Comments
 (0)