Refactor general pour ajout d'un flow CI/CD

This commit is contained in:
Florian Sylvain
2023-02-09 20:05:33 +01:00
parent ff0cb60890
commit 6998217399
18 changed files with 298 additions and 201 deletions
+5
View File
@@ -0,0 +1,5 @@
.dockerignore
node_modules
.vscode
+1
View File
@@ -1,3 +1,4 @@
node_modules node_modules
mysql-data
# Keep environment variables out of version control # Keep environment variables out of version control
.env .env
+13
View File
@@ -0,0 +1,13 @@
FROM node:lts-hydrogen
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY .env ./
ADD src ./src/
ADD prisma ./prisma/
RUN npm ci
RUN npx prisma generate
CMD npm start
+19 -2
View File
@@ -1,3 +1,20 @@
Dans le point env : # POPCORN
- DataBase_url : donc le lien vers une base mysql
## Variables d'environnement
```
DATABASE_URL=donc le lien vers une base mysql (⚠️ pas nécessaire si lancé avec Docker)
API_PORT=port de l'API
CORS_ORIGIN=adresse autorisée pour les CORS
MYSQL_ROOT_PASSWORD=mot de passe du root MYSQL (⚠️ pas nécessaire si lancé sans Docker)
```
## Utilisation avec Docker
Penser à bien définir les variables d'environnement dans un .env à la racine du projet.
### Build & start
```
docker-compose up --build -d
```
-25
View File
@@ -1,25 +0,0 @@
import express from "express";
import { PrismaClient } from "@prisma/client";
import createError from "http-errors"
import cors from 'cors';
import jeux from './route/jeux.js'
import groupe from './route/groupe.js'
const app = express()
app.use(express.json())
app.use(express.urlencoded({extended:true}))
const port = 3500
app.use(
cors({
origin: ["http://127.0.0.1:5500"],
})
);
app.use('/',jeux)
app.use('/',groupe)
// run the server
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
+36
View File
@@ -0,0 +1,36 @@
services:
db:
image: mysql:oracle
env_file:
- .env
networks:
- back-net
environment:
- "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}"
- "MYSQL_DATABASE=popcorn"
volumes:
- ./mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3306"]
interval: 3s
timeout: 30s
retries: 10
ports:
- "3306:3306"
backend:
depends_on:
db:
condition: service_healthy
build: .
image: popcorn-backend
env_file:
- .env
environment:
- "DATABASE_URL=mysql://root:${MYSQL_ROOT_PASSWORD}@db:3306/popcorn"
networks:
- back-net
ports:
- "${API_PORT}:${API_PORT}"
networks:
back-net:
-10
View File
@@ -1,10 +0,0 @@
import { optional, string, z } from "zod";
const groupeValidation = z.object({
id : z.number().optional(),
name : z.string(),
logo : z.string(),
});
export default groupeValidation;
-13
View File
@@ -1,13 +0,0 @@
import { optional, string, z } from "zod";
const jeuxValidation = z.object({
id : z.number().optional(),
Title : z.string(),
Description : z.string(),
Picture: z.string(),
lien : z.string(),
groupe_id : z.number()
});
export default jeuxValidation;
+50 -30
View File
@@ -9,25 +9,28 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@prisma/client": "^4.9.0", "@prisma/client": "^4.10.0",
"cloudinary": "^1.33.0", "cloudinary": "^1.33.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2", "express": "^4.18.2",
"http-errors": "^2.0.0", "http-errors": "^2.0.0",
"https-error": "^1.0.2", "https-error": "^1.0.2",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"nodemon": "^2.0.20", "nodemon": "^2.0.20",
"prisma": "^4.9.0",
"zod": "^3.20.2" "zod": "^3.20.2"
},
"devDependencies": {
"prisma": "^4.10.0"
} }
}, },
"node_modules/@prisma/client": { "node_modules/@prisma/client": {
"version": "4.9.0", "version": "4.10.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.9.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.10.0.tgz",
"integrity": "sha512-bz6QARw54sWcbyR1lLnF2QHvRW5R/Jxnbbmwh3u+969vUKXtBkXgSgjDA85nji31ZBlf7+FrHDy5x+5ydGyQDg==", "integrity": "sha512-sBmYb1S6SMKFIESaLMfKqWSalv3pH73cMCsFt9HslJvYjIIcKQCA6PDL2O4SZGWvc4JBef9cg5Gd7d9x3AtKjw==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@prisma/engines-version": "4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5" "@prisma/engines-version": "4.10.0-84.ca7fcef713137fa11029d519a9780db130cca91d"
}, },
"engines": { "engines": {
"node": ">=14.17" "node": ">=14.17"
@@ -42,15 +45,16 @@
} }
}, },
"node_modules/@prisma/engines": { "node_modules/@prisma/engines": {
"version": "4.9.0", "version": "4.10.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.9.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.10.0.tgz",
"integrity": "sha512-t1pt0Gsp+HcgPJrHFc+d/ZSAaKKWar2G/iakrE07yeKPNavDP3iVKPpfXP22OTCHZUWf7OelwKJxQgKAm5hkgw==", "integrity": "sha512-ZPPo7q+nQZdTlPFedS7mFXPE3oZ2kWtTh3GO4sku0XQ8ikLqEyinuTPJbQCw/8qel2xglIEQicsK6yI4Jgh20A==",
"devOptional": true,
"hasInstallScript": true "hasInstallScript": true
}, },
"node_modules/@prisma/engines-version": { "node_modules/@prisma/engines-version": {
"version": "4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5", "version": "4.10.0-84.ca7fcef713137fa11029d519a9780db130cca91d",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5.tgz", "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.10.0-84.ca7fcef713137fa11029d519a9780db130cca91d.tgz",
"integrity": "sha512-M16aibbxi/FhW7z1sJCX8u+0DriyQYY5AyeTH7plQm9MLnURoiyn3CZBqAyIoQ+Z1pS77usCIibYJWSgleBMBA==" "integrity": "sha512-UVpmVlvSaGfY4ue+hh8CTkIesbuXCFUfrr8zk//+u85WwkKfWMtt6nLB2tNSzR1YO8eAA8+HqNf8LM7mnXIq5w=="
}, },
"node_modules/@tootallnate/once": { "node_modules/@tootallnate/once": {
"version": "1.1.2", "version": "1.1.2",
@@ -476,6 +480,14 @@
"npm": "1.2.8000 || >= 1.4.16" "npm": "1.2.8000 || >= 1.4.16"
} }
}, },
"node_modules/dotenv": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
"engines": {
"node": ">=12"
}
},
"node_modules/ee-first": { "node_modules/ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -1325,12 +1337,13 @@
} }
}, },
"node_modules/prisma": { "node_modules/prisma": {
"version": "4.9.0", "version": "4.10.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-4.9.0.tgz", "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.10.0.tgz",
"integrity": "sha512-bS96oZ5oDFXYgoF2l7PJ3Mp1wWWfLOo8B/jAfbA2Pn0Wm5Z/owBHzaMQKS3i1CzVBDWWPVnOohmbJmjvkcHS5w==", "integrity": "sha512-xUHcF3Glc8QGgW8x0rfPITvyyTo04fskUdG7pI4kQbvDX/rhzDP4046x/FvazYqYHXMLR5/KTIi2p2Gth5vKOQ==",
"devOptional": true,
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@prisma/engines": "4.9.0" "@prisma/engines": "4.10.0"
}, },
"bin": { "bin": {
"prisma": "build/index.js", "prisma": "build/index.js",
@@ -1865,22 +1878,23 @@
}, },
"dependencies": { "dependencies": {
"@prisma/client": { "@prisma/client": {
"version": "4.9.0", "version": "4.10.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.9.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.10.0.tgz",
"integrity": "sha512-bz6QARw54sWcbyR1lLnF2QHvRW5R/Jxnbbmwh3u+969vUKXtBkXgSgjDA85nji31ZBlf7+FrHDy5x+5ydGyQDg==", "integrity": "sha512-sBmYb1S6SMKFIESaLMfKqWSalv3pH73cMCsFt9HslJvYjIIcKQCA6PDL2O4SZGWvc4JBef9cg5Gd7d9x3AtKjw==",
"requires": { "requires": {
"@prisma/engines-version": "4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5" "@prisma/engines-version": "4.10.0-84.ca7fcef713137fa11029d519a9780db130cca91d"
} }
}, },
"@prisma/engines": { "@prisma/engines": {
"version": "4.9.0", "version": "4.10.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.9.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.10.0.tgz",
"integrity": "sha512-t1pt0Gsp+HcgPJrHFc+d/ZSAaKKWar2G/iakrE07yeKPNavDP3iVKPpfXP22OTCHZUWf7OelwKJxQgKAm5hkgw==" "integrity": "sha512-ZPPo7q+nQZdTlPFedS7mFXPE3oZ2kWtTh3GO4sku0XQ8ikLqEyinuTPJbQCw/8qel2xglIEQicsK6yI4Jgh20A==",
"devOptional": true
}, },
"@prisma/engines-version": { "@prisma/engines-version": {
"version": "4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5", "version": "4.10.0-84.ca7fcef713137fa11029d519a9780db130cca91d",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5.tgz", "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.10.0-84.ca7fcef713137fa11029d519a9780db130cca91d.tgz",
"integrity": "sha512-M16aibbxi/FhW7z1sJCX8u+0DriyQYY5AyeTH7plQm9MLnURoiyn3CZBqAyIoQ+Z1pS77usCIibYJWSgleBMBA==" "integrity": "sha512-UVpmVlvSaGfY4ue+hh8CTkIesbuXCFUfrr8zk//+u85WwkKfWMtt6nLB2tNSzR1YO8eAA8+HqNf8LM7mnXIq5w=="
}, },
"@tootallnate/once": { "@tootallnate/once": {
"version": "1.1.2", "version": "1.1.2",
@@ -2208,6 +2222,11 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
}, },
"dotenv": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
},
"ee-first": { "ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -2840,11 +2859,12 @@
"optional": true "optional": true
}, },
"prisma": { "prisma": {
"version": "4.9.0", "version": "4.10.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-4.9.0.tgz", "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.10.0.tgz",
"integrity": "sha512-bS96oZ5oDFXYgoF2l7PJ3Mp1wWWfLOo8B/jAfbA2Pn0Wm5Z/owBHzaMQKS3i1CzVBDWWPVnOohmbJmjvkcHS5w==", "integrity": "sha512-xUHcF3Glc8QGgW8x0rfPITvyyTo04fskUdG7pI4kQbvDX/rhzDP4046x/FvazYqYHXMLR5/KTIi2p2Gth5vKOQ==",
"devOptional": true,
"requires": { "requires": {
"@prisma/engines": "4.9.0" "@prisma/engines": "4.10.0"
} }
}, },
"process-nextick-args": { "process-nextick-args": {
+8 -5
View File
@@ -1,14 +1,14 @@
{ {
"dependencies": { "dependencies": {
"@prisma/client": "^4.9.0", "@prisma/client": "^4.10.0",
"cloudinary": "^1.33.0", "cloudinary": "^1.33.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2", "express": "^4.18.2",
"http-errors": "^2.0.0", "http-errors": "^2.0.0",
"https-error": "^1.0.2", "https-error": "^1.0.2",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"nodemon": "^2.0.20", "nodemon": "^2.0.20",
"prisma": "^4.9.0",
"zod": "^3.20.2" "zod": "^3.20.2"
}, },
"name": "popcorn", "name": "popcorn",
@@ -17,8 +17,8 @@
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "nodemon app.js", "start": "npx prisma migrate deploy && node src/app.js",
"dev": "nodemon app.js", "dev": "nodemon src/app.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"repository": { "repository": {
@@ -30,5 +30,8 @@
"bugs": { "bugs": {
"url": "https://github.com/scotty974/PopCorn/issues" "url": "https://github.com/scotty974/PopCorn/issues"
}, },
"homepage": "https://github.com/scotty974/PopCorn#readme" "homepage": "https://github.com/scotty974/PopCorn#readme",
"devDependencies": {
"prisma": "^4.10.0"
}
} }
+11 -11
View File
@@ -10,19 +10,19 @@ datasource db {
url = env("DATABASE_URL") url = env("DATABASE_URL")
} }
model Groupe{ model Groupe {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
name String name String
logo String @db.VarChar(255) logo String @db.VarChar(255)
jeux Jeux [] jeux Jeux[]
} }
model Jeux{
id Int @id @default(autoincrement())
Title String
Description String
Picture String @db.VarChar(255)
lien String
groupe_id Int
groupe Groupe @relation(fields: [groupe_id], references: [id])
model Jeux {
id Int @id @default(autoincrement())
Title String
Description String
Picture String @db.VarChar(255)
lien String
groupe_id Int
groupe Groupe @relation(fields: [groupe_id], references: [id])
} }
-81
View File
@@ -1,81 +0,0 @@
import express from "express";
import { PrismaClient } from "@prisma/client";
import createError from "http-errors"
import jeuxValidation from "../jeuxValidator.js";
const router = express.Router()
const prisma = new PrismaClient();
router.patch('/upload',async(req,res,next)=>{
let modifyData;
try{
modifyData = jeuxValidation.parse(req.body)
}catch(error){
return res.status(400).json({ errors: error.issues })
}
const id = await prisma.jeux.findFirst({
where:{
id : modifyData.id
}
})
// on va verifier si le mail de la personne est bon , sinon il peut pas modifier son mot de passe
if(!id) return next(createError(200, "Vérifiez l'existence de ce jeux "));
await prisma.jeux.update({
where:{
id : modifyData.id
},
data:{
Title : modifyData.Title,
Description : modifyData.Description,
Picture : modifyData.Picture,
lien : modifyData.lien,
groupe:{
connect:{
id : modifyData.groupe_id
}
}
}
})
.then(()=>{
res.json({"message" : "Modification de la page"})
})
})
router.post('/jeux',async (req,res,next)=>{
let jeuxData;
jeuxData = jeuxValidation.parse(req.body)
let jeux = await prisma.jeux.create({
data:{
Title : jeuxData.Title,
Description : jeuxData.Description,
Picture : jeuxData.Picture,
lien : jeuxData.lien,
groupe:{
connect:{
id : jeuxData.groupe_id
}
}
}
})
res.json(jeux)
console.log(jeux)
})
router.get('/jeux', async(req,res)=>{
let jeux = await prisma.jeux.findMany({
include:{
groupe:true
}
})
res.json(jeux)
})
export default router;
+27
View File
@@ -0,0 +1,27 @@
import express from "express";
import cors from 'cors';
import jeux from './route/jeux.js'
import groupe from './route/groupe.js'
import * as dotenv from 'dotenv'
dotenv.config()
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
const port = process.env.API_PORT
app.use(
cors({
origin: [process.env.CORS_ORIGIN ?? '*'],
})
);
app.use('/', jeux)
app.use('/', groupe)
// run the server
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
+10
View File
@@ -0,0 +1,10 @@
import { z } from "zod";
const groupeValidation = z.object({
id: z.number().optional(),
name: z.string(),
logo: z.string(),
});
export default groupeValidation;
+13
View File
@@ -0,0 +1,13 @@
import { z } from "zod";
const jeuxValidation = z.object({
id: z.number().optional(),
Title: z.string(),
Description: z.string(),
Picture: z.string(),
lien: z.string(),
groupe_id: z.number()
});
export default jeuxValidation;
+24 -24
View File
@@ -6,46 +6,46 @@ import groupeValidation from "../groupeValidator.js";
const router = express.Router() const router = express.Router()
const prisma = new PrismaClient(); const prisma = new PrismaClient();
router.patch('/uploadGroupe',async(req,res,next)=>{ router.patch('/uploadGroupe', async (req, res, next) => {
let modifyData; let modifyData;
try{ try {
modifyData = groupeValidation.parse(req.body) modifyData = groupeValidation.parse(req.body)
}catch(error){ } catch (error) {
return res.status(400).json({ errors: error.issues }) return res.status(400).json({ errors: error.issues })
} }
const id = await prisma.groupe.findFirst({ const id = await prisma.groupe.findFirst({
where:{ where: {
id : modifyData.id id: modifyData.id
} }
}) })
// on va verifier si le mail de la personne est bon , sinon il peut pas modifier son mot de passe // on va verifier si le mail de la personne est bon , sinon il peut pas modifier son mot de passe
if(!id) return next(createError(200, "Vérifiez l'existence de ce groupe ")); if (!id) return next(createError(200, "Vérifiez l'existence de ce groupe "));
await prisma.groupe.update({ await prisma.groupe.update({
where:{ where: {
id : modifyData.id id: modifyData.id
}, },
data:{ data: {
name : modifyData.name, name: modifyData.name,
logo : modifyData.logo logo: modifyData.logo
} }
}) })
.then(()=>{ .then(() => {
res.json({"message" : "Modification de la page"}) res.json({ "message": "Modification de la page" })
}) })
}) })
router.post('/groupe', async(req,res)=>{ router.post('/groupe', async (req, res) => {
let groupData; let groupData;
groupData = groupeValidation.parse(req.body) groupData = groupeValidation.parse(req.body)
let group = await prisma.groupe.create({ let group = await prisma.groupe.create({
data:{ data: {
name : groupData.name, name: groupData.name,
logo : groupData.logo, logo: groupData.logo,
} }
}) })
res.json(group) res.json(group)
}) })
+81
View File
@@ -0,0 +1,81 @@
import express from "express";
import { PrismaClient } from "@prisma/client";
import createError from "http-errors"
import jeuxValidation from "../jeuxValidator.js";
const router = express.Router()
const prisma = new PrismaClient();
router.patch('/upload', async (req, res, next) => {
let modifyData;
try {
modifyData = jeuxValidation.parse(req.body)
} catch (error) {
return res.status(400).json({ errors: error.issues })
}
const id = await prisma.jeux.findFirst({
where: {
id: modifyData.id
}
})
// on va verifier si le mail de la personne est bon , sinon il peut pas modifier son mot de passe
if (!id) return next(createError(200, "Vérifiez l'existence de ce jeux "));
await prisma.jeux.update({
where: {
id: modifyData.id
},
data: {
Title: modifyData.Title,
Description: modifyData.Description,
Picture: modifyData.Picture,
lien: modifyData.lien,
groupe: {
connect: {
id: modifyData.groupe_id
}
}
}
})
.then(() => {
res.json({ "message": "Modification de la page" })
})
})
router.post('/jeux', async (req, res, next) => {
let jeuxData;
jeuxData = jeuxValidation.parse(req.body)
let jeux = await prisma.jeux.create({
data: {
Title: jeuxData.Title,
Description: jeuxData.Description,
Picture: jeuxData.Picture,
lien: jeuxData.lien,
groupe: {
connect: {
id: jeuxData.groupe_id
}
}
}
})
res.json(jeux)
console.log(jeux)
})
router.get('/jeux', async (req, res) => {
let jeux = await prisma.jeux.findMany({
include: {
groupe: true
}
})
res.json(jeux)
})
export default router;