├── .gitignore ├── prisma ├── migrations │ ├── 20220730121914_v2 │ │ └── migration.sql │ ├── migration_lock.toml │ ├── 20220730103229_v1 │ │ └── migration.sql │ ├── 20220730122333_v3 │ │ └── migration.sql │ └── 20220730100130_init │ │ └── migration.sql └── schema.prisma ├── src ├── repository │ ├── link │ │ ├── ILinkRepository.ts │ │ └── LinkRepository.ts │ ├── project │ │ ├── IProjectRepository.ts │ │ └── ProjectRepository.ts │ ├── education │ │ ├── IEducationRepository.ts │ │ └── EducationRepository.ts │ ├── deployments │ │ ├── IDeploymentsRepository.ts │ │ └── DeploymentsRepository.ts │ ├── certificate │ │ ├── ICertificateRepository.ts │ │ └── CertificateRepository.ts │ └── workExperience │ │ ├── IWorkExperienceRepository.ts │ │ └── WorkExperienceRepository.ts ├── Server.ts ├── model │ ├── Activity.ts │ ├── Technology.ts │ ├── Responsibility.ts │ ├── Location.ts │ ├── Link.ts │ ├── ProjectLink.ts │ ├── Deployment.ts │ ├── Certificate.ts │ ├── Education.ts │ ├── WorkExperience.ts │ └── Project.ts ├── helper │ ├── PrismaClientProvider.ts │ └── RepositoryProvider.ts ├── controller │ ├── HealthCheckController.ts │ ├── LinkController.ts │ ├── EducationController.ts │ ├── ProjectController.ts │ ├── DeploymentsController.ts │ ├── WorkExperienceController.ts │ └── CertificateController.ts └── routes │ ├── HealthCheckRoutes.ts │ ├── LinkRoutes.ts │ ├── ProjectRoutes.ts │ ├── EducationRoutes.ts │ ├── CertificateRoutes.ts │ ├── DeploymentsRoutes.ts │ ├── WorkExperienceRoutes.ts │ └── MainRoutes.ts ├── Dockerfile ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /node_modules/ -------------------------------------------------------------------------------- /prisma/migrations/20220730121914_v2/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE `Deployment` MODIFY `deployedOn` VARCHAR(191) NOT NULL; 3 | -------------------------------------------------------------------------------- /prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "mysql" -------------------------------------------------------------------------------- /src/repository/link/ILinkRepository.ts: -------------------------------------------------------------------------------- 1 | import Link from "../../model/Link"; 2 | 3 | export interface ILinkRepository { 4 | getLinks(): Promise; 5 | createLink(link: Link): Promise; 6 | } -------------------------------------------------------------------------------- /src/repository/project/IProjectRepository.ts: -------------------------------------------------------------------------------- 1 | import Project from "../../model/Project"; 2 | 3 | export default interface IProjectRepository { 4 | getProjects(): Promise; 5 | createProject(body: Project): Promise; 6 | } -------------------------------------------------------------------------------- /src/repository/education/IEducationRepository.ts: -------------------------------------------------------------------------------- 1 | import Education from "../../model/Education"; 2 | 3 | export interface IEducationRepository { 4 | getEducations(): Promise; 5 | createEducation(body: Education): Promise; 6 | } -------------------------------------------------------------------------------- /src/Server.ts: -------------------------------------------------------------------------------- 1 | import Express from "express"; 2 | import MainRoutes from "./routes/MainRoutes"; 3 | 4 | const app = Express(); 5 | 6 | new MainRoutes(app); 7 | 8 | app.listen(8080, () => { 9 | console.log("Server is running on port 8080"); 10 | }); 11 | -------------------------------------------------------------------------------- /src/repository/deployments/IDeploymentsRepository.ts: -------------------------------------------------------------------------------- 1 | import Deployment from "../../model/Deployment"; 2 | 3 | export interface IDeploymentsRepository { 4 | getDeployments(): Promise; 5 | createDeployment(body: Deployment): Promise; 6 | } -------------------------------------------------------------------------------- /src/repository/certificate/ICertificateRepository.ts: -------------------------------------------------------------------------------- 1 | import Certificate from "../../model/Certificate"; 2 | 3 | export interface ICertificateRepository { 4 | getCertificates(): Promise; 5 | createCertificate(certificate: Certificate): Promise; 6 | } -------------------------------------------------------------------------------- /src/repository/workExperience/IWorkExperienceRepository.ts: -------------------------------------------------------------------------------- 1 | import WorkExperience from "../../model/WorkExperience"; 2 | 3 | export interface IWorkExperienceRepository { 4 | getAllWorkExperience(): Promise; 5 | createWorkExperience(workExperience: WorkExperience): Promise; 6 | } -------------------------------------------------------------------------------- /prisma/migrations/20220730103229_v1/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `createdAt` on the `Deployment` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE `Deployment` DROP COLUMN `createdAt`, 9 | ADD COLUMN `deployedOn` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3); 10 | -------------------------------------------------------------------------------- /prisma/migrations/20220730122333_v3/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to alter the column `deployedOn` on the `Deployment` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `DateTime(3)`. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE `Deployment` MODIFY `deployedOn` DATETIME(3) NOT NULL; 9 | -------------------------------------------------------------------------------- /src/model/Activity.ts: -------------------------------------------------------------------------------- 1 | 2 | export default class Activity { 3 | private _activity: string; 4 | 5 | constructor(activity: string) { 6 | this._activity = activity; 7 | } 8 | 9 | get activity(): string { 10 | return this._activity; 11 | } 12 | 13 | set activity(value: string) { 14 | this._activity = value; 15 | } 16 | } -------------------------------------------------------------------------------- /src/model/Technology.ts: -------------------------------------------------------------------------------- 1 | export default class Technology { 2 | private _technology: string; 3 | 4 | constructor(technology: string) { 5 | this._technology = technology; 6 | } 7 | 8 | get technology(): string { 9 | return this._technology; 10 | } 11 | 12 | set technology(value: string) { 13 | this._technology = value; 14 | } 15 | } -------------------------------------------------------------------------------- /src/model/Responsibility.ts: -------------------------------------------------------------------------------- 1 | 2 | export default class Responsibility { 3 | private _responsibility: string; 4 | 5 | constructor(responsibility: string) { 6 | this._responsibility = responsibility; 7 | } 8 | 9 | get responsibility(): string { 10 | return this._responsibility; 11 | } 12 | 13 | set responsibility(value: string) { 14 | this._responsibility = value; 15 | } 16 | } -------------------------------------------------------------------------------- /prisma/migrations/20220730100130_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE `Deployment` ( 3 | `id` INTEGER NOT NULL AUTO_INCREMENT, 4 | `name` VARCHAR(191) NOT NULL, 5 | `description` VARCHAR(191) NOT NULL, 6 | `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), 7 | `url` VARCHAR(191) NOT NULL, 8 | 9 | PRIMARY KEY (`id`) 10 | ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 11 | -------------------------------------------------------------------------------- /src/helper/PrismaClientProvider.ts: -------------------------------------------------------------------------------- 1 | import {PrismaClient} from "@prisma/client"; 2 | 3 | export default class PrismaClientProvider { 4 | private static client: PrismaClient; 5 | 6 | private constructor() {} 7 | 8 | static getClient(): PrismaClient { 9 | if (this.client == undefined) { 10 | this.client = new PrismaClient({log: ['query', 'info', 'warn', 'error'],}); 11 | } 12 | return this.client; 13 | } 14 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16 2 | WORKDIR /app 3 | COPY package.json ./ 4 | COPY tsconfig.json ./ 5 | COPY prisma ./prisma 6 | COPY src ./src 7 | RUN ls -a 8 | RUN npm install 9 | RUN npm install -g typescript 10 | RUN npm run build 11 | 12 | FROM node:16 13 | WORKDIR /app 14 | COPY package.json ./ 15 | RUN npm install 16 | COPY --from=0 /app/build ./src 17 | COPY --from=0 /app/prisma ./prisma 18 | RUN npx prisma generate 19 | EXPOSE 8080 20 | CMD ["node","/app/src/Server.js"] 21 | -------------------------------------------------------------------------------- /src/controller/HealthCheckController.ts: -------------------------------------------------------------------------------- 1 | import {IDeploymentsRepository} from "../repository/deployments/IDeploymentsRepository"; 2 | import RepositoryProvider from "../helper/RepositoryProvider"; 3 | import {Request, Response} from "express"; 4 | import {body} from "express-validator"; 5 | import Deployment from "../model/Deployment"; 6 | 7 | export default class HealthCheckController { 8 | 9 | constructor() { 10 | } 11 | 12 | async healthCheck(req: Request, res: Response) { 13 | res.send('KO'); 14 | } 15 | } -------------------------------------------------------------------------------- /src/model/Location.ts: -------------------------------------------------------------------------------- 1 | 2 | export default class Location { 3 | private _city: string; 4 | private _country: string; 5 | 6 | constructor(city: string, country: string) { 7 | this._city = city; 8 | this._country = country; 9 | } 10 | 11 | get city(): string { 12 | return this._city; 13 | } 14 | 15 | set city(value: string) { 16 | this._city = value; 17 | } 18 | 19 | get country(): string { 20 | return this._country; 21 | } 22 | 23 | set country(value: string) { 24 | this._country = value; 25 | } 26 | } -------------------------------------------------------------------------------- /src/model/Link.ts: -------------------------------------------------------------------------------- 1 | 2 | export default class Link { 3 | private _description: string; 4 | private _url: string; 5 | 6 | constructor(description: string, url: string) { 7 | this._description = description; 8 | this._url = url; 9 | } 10 | 11 | get description(): string { 12 | return this._description; 13 | } 14 | 15 | set description(value: string) { 16 | this._description = value; 17 | } 18 | 19 | get url(): string { 20 | return this._url; 21 | } 22 | 23 | set url(value: string) { 24 | this._url = value; 25 | } 26 | } -------------------------------------------------------------------------------- /src/routes/HealthCheckRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import DeploymentsController from "../controller/DeploymentsController"; 3 | import HealthCheckController from "../controller/HealthCheckController"; 4 | 5 | class HealthCheckRoutes { 6 | router: Router = Router(); 7 | healthCheckController: HealthCheckController = new HealthCheckController(); 8 | 9 | constructor() { 10 | this.initializeRoutes(); 11 | } 12 | 13 | initializeRoutes() { 14 | this.router.route('/').get(((req, res) => this.healthCheckController.healthCheck(req, res))); 15 | } 16 | } 17 | 18 | export default new HealthCheckRoutes().router; -------------------------------------------------------------------------------- /src/routes/LinkRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import LinkController from "../controller/LinkController"; 3 | 4 | class LinkRoutes { 5 | router: Router = Router(); 6 | linkController: LinkController = new LinkController(); 7 | 8 | constructor() { 9 | this.initializeRoutes(); 10 | } 11 | 12 | initializeRoutes() { 13 | this.router.route('/').get(((req, res) => this.linkController.getLinks(req, res))); 14 | // TODO Add authorization - either by token in the HTTP request or whitelisting the IP address 15 | // this.router.route('/').post(((req, res) => this.linkController.createLink(req, res))); 16 | } 17 | } 18 | 19 | export default new LinkRoutes().router; -------------------------------------------------------------------------------- /src/routes/ProjectRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import ProjectController from "../controller/ProjectController"; 3 | 4 | class ProjectRoutes { 5 | router: Router = Router(); 6 | projectController: ProjectController = new ProjectController(); 7 | 8 | constructor() { 9 | this.initializeRoutes(); 10 | } 11 | 12 | initializeRoutes() { 13 | this.router.route('/').get(((req, res) => this.projectController.getProjects(req, res))); 14 | // TODO Add authorization - either by token in the HTTP request or whitelisting the IP address 15 | // this.router.route('/').post(((req, res) => this.projectController.createProject(req, res))); 16 | } 17 | } 18 | 19 | export default new ProjectRoutes().router; -------------------------------------------------------------------------------- /src/routes/EducationRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import EducationController from "../controller/EducationController"; 3 | 4 | class EducationRoutes { 5 | router: Router = Router(); 6 | educationController: EducationController = new EducationController(); 7 | 8 | constructor() { 9 | this.initializeRoutes(); 10 | } 11 | 12 | initializeRoutes() { 13 | this.router.route('/').get(((req, res) => this.educationController.getEducations(req, res))); 14 | // TODO Add authorization - either by token in the HTTP request or whitelisting the IP address 15 | // this.router.route('/').post(((req, res) => this.educationController.createEducation(req, res))); 16 | } 17 | } 18 | 19 | export default new EducationRoutes().router; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api-tomondre", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "tsc && node build/Server.js", 8 | "build": "tsc", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@prisma/client": "^4.1.1", 16 | "@types/cors": "^2.8.12", 17 | "@types/express": "^4.17.13", 18 | "@types/node": "^18.6.2", 19 | "typescript": "^4.7.4" 20 | }, 21 | "dependencies": { 22 | "body-parser": "^1.20.0", 23 | "class-validator": "^0.13.2", 24 | "cors": "^2.8.5", 25 | "express": "^4.18.1", 26 | "express-validator": "^6.14.2", 27 | "prisma": "^4.1.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/routes/CertificateRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import CertificateController from "../controller/CertificateController"; 3 | 4 | class CertificateRoutes { 5 | router: Router = Router(); 6 | certificateController: CertificateController = new CertificateController(); 7 | 8 | constructor() { 9 | this.initializeRoutes(); 10 | } 11 | 12 | initializeRoutes() { 13 | this.router.route('/').get(((req, res) => this.certificateController.getCertificates(req, res))); 14 | // TODO Add authorization - either by token in the HTTP request or whitelisting the IP address 15 | // this.router.route('/').post(((req, res) => this.certificateController.createCertificate(req, res))); 16 | } 17 | } 18 | 19 | export default new CertificateRoutes().router; -------------------------------------------------------------------------------- /src/routes/DeploymentsRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import DeploymentsController from "../controller/DeploymentsController"; 3 | 4 | class DeploymentsRoutes { 5 | router: Router = Router(); 6 | deploymentsController: DeploymentsController = new DeploymentsController(); 7 | 8 | constructor() { 9 | this.initializeRoutes(); 10 | } 11 | 12 | initializeRoutes() { 13 | this.router.route('/').get(((req, res) => this.deploymentsController.getDeployments(req, res))); 14 | // TODO Add authorization - either by token in the HTTP request or whitelisting the IP address 15 | // this.router.route('/').post(((req, res) => this.deploymentsController.createDeployment(req, res))); 16 | } 17 | } 18 | 19 | export default new DeploymentsRoutes().router; -------------------------------------------------------------------------------- /src/model/ProjectLink.ts: -------------------------------------------------------------------------------- 1 | export default class ProjectLink { 2 | private _description: string; 3 | private _url: string; 4 | private _type: string; 5 | 6 | constructor(description: string, url: string, type: string) { 7 | this._description = description; 8 | this._url = url; 9 | this._type = type; 10 | } 11 | 12 | get description(): string { 13 | return this._description; 14 | } 15 | 16 | set description(value: string) { 17 | this._description = value; 18 | } 19 | 20 | get url(): string { 21 | return this._url; 22 | } 23 | 24 | set url(value: string) { 25 | this._url = value; 26 | } 27 | 28 | get type(): string { 29 | return this._type; 30 | } 31 | 32 | set type(value: string) { 33 | this._type = value; 34 | } 35 | } -------------------------------------------------------------------------------- /src/routes/WorkExperienceRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import DeploymentsController from "../controller/DeploymentsController"; 3 | import HealthCheckController from "../controller/HealthCheckController"; 4 | import WorkExperienceController from "../controller/WorkExperienceController"; 5 | 6 | class WorkExperienceRoutes { 7 | router: Router = Router(); 8 | workExperienceController: WorkExperienceController = new WorkExperienceController(); 9 | 10 | constructor() { 11 | this.initializeRoutes(); 12 | } 13 | 14 | initializeRoutes() { 15 | this.router.route('/').get(((req, res) => this.workExperienceController.getAllWorkExperience(req, res))); 16 | // TODO Add authorization - either by token in the HTTP request or whitelisting the IP address 17 | // this.router.route('/').post(((req, res) => this.workExperienceController.createWorkExperience(req, res))); 18 | } 19 | } 20 | 21 | export default new WorkExperienceRoutes().router; -------------------------------------------------------------------------------- /src/routes/MainRoutes.ts: -------------------------------------------------------------------------------- 1 | import {Application} from "express"; 2 | import * as express from "express"; 3 | import deploymentsRoutes from "./DeploymentsRoutes"; 4 | import healthCheckRoutes from "./HealthCheckRoutes"; 5 | import workExperienceRoutes from "./WorkExperienceRoutes"; 6 | import educationRoutes from "./EducationRoutes"; 7 | import projectRoutes from "./ProjectRoutes"; 8 | import certificateRoutes from "./CertificateRoutes"; 9 | import linkRoutes from "./LinkRoutes"; 10 | import bodyParser from "body-parser"; 11 | import cors from 'cors' 12 | 13 | export default class MainRoutes { 14 | constructor(app: Application) { 15 | app.use(express.json()); 16 | app.use(cors()); 17 | app.use(bodyParser.json()); 18 | app.use('/healthCheck', healthCheckRoutes); 19 | app.use('/deployments', deploymentsRoutes); 20 | app.use('/workExperiences', workExperienceRoutes); 21 | app.use('/educations', educationRoutes); 22 | app.use('/projects', projectRoutes); 23 | app.use('/certificates', certificateRoutes); 24 | app.use('/links', linkRoutes) 25 | } 26 | } -------------------------------------------------------------------------------- /src/controller/LinkController.ts: -------------------------------------------------------------------------------- 1 | import {ILinkRepository} from "../repository/link/ILinkRepository"; 2 | import RepositoryProvider from "../helper/RepositoryProvider"; 3 | import {Request, Response} from "express"; 4 | import Link from "../model/Link"; 5 | 6 | export default class LinkController { 7 | private linkRepository: ILinkRepository; 8 | 9 | constructor() { 10 | this.linkRepository = RepositoryProvider.getLinkRepository(); 11 | } 12 | 13 | async getLinks(req: Request, res: Response) { 14 | try { 15 | let links = await this.linkRepository.getLinks(); 16 | res.json(links); 17 | } catch (e: any) { 18 | console.log(e); 19 | res.status(400); 20 | res.send(e.toString()); 21 | } 22 | } 23 | 24 | async createLink(req: Request, res: Response) { 25 | try { 26 | let link = new Link(req.body.description, req.body.url); 27 | let created = await this.linkRepository.createLink(link); 28 | res.json(created); 29 | } catch (e: any) { 30 | console.log(e); 31 | res.status(400); 32 | res.send(e.toString()); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/repository/certificate/CertificateRepository.ts: -------------------------------------------------------------------------------- 1 | import {ICertificateRepository} from "./ICertificateRepository"; 2 | import {PrismaClient} from "@prisma/client"; 3 | import PrismaClientProvider from "../../helper/PrismaClientProvider"; 4 | import Certificate from "../../model/Certificate"; 5 | 6 | export default class CertificateRepository implements ICertificateRepository { 7 | private prismaClient: PrismaClient; 8 | 9 | constructor() { 10 | this.prismaClient = PrismaClientProvider.getClient(); 11 | } 12 | 13 | async getCertificates(): Promise { 14 | // @ts-ignore 15 | return await this.prismaClient.certificate.findMany(); 16 | } 17 | 18 | async createCertificate(certificate: Certificate): Promise { 19 | // @ts-ignore 20 | return await this.prismaClient.certificate.create({ 21 | data: { 22 | name: certificate.name, 23 | organization: certificate.organization, 24 | issuedDate: certificate.issuedDate, 25 | expiryDate: certificate.expiryDate, 26 | credentialId: certificate.credentialId, 27 | description: certificate.description, 28 | url: certificate.url 29 | } 30 | }); 31 | } 32 | } -------------------------------------------------------------------------------- /src/repository/deployments/DeploymentsRepository.ts: -------------------------------------------------------------------------------- 1 | import {IDeploymentsRepository} from "./IDeploymentsRepository"; 2 | import Deployment from "../../model/Deployment"; 3 | import {PrismaClient} from "@prisma/client"; 4 | import PrismaClientProvider from "../../helper/PrismaClientProvider"; 5 | 6 | export default class DeploymentsRepository implements IDeploymentsRepository { 7 | 8 | private prismaClient: PrismaClient; 9 | 10 | constructor() { 11 | this.prismaClient = PrismaClientProvider.getClient(); 12 | } 13 | 14 | async getDeployments(): Promise { 15 | // @ts-ignore 16 | return this.prismaClient.deployment.findMany({ 17 | orderBy: { 18 | deployedOn: 'desc' 19 | } 20 | }); 21 | } 22 | 23 | async createDeployment(body: Deployment): Promise { 24 | console.log(body.deployedOn); 25 | // @ts-ignore 26 | return this.prismaClient.deployment.create({ 27 | data: { 28 | name: body.name, 29 | deployedOn: body.deployedOn, 30 | description: body.description, 31 | repoUrl: body.repoUrl, 32 | url: body.url, 33 | healthUrl: body.healthUrl 34 | } 35 | }); 36 | } 37 | } -------------------------------------------------------------------------------- /src/repository/link/LinkRepository.ts: -------------------------------------------------------------------------------- 1 | import {PrismaClient} from "@prisma/client"; 2 | import PrismaClientProvider from "../../helper/PrismaClientProvider"; 3 | import Link from "../../model/Link"; 4 | 5 | export default class LinkRepository { 6 | private prismaClient: PrismaClient; 7 | 8 | constructor() { 9 | this.prismaClient = PrismaClientProvider.getClient(); 10 | } 11 | 12 | async getLinks(): Promise { 13 | let links = await this.prismaClient.link.findMany({ 14 | where: { 15 | educationId: null, 16 | projectId: null, 17 | workExperienceId: null 18 | } 19 | }); 20 | 21 | links.forEach(link => { 22 | // @ts-ignore 23 | delete link['id']; 24 | // @ts-ignore 25 | delete link['workExperienceId']; 26 | // @ts-ignore 27 | delete link['educationId']; 28 | // @ts-ignore 29 | delete link['projectId']; 30 | }); 31 | 32 | // @ts-ignore 33 | return links; 34 | } 35 | 36 | async createLink(link: Link): Promise { 37 | // @ts-ignore 38 | return await this.prismaClient.link.create({ 39 | data: { 40 | description: link.description, 41 | url: link.url 42 | } 43 | }); 44 | } 45 | } -------------------------------------------------------------------------------- /src/controller/EducationController.ts: -------------------------------------------------------------------------------- 1 | import RepositoryProvider from "../helper/RepositoryProvider"; 2 | import {Request, Response} from "express"; 3 | import Education from "../model/Education"; 4 | import {IEducationRepository} from "../repository/education/IEducationRepository"; 5 | 6 | export default class EducationController { 7 | private educationRepository: IEducationRepository; 8 | 9 | constructor() { 10 | this.educationRepository = RepositoryProvider.getEducationRepository(); 11 | } 12 | 13 | async getEducations(req: Request, res: Response) { 14 | try { 15 | let educations = await this.educationRepository.getEducations(); 16 | res.json(educations); 17 | } 18 | catch (e: any) { 19 | console.log(e); 20 | res.status(400); 21 | res.send(e.toString()); 22 | } 23 | } 24 | 25 | async createEducation(req: Request, res: Response) { 26 | try { 27 | let body = new Education(req.body.school, req.body.degree, req.body.fieldOfStudy, req.body.isCurrent, new Date(req.body.startDate), new Date(req.body.endDate), req.body.location, req.body.activities, req.body.links); 28 | let deployment = await this.educationRepository.createEducation(body); 29 | res.json(deployment); 30 | } 31 | catch (e: any) { 32 | console.log(e); 33 | res.status(400); 34 | res.send(e.toString()); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/controller/ProjectController.ts: -------------------------------------------------------------------------------- 1 | import IProjectRepository from "../repository/project/IProjectRepository"; 2 | import RepositoryProvider from "../helper/RepositoryProvider"; 3 | import Responsibility from "../model/Responsibility"; 4 | import {Request, Response} from "express"; 5 | import Project from "../model/Project"; 6 | 7 | export default class ProjectController { 8 | private projectRepository: IProjectRepository; 9 | 10 | constructor() { 11 | this.projectRepository = RepositoryProvider.getProjectRepository(); 12 | } 13 | 14 | async getProjects(req: Request, res: Response) { 15 | try { 16 | let projects = await this.projectRepository.getProjects(); 17 | res.json(projects); 18 | } catch (e: any) { 19 | console.log(e); 20 | res.status(400); 21 | res.send(e.toString()); 22 | } 23 | } 24 | 25 | async createProject(req: Request, res: Response) { 26 | try { 27 | let body = new Project(req.body.name, req.body.description, req.body.status, req.body.category, new Date(req.body.startDate), new Date(req.body.endDate), req.body.location, req.body.client, req.body.technologies, req.body.links); 28 | let project = await this.projectRepository.createProject(body); 29 | res.json(project); 30 | } catch (e: any) { 31 | console.log(e); 32 | res.status(400); 33 | res.send(e.toString()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/controller/DeploymentsController.ts: -------------------------------------------------------------------------------- 1 | import {IDeploymentsRepository} from "../repository/deployments/IDeploymentsRepository"; 2 | import RepositoryProvider from "../helper/RepositoryProvider"; 3 | import {Request, Response} from "express"; 4 | import {body} from "express-validator"; 5 | import Deployment from "../model/Deployment"; 6 | 7 | export default class DeploymentsController { 8 | private deploymentsRepository: IDeploymentsRepository; 9 | 10 | constructor() { 11 | this.deploymentsRepository = RepositoryProvider.getDeploymentsRepository(); 12 | } 13 | 14 | async getDeployments(req: Request, res: Response) { 15 | try { 16 | let deployments = await this.deploymentsRepository.getDeployments(); 17 | res.json(deployments); 18 | } 19 | catch (e: any) { 20 | console.log(e); 21 | res.status(400); 22 | res.send(e.toString()); 23 | } 24 | } 25 | 26 | async createDeployment(req: Request, res: Response) { 27 | try { 28 | let body = new Deployment(0, req.body.name, req.body.description, new Date(req.body.deployedOn), req.body.repoUrl, req.body.url, req.body.healthUrl); 29 | let deployment = await this.deploymentsRepository.createDeployment(body); 30 | res.json(deployment); 31 | } 32 | catch (e: any) { 33 | console.log(e); 34 | res.status(400); 35 | res.send(e.toString()); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/controller/WorkExperienceController.ts: -------------------------------------------------------------------------------- 1 | import {IWorkExperienceRepository} from "../repository/workExperience/IWorkExperienceRepository"; 2 | import RepositoryProvider from "../helper/RepositoryProvider"; 3 | import WorkExperience from "../model/WorkExperience"; 4 | import {Request, Response} from "express"; 5 | 6 | export default class WorkExperienceController { 7 | 8 | private workExperienceRepository: IWorkExperienceRepository; 9 | 10 | constructor() { 11 | this.workExperienceRepository = RepositoryProvider.getWorkExperienceRepository(); 12 | } 13 | 14 | async getAllWorkExperience(req: Request, res: Response) { 15 | try { 16 | let allWorkExperience = await this.workExperienceRepository.getAllWorkExperience(); 17 | res.json(allWorkExperience); 18 | } catch (error: any) { 19 | console.log(error.toString()); 20 | res.status(400); 21 | res.send(error.toString()); 22 | } 23 | } 24 | 25 | async createWorkExperience(req: Request, res: Response) { 26 | try { 27 | let workExperience = new WorkExperience( req.body.position, req.body.company, req.body.employmentType, req.body.isCurrent, new Date(req.body.startDate), new Date(req.body.endDate), req.body.location, req.body.responsibilities, req.body.links); 28 | let createdWorkExperience = await this.workExperienceRepository.createWorkExperience(workExperience); 29 | res.json(createdWorkExperience); 30 | } catch (error: any) { 31 | console.log(error.toString()); 32 | res.status(400); 33 | res.send(error.toString()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/controller/CertificateController.ts: -------------------------------------------------------------------------------- 1 | import {IDeploymentsRepository} from "../repository/deployments/IDeploymentsRepository"; 2 | import RepositoryProvider from "../helper/RepositoryProvider"; 3 | import {Request, Response} from "express"; 4 | import {body} from "express-validator"; 5 | import Deployment from "../model/Deployment"; 6 | import {ICertificateRepository} from "../repository/certificate/ICertificateRepository"; 7 | import Certificate from "../model/Certificate"; 8 | 9 | export default class CertificateController { 10 | private certificateRepository: ICertificateRepository; 11 | 12 | constructor() { 13 | this.certificateRepository = RepositoryProvider.getCertificateRepository(); 14 | } 15 | 16 | async getCertificates(req: Request, res: Response) { 17 | try { 18 | let certificates = await this.certificateRepository.getCertificates(); 19 | res.json(certificates); 20 | } 21 | catch (e: any) { 22 | console.log(e); 23 | res.status(400); 24 | res.send(e.toString()); 25 | } 26 | } 27 | 28 | async createCertificate(req: Request, res: Response) { 29 | try { 30 | let certificate = new Certificate(req.body.name, req.body.organization, req.body.description, new Date(req.body.issuedDate), new Date(req.body.expiryDate), req.body.credentialId, req.body.url); 31 | let created = await this.certificateRepository.createCertificate(certificate); 32 | res.json(created); 33 | } 34 | catch (e: any) { 35 | console.log(e); 36 | res.status(400); 37 | res.send(e.toString()); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/model/Deployment.ts: -------------------------------------------------------------------------------- 1 | import e from "express"; 2 | import {IsDate} from "class-validator"; 3 | 4 | export default class Deployment { 5 | private _id: number = 0; 6 | private _name: string; 7 | private _description: string; 8 | private _deployedOn: Date; 9 | private _repoUrl: string; 10 | private _url: string; 11 | private _healthUrl: string; 12 | 13 | constructor(id: number, name: string, description: string, deployedOn: Date, repoUrl: string, url: string, healthUrl: string) { 14 | this._id = id; 15 | this._name = name; 16 | this._description = description; 17 | this._deployedOn = deployedOn; 18 | this._repoUrl = repoUrl; 19 | this._url = url; 20 | this._healthUrl = healthUrl; 21 | } 22 | 23 | get id(): number { 24 | return this._id; 25 | } 26 | 27 | set id(value: number) { 28 | this._id = value; 29 | } 30 | 31 | get name(): string { 32 | return this._name; 33 | } 34 | 35 | set name(value: string) { 36 | this._name = value; 37 | } 38 | 39 | get description(): string { 40 | return this._description; 41 | } 42 | 43 | set description(value: string) { 44 | this._description = value; 45 | } 46 | 47 | get deployedOn(): Date { 48 | return this._deployedOn; 49 | } 50 | 51 | set deployedOn(value: Date) { 52 | this._deployedOn = value; 53 | } 54 | 55 | get repoUrl(): string { 56 | return this._repoUrl; 57 | } 58 | 59 | set repoUrl(value: string) { 60 | this._repoUrl = value; 61 | } 62 | 63 | get url(): string { 64 | return this._url; 65 | } 66 | 67 | set url(value: string) { 68 | this._url = value; 69 | } 70 | 71 | get healthUrl(): string { 72 | return this._healthUrl; 73 | } 74 | 75 | set healthUrl(value: string) { 76 | this._healthUrl = value; 77 | } 78 | } -------------------------------------------------------------------------------- /src/model/Certificate.ts: -------------------------------------------------------------------------------- 1 | export default class Certificate { 2 | private _name: string; 3 | private _organization: string; 4 | private _description: string; 5 | private _issuedDate: Date; 6 | private _expiryDate: Date; 7 | private _credentialId: string; 8 | private _url: string; 9 | 10 | constructor(name: string, organization: string, description: string, issuedDate: Date, expiryDate: Date, credentialId: string, url: string) { 11 | this._name = name; 12 | this._organization = organization; 13 | this._description = description; 14 | this._issuedDate = issuedDate; 15 | this._expiryDate = expiryDate; 16 | this._credentialId = credentialId; 17 | this._url = url; 18 | } 19 | 20 | get description(): string { 21 | return this._description; 22 | } 23 | 24 | set description(value: string) { 25 | this._description = value; 26 | } 27 | 28 | get name(): string { 29 | return this._name; 30 | } 31 | 32 | set name(value: string) { 33 | this._name = value; 34 | } 35 | 36 | get organization(): string { 37 | return this._organization; 38 | } 39 | 40 | set organization(value: string) { 41 | this._organization = value; 42 | } 43 | 44 | get issuedDate(): Date { 45 | return this._issuedDate; 46 | } 47 | 48 | set issuedDate(value: Date) { 49 | this._issuedDate = value; 50 | } 51 | 52 | get expiryDate(): Date { 53 | return this._expiryDate; 54 | } 55 | 56 | set expiryDate(value: Date) { 57 | this._expiryDate = value; 58 | } 59 | 60 | get credentialId(): string { 61 | return this._credentialId; 62 | } 63 | 64 | set credentialId(value: string) { 65 | this._credentialId = value; 66 | } 67 | 68 | get url(): string { 69 | return this._url; 70 | } 71 | 72 | set url(value: string) { 73 | this._url = value; 74 | } 75 | } -------------------------------------------------------------------------------- /src/model/Education.ts: -------------------------------------------------------------------------------- 1 | import Location from "./Location"; 2 | import Activity from "./Activity"; 3 | import Link from "./Link"; 4 | 5 | export default class Education { 6 | 7 | private _school: string; 8 | private _degree: string; 9 | private _fieldOfStudy: string; 10 | private _isCurrent: boolean; 11 | private _startDate: Date; 12 | private _endDate: Date; 13 | private _location: Location; 14 | private _activities: Activity[]; 15 | private _links: Link[]; 16 | 17 | constructor(school: string, degree: string, fieldOfStudy: string, isCurrent: boolean, startDate: Date, endDate: Date, location: Location, activities: Activity[], links: Link[]) { 18 | this._school = school; 19 | this._degree = degree; 20 | this._fieldOfStudy = fieldOfStudy; 21 | this._isCurrent = isCurrent; 22 | this._startDate = startDate; 23 | this._endDate = endDate; 24 | this._location = location; 25 | this._activities = activities; 26 | this._links = links; 27 | } 28 | 29 | get school(): string { 30 | return this._school; 31 | } 32 | 33 | set school(value: string) { 34 | this._school = value; 35 | } 36 | 37 | get degree(): string { 38 | return this._degree; 39 | } 40 | 41 | set degree(value: string) { 42 | this._degree = value; 43 | } 44 | 45 | get fieldOfStudy(): string { 46 | return this._fieldOfStudy; 47 | } 48 | 49 | set fieldOfStudy(value: string) { 50 | this._fieldOfStudy = value; 51 | } 52 | 53 | get isCurrent(): boolean { 54 | return this._isCurrent; 55 | } 56 | 57 | set isCurrent(value: boolean) { 58 | this._isCurrent = value; 59 | } 60 | 61 | get startDate(): Date { 62 | return this._startDate; 63 | } 64 | 65 | set startDate(value: Date) { 66 | this._startDate = value; 67 | } 68 | 69 | get endDate(): Date { 70 | return this._endDate; 71 | } 72 | 73 | set endDate(value: Date) { 74 | this._endDate = value; 75 | } 76 | 77 | get location(): Location { 78 | return this._location; 79 | } 80 | 81 | set location(value: Location) { 82 | this._location = value; 83 | } 84 | 85 | get activities(): Activity[] { 86 | return this._activities; 87 | } 88 | 89 | set activities(value: Activity[]) { 90 | this._activities = value; 91 | } 92 | 93 | get links(): Link[] { 94 | return this._links; 95 | } 96 | 97 | set links(value: Link[]) { 98 | this._links = value; 99 | } 100 | } -------------------------------------------------------------------------------- /src/model/WorkExperience.ts: -------------------------------------------------------------------------------- 1 | import Location from "./Location"; 2 | import Link from "./Link"; 3 | import Responsibility from "./Responsibility"; 4 | 5 | export default class WorkExperience { 6 | private _position: string; 7 | private _company: string; 8 | private _employmentType: string; 9 | private _isCurrent: boolean; 10 | private _startDate: Date; 11 | private _endDate: Date; 12 | private _location: Location; 13 | private _responsibilities: Responsibility[]; 14 | private _links: Link[]; 15 | 16 | constructor(position: string, company: string, employmentType: string, isCurrent: boolean, startDate: Date, endDate: Date, location: Location, responsibilities: Responsibility[], links: Link[]) { 17 | this._position = position; 18 | this._company = company; 19 | this._employmentType = employmentType; 20 | this._isCurrent = isCurrent; 21 | this._startDate = startDate; 22 | this._endDate = endDate; 23 | this._location = location; 24 | this._responsibilities = responsibilities; 25 | this._links = links; 26 | } 27 | 28 | get position(): string { 29 | return this._position; 30 | } 31 | 32 | set position(value: string) { 33 | this._position = value; 34 | } 35 | 36 | get company(): string { 37 | return this._company; 38 | } 39 | 40 | set company(value: string) { 41 | this._company = value; 42 | } 43 | 44 | get employmentType(): string { 45 | return this._employmentType; 46 | } 47 | 48 | set employmentType(value: string) { 49 | this._employmentType = value; 50 | } 51 | 52 | get isCurrent(): boolean { 53 | return this._isCurrent; 54 | } 55 | 56 | set isCurrent(value: boolean) { 57 | this._isCurrent = value; 58 | } 59 | 60 | get startDate(): Date { 61 | return this._startDate; 62 | } 63 | 64 | set startDate(value: Date) { 65 | this._startDate = value; 66 | } 67 | 68 | get endDate(): Date { 69 | return this._endDate; 70 | } 71 | 72 | set endDate(value: Date) { 73 | this._endDate = value; 74 | } 75 | 76 | get location(): Location { 77 | return this._location; 78 | } 79 | 80 | set location(value: Location) { 81 | this._location = value; 82 | } 83 | 84 | get responsibilities(): Responsibility[] { 85 | return this._responsibilities; 86 | } 87 | 88 | set responsibilities(value: Responsibility[]) { 89 | this._responsibilities = value; 90 | } 91 | 92 | get links(): Link[] { 93 | return this._links; 94 | } 95 | 96 | set links(value: Link[]) { 97 | this._links = value; 98 | } 99 | } -------------------------------------------------------------------------------- /src/model/Project.ts: -------------------------------------------------------------------------------- 1 | import Location from "./Location"; 2 | import Technology from "./Technology"; 3 | import ProjectLink from "./ProjectLink"; 4 | 5 | export default class Project { 6 | private _name: string; 7 | private _description: string; 8 | private _status: string; 9 | private _category: string; 10 | private _startDate: Date; 11 | private _endDate: Date; 12 | private _location: Location; 13 | private _client: string; 14 | private _technologies: Technology[]; 15 | private _links: ProjectLink[]; 16 | 17 | constructor(name: string, description: string, status: string, category: string, startDate: Date, endDate: Date, location: Location, client: string, technologies: Technology[], links: ProjectLink[]) { 18 | this._name = name; 19 | this._description = description; 20 | this._status = status; 21 | this._category = category; 22 | this._startDate = startDate; 23 | this._endDate = endDate; 24 | this._location = location; 25 | this._client = client; 26 | this._technologies = technologies; 27 | this._links = links; 28 | } 29 | 30 | get name(): string { 31 | return this._name; 32 | } 33 | 34 | set name(value: string) { 35 | this._name = value; 36 | } 37 | 38 | get description(): string { 39 | return this._description; 40 | } 41 | 42 | set description(value: string) { 43 | this._description = value; 44 | } 45 | 46 | get status(): string { 47 | return this._status; 48 | } 49 | 50 | set status(value: string) { 51 | this._status = value; 52 | } 53 | 54 | get category(): string { 55 | return this._category; 56 | } 57 | 58 | set category(value: string) { 59 | this._category = value; 60 | } 61 | 62 | get startDate(): Date { 63 | return this._startDate; 64 | } 65 | 66 | set startDate(value: Date) { 67 | this._startDate = value; 68 | } 69 | 70 | get endDate(): Date { 71 | return this._endDate; 72 | } 73 | 74 | set endDate(value: Date) { 75 | this._endDate = value; 76 | } 77 | 78 | get location(): Location { 79 | return this._location; 80 | } 81 | 82 | set location(value: Location) { 83 | this._location = value; 84 | } 85 | 86 | get client(): string { 87 | return this._client; 88 | } 89 | 90 | set client(value: string) { 91 | this._client = value; 92 | } 93 | 94 | get technologies(): Technology[] { 95 | return this._technologies; 96 | } 97 | 98 | set technologies(value: Technology[]) { 99 | this._technologies = value; 100 | } 101 | 102 | get links(): ProjectLink[] { 103 | return this._links; 104 | } 105 | 106 | set links(value: ProjectLink[]) { 107 | this._links = value; 108 | } 109 | } -------------------------------------------------------------------------------- /src/helper/RepositoryProvider.ts: -------------------------------------------------------------------------------- 1 | import {IDeploymentsRepository} from "../repository/deployments/IDeploymentsRepository"; 2 | import DeploymentsRepository from "../repository/deployments/DeploymentsRepository"; 3 | import {IWorkExperienceRepository} from "../repository/workExperience/IWorkExperienceRepository"; 4 | import WorkExperienceRepository from "../repository/workExperience/WorkExperienceRepository"; 5 | import {IEducationRepository} from "../repository/education/IEducationRepository"; 6 | import EducationRepository from "../repository/education/EducationRepository"; 7 | import IProjectRepository from "../repository/project/IProjectRepository"; 8 | import ProjectRepository from "../repository/project/ProjectRepository"; 9 | import {ICertificateRepository} from "../repository/certificate/ICertificateRepository"; 10 | import CertificateRepository from "../repository/certificate/CertificateRepository"; 11 | import {ILinkRepository} from "../repository/link/ILinkRepository"; 12 | import LinkRepository from "../repository/link/LinkRepository"; 13 | 14 | export default class RepositoryProvider { 15 | 16 | private static deploymentsRepository: IDeploymentsRepository; 17 | private static workExperienceRepository: IWorkExperienceRepository; 18 | private static educationRepository: IEducationRepository; 19 | private static projectRepository: IProjectRepository; 20 | private static certificateRepository: ICertificateRepository; 21 | private static linkRepository: ILinkRepository; 22 | 23 | private constructor() {} 24 | 25 | static getDeploymentsRepository(): IDeploymentsRepository { 26 | if (!this.deploymentsRepository) { 27 | this.deploymentsRepository = new DeploymentsRepository(); 28 | } 29 | return this.deploymentsRepository; 30 | } 31 | 32 | static getWorkExperienceRepository(): IWorkExperienceRepository { 33 | if (!this.workExperienceRepository) { 34 | this.workExperienceRepository = new WorkExperienceRepository(); 35 | } 36 | return this.workExperienceRepository; 37 | } 38 | 39 | static getEducationRepository(): IEducationRepository { 40 | if (!this.educationRepository) { 41 | this.educationRepository = new EducationRepository(); 42 | } 43 | return this.educationRepository; 44 | } 45 | 46 | static getProjectRepository(): IProjectRepository { 47 | if (!this.projectRepository) { 48 | this.projectRepository = new ProjectRepository(); 49 | } 50 | return this.projectRepository; 51 | } 52 | 53 | static getCertificateRepository(): ICertificateRepository { 54 | if (!this.certificateRepository) { 55 | this.certificateRepository = new CertificateRepository(); 56 | } 57 | return this.certificateRepository; 58 | } 59 | 60 | static getLinkRepository(): ILinkRepository { 61 | if (!this.linkRepository) { 62 | this.linkRepository = new LinkRepository(); 63 | } 64 | return this.linkRepository; 65 | } 66 | } -------------------------------------------------------------------------------- /src/repository/project/ProjectRepository.ts: -------------------------------------------------------------------------------- 1 | import IProjectRepository from "./IProjectRepository"; 2 | import {PrismaClient} from "@prisma/client"; 3 | import PrismaClientProvider from "../../helper/PrismaClientProvider"; 4 | import Project from "../../model/Project"; 5 | 6 | export default class ProjectRepository implements IProjectRepository { 7 | private prismaClient: PrismaClient; 8 | 9 | constructor() { 10 | this.prismaClient = PrismaClientProvider.getClient(); 11 | } 12 | 13 | async getProjects(): Promise { 14 | let projects = await this.prismaClient.project.findMany({ 15 | include: { 16 | location: true, 17 | links: true, 18 | technologies: true 19 | }, 20 | orderBy: { 21 | startDate: "desc" 22 | } 23 | }); 24 | 25 | projects.forEach(project => { 26 | // @ts-ignore 27 | delete project['id'] 28 | // @ts-ignore 29 | delete project['locationId'] 30 | // @ts-ignore 31 | delete project.location['id'] 32 | 33 | // @ts-ignore 34 | project.technologies.forEach(technology => { 35 | // @ts-ignore 36 | delete technology['id']; 37 | // @ts-ignore 38 | delete technology['projectId']; 39 | } 40 | ); 41 | 42 | project.links.forEach(link => { 43 | // @ts-ignore 44 | delete link['id']; 45 | // @ts-ignore 46 | delete link['projectId']; 47 | }); 48 | }); 49 | 50 | // @ts-ignore 51 | return projects; 52 | } 53 | 54 | async createProject(project: Project): Promise { 55 | // @ts-ignore 56 | return await this.prismaClient.project.create({ 57 | data: { 58 | name: project.name, 59 | description: project.description, 60 | status: project.status, 61 | category: project.category, 62 | client: project.client, 63 | startDate: project.startDate, 64 | endDate: project.endDate, 65 | location: { 66 | connectOrCreate: { 67 | where: { 68 | city_country: { 69 | city: project.location.city, 70 | country: project.location.country 71 | } 72 | }, 73 | create: { 74 | city: project.location.city, 75 | country: project.location.country 76 | } 77 | } 78 | }, 79 | links: { 80 | createMany: { 81 | data: project.links 82 | } 83 | }, 84 | technologies: { 85 | createMany: { 86 | data: project.technologies 87 | } 88 | } 89 | } 90 | }); 91 | } 92 | } -------------------------------------------------------------------------------- /src/repository/education/EducationRepository.ts: -------------------------------------------------------------------------------- 1 | import {IEducationRepository} from "./IEducationRepository"; 2 | import {PrismaClient} from "@prisma/client/scripts/default-index"; 3 | import PrismaClientProvider from "../../helper/PrismaClientProvider"; 4 | import Education from "../../model/Education"; 5 | import Activity from "../../model/Activity"; 6 | import Link from "../../model/Link"; 7 | 8 | export default class EducationRepository implements IEducationRepository { 9 | private prismaClient: PrismaClient; 10 | 11 | constructor() { 12 | this.prismaClient = PrismaClientProvider.getClient(); 13 | } 14 | 15 | async getEducations(): Promise { 16 | let educations = await this.prismaClient.education.findMany({ 17 | include: { 18 | activities: true, 19 | links: true, 20 | location: true 21 | }, 22 | orderBy: { 23 | startDate: "desc" 24 | } 25 | }); 26 | 27 | educations.forEach((education: Education) => { 28 | // @ts-ignore 29 | delete education['id']; 30 | // @ts-ignore 31 | delete education['locationId']; 32 | // @ts-ignore 33 | delete education.location['id']; 34 | 35 | education.activities.forEach((activity: Activity) => { 36 | // @ts-ignore 37 | delete activity['id']; 38 | // @ts-ignore 39 | delete activity['educationId']; 40 | }) 41 | 42 | education.links.forEach((link: Link) => { 43 | // @ts-ignore 44 | delete link['id']; 45 | // @ts-ignore 46 | delete link['educationId']; 47 | // @ts-ignore 48 | delete link['workExperienceId']; 49 | // @ts-ignore 50 | delete link['projectId']; 51 | }) 52 | }); 53 | 54 | 55 | return educations; 56 | } 57 | 58 | async createEducation(body: Education): Promise { 59 | let education = await this.prismaClient.education.create({ 60 | data: { 61 | school: body.school, 62 | degree: body.degree, 63 | fieldOfStudy: body.fieldOfStudy, 64 | isCurrent: body.isCurrent, 65 | startDate: body.startDate, 66 | endDate: body.endDate, 67 | location: { 68 | connectOrCreate: { 69 | where: { 70 | city_country: { 71 | city: body.location.city, 72 | country: body.location.country 73 | } 74 | }, 75 | create: { 76 | city: body.location.city, 77 | country: body.location.country 78 | } 79 | } 80 | }, 81 | activities: { 82 | createMany: { 83 | data: body.activities 84 | } 85 | }, 86 | links: { 87 | createMany: { 88 | data: body.links 89 | } 90 | } 91 | } 92 | }); 93 | return education; 94 | } 95 | } -------------------------------------------------------------------------------- /src/repository/workExperience/WorkExperienceRepository.ts: -------------------------------------------------------------------------------- 1 | import {IWorkExperienceRepository} from "./IWorkExperienceRepository"; 2 | import {PrismaClient} from "@prisma/client"; 3 | import PrismaClientProvider from "../../helper/PrismaClientProvider"; 4 | import WorkExperience from "../../model/WorkExperience"; 5 | import WorkExperienceRoutes from "../../routes/WorkExperienceRoutes"; 6 | 7 | export default class WorkExperienceRepository implements IWorkExperienceRepository{ 8 | 9 | private prismaClient: PrismaClient; 10 | 11 | constructor() { 12 | this.prismaClient = PrismaClientProvider.getClient(); 13 | } 14 | 15 | async getAllWorkExperience(): Promise { 16 | let workExperiences = await this.prismaClient.workExperience.findMany({ 17 | include: { 18 | location: true, 19 | links: true, 20 | responsibilities: true 21 | }, 22 | orderBy: { 23 | startDate: "desc" 24 | } 25 | }); 26 | 27 | workExperiences.forEach(workExperience => { 28 | // @ts-ignore 29 | delete workExperience['id'] 30 | // @ts-ignore 31 | delete workExperience['locationId'] 32 | // @ts-ignore 33 | delete workExperience.location['id'] 34 | 35 | // @ts-ignore 36 | workExperience.responsibilities.forEach(responsibility => { 37 | // @ts-ignore 38 | delete responsibility['id']; 39 | // @ts-ignore 40 | delete responsibility['workExperienceId']; 41 | }); 42 | 43 | workExperience.links.forEach(link => { 44 | // @ts-ignore 45 | delete link['id'] 46 | // @ts-ignore 47 | delete link['workExperienceId']; 48 | // @ts-ignore 49 | delete link['educationId']; 50 | }); 51 | }) 52 | 53 | // @ts-ignore 54 | return workExperiences; 55 | } 56 | 57 | async createWorkExperience(workExperience: WorkExperience): Promise { 58 | let create = await this.prismaClient.workExperience.create({ 59 | data: { 60 | company: workExperience.company, 61 | position: workExperience.position, 62 | startDate: workExperience.startDate, 63 | endDate: workExperience.endDate, 64 | isCurrent: workExperience.isCurrent, 65 | employmentType: workExperience.employmentType, 66 | location: { 67 | connectOrCreate: { 68 | where: { 69 | city_country: { 70 | country: workExperience.location.country, 71 | city: workExperience.location.city 72 | } 73 | }, 74 | create: { 75 | city: workExperience.location.city, 76 | country: workExperience.location.country 77 | } 78 | } 79 | }, 80 | links: { 81 | createMany: { 82 | data: workExperience.links 83 | } 84 | }, 85 | responsibilities: { 86 | createMany: { 87 | data: workExperience.responsibilities 88 | } 89 | } 90 | 91 | } 92 | }); 93 | // @ts-ignore 94 | return create; 95 | } 96 | } -------------------------------------------------------------------------------- /prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | model Deployment { 6 | id Int @id @default(autoincrement()) 7 | name String 8 | description String 9 | deployedOn DateTime 10 | repoUrl String @default("") 11 | url String 12 | healthUrl String 13 | } 14 | 15 | model WorkExperience { 16 | id Int @id @default(autoincrement()) 17 | company String 18 | position String 19 | employmentType String 20 | isCurrent Boolean 21 | startDate DateTime 22 | endDate DateTime 23 | location Location @relation(fields: [locationId], references: [id]) 24 | locationId Int 25 | responsibilities Responsibility[] 26 | links Link[] 27 | } 28 | 29 | model Responsibility { 30 | id Int @id @default(autoincrement()) 31 | responsibility String 32 | workExperience WorkExperience @relation(fields: [workExperienceId], references: [id]) 33 | workExperienceId Int 34 | } 35 | 36 | model Location { 37 | id Int @id @default(autoincrement()) 38 | city String 39 | country String 40 | workExperience WorkExperience[] 41 | Education Education[] 42 | Project Project[] 43 | 44 | @@unique(fields: [city, country]) 45 | } 46 | 47 | model Link { 48 | id Int @id @default(autoincrement()) 49 | description String 50 | url String 51 | workExperience WorkExperience? @relation(fields: [workExperienceId], references: [id]) 52 | workExperienceId Int? 53 | education Education? @relation(fields: [educationId], references: [id]) 54 | educationId Int? 55 | project Project? @relation(fields: [projectId], references: [id]) 56 | projectId Int? 57 | } 58 | 59 | model Education { 60 | id Int @id @default(autoincrement()) 61 | school String 62 | degree String 63 | fieldOfStudy String 64 | isCurrent Boolean 65 | startDate DateTime 66 | endDate DateTime 67 | location Location @relation(fields: [locationId], references: [id]) 68 | locationId Int 69 | activities Activity[] 70 | links Link[] 71 | } 72 | 73 | model Activity { 74 | id Int @id @default(autoincrement()) 75 | activity String 76 | education Education @relation(fields: [educationId], references: [id]) 77 | educationId Int 78 | } 79 | 80 | model Project { 81 | id Int @id @default(autoincrement()) 82 | name String 83 | description String @db.VarChar(1500) 84 | status String 85 | category String 86 | startDate DateTime 87 | endDate DateTime 88 | location Location @relation(fields: [locationId], references: [id]) 89 | locationId Int 90 | client String 91 | technologies Technology[] 92 | links ProjectLink[] 93 | Link Link[] 94 | } 95 | 96 | model ProjectLink { 97 | id Int @id @default(autoincrement()) 98 | url String 99 | description String 100 | type String 101 | project Project @relation(fields: [projectId], references: [id]) 102 | projectId Int 103 | } 104 | 105 | model Technology { 106 | id Int @id @default(autoincrement()) 107 | technology String 108 | project Project @relation(fields: [projectId], references: [id]) 109 | projectId Int 110 | } 111 | 112 | model Certificate { 113 | id Int @id @default(autoincrement()) 114 | name String 115 | organization String 116 | description String @db.LongText 117 | issuedDate DateTime 118 | expiryDate DateTime 119 | credentialId String 120 | url String 121 | } 122 | 123 | datasource db { 124 | provider = "mysql" 125 | url = env("DATABASE_URL") 126 | } 127 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true, 4 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 5 | 6 | /* Projects */ 7 | // "incremental": true, /* Enable incremental compilation */ 8 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 9 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 10 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 11 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 12 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 13 | 14 | /* Language and Environment */ 15 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 16 | "lib": ["es6"], 17 | /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 18 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 19 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 20 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 21 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 22 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 23 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 24 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 25 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 26 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 27 | 28 | /* Modules */ 29 | "module": "commonjs", /* Specify what module code is generated. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | "resolveJsonModule": true, /* Enable importing .json files */ 38 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 39 | 40 | /* JavaScript Support */ 41 | "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 42 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 43 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 44 | 45 | /* Emit */ 46 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 47 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 48 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 49 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 50 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 51 | "outDir": "build", /* Specify an output folder for all emitted files. */ 52 | // "removeComments": true, /* Disable emitting comments. */ 53 | // "noEmit": true, /* Disable emitting files from a compilation. */ 54 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 55 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 56 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 57 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 60 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 61 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 62 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 63 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 64 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 65 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 66 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 67 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 68 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 69 | 70 | /* Interop Constraints */ 71 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 72 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 73 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 74 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 75 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 76 | 77 | /* Type Checking */ 78 | "strict": true, /* Enable all strict type-checking options. */ 79 | "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 80 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 81 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 82 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 83 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 84 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 85 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 86 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 87 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 88 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 89 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 90 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 91 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 92 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 93 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 94 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 95 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 96 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 97 | 98 | /* Completeness */ 99 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 100 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 101 | } 102 | } 103 | --------------------------------------------------------------------------------