Commit f0a5d17f authored by dylan.peiry's avatar dylan.peiry
Browse files

Merge branch 'dev' into 'main'

feat(sprint3): Source code release of the sprint3

See merge request !19
parents 0505ca3f a44a5e12
......@@ -83,3 +83,6 @@ buildNumber.properties
# intellij
*.iml
# End of https://www.toptal.com/developers/gitignore/api/maven
api/.env
api/node_modules
api/.data/
......@@ -103,15 +103,17 @@ Commencer la journée par 3 minutes de Daily Scrum.
![Roadmap](screenshot/UserStories.JPG)
---
# Objectifs Sprint 1
---
---
# Sprint 1 (24.03.2022 - 14.04.2022)
## Objectifs Sprint 1
- Afficher la carte interactive (menu)
- Afficher un emplacement utilisateur (pin) sur la carte
- Afficher un utilisateur (text box) map en fond
- Afficher un profil (UI)
- Modifier un profil (UI)
# Sprint 1 - Backlog
## Sprint 1 - Backlog
![Roadmap](screenshot/Sprint1_Backlog.jpg)
*Dylan & Nikola* : Afficher la carte
......@@ -122,7 +124,7 @@ Commencer la journée par 3 minutes de Daily Scrum.
---
## How to setup (javaFX + maven)
### How to setup (javaFX + maven)
Java version : 17.0.2
Maven version : 3.6.3
......@@ -141,7 +143,7 @@ Run program with maven :
mvn clean javafx:run
```
## Create a branch and push it
### Create a branch and push it
```console
git checkout -b [branchName] [baseBranch=dev]
```
......@@ -159,10 +161,8 @@ mvn clean javafx:run
```
---
---
# Présentation Sprint 1
## Présentation Sprint 1
- Introduire le sujet (Maxence) -> gestion des branches avec git
- Montrer les objectifs du sprint 1 (Maxence) BACKLOG
- Présenter ce qui est fonctionnel :
......@@ -170,4 +170,43 @@ mvn clean javafx:run
- Markers (Scott)
- Scene (John)
- Profile (Niko)
- Conclution (Damian)
\ No newline at end of file
- Conclution (Damian)
## Retrospective du Sprint 1
### KDS (Keep Drop Start)
![Retrospective Sprint 1](screenshot/Sprint1_Retrospective.jpg)
---
---
---
# Sprint 2 (14.04.2022 - 19.05.2022)
## Sprint 2 - Backlog
![Backlog Sprint 2](screenshot/Sprint2_Backlog.jpg)
## Présentation Sprint 2
1. Maxence : remise en contexte
2. Scott : pins
3. Damian : comportement CRUD
4. Niko : graphique profile
5. Dylan : graphique CRUD
6. John : redimension + responsivness
## Retrospective du Sprint 2
### KDS (Keep Drop Start)
![Retrospective Sprint 2](screenshot/Sprint2_Retrospective.jpg)
---
---
---
# Sprint 3 (19.05.2022 - 16.06.2022)
## Sprint 3 - Backlog
![Backlog Sprint 3](screenshot/Sprint3_Backlog.jpg)
## Choses IMPORTANTES a changer
- Tout passer en français !!!
\ No newline at end of file
API_PORT=30992
DATABASE=geoconnect
DIALECT=mysql
USERNAME=
PASSWORD=
HOST=localhost
PORT=3306
\ No newline at end of file
node_modules/
version: '3'
services:
database:
image: mysql:5.7
volumes:
- ./.data/db:/var/lib/mysql:rw
- ./sql/geoconnect.sql:/data/application/database.sql
command: --init-file /data/application/database.sql
environment:
- MYSQL_ROOT_PASSWORD=root
- "MYSQL_DATABASE=${DATABASE}"
- "MYSQL_USER=${USERNAME}"
- "MYSQL_PASSWORD=${PASSWORD}"
ports:
- "${PORT}:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- 1028:80
links:
- database
environment:
- PMA_HOST=database
- "MYSQL_USER=${USERNAME}"
- "MYSQL_PASSWORD=${PASSWORD}"
- MYSQL_ROOT_PASSWORD=root
# Choix technologies
# Routes
# Fonctionnalités
## Fonctionnel
## Non fonctionnel
# Sources
# Setup
\ No newline at end of file
This diff is collapsed.
{
"name": "architecture_web_tp",
"description": "Template du projet d'architecture web",
"version": "1.0.0",
"license": "",
"author": "Michaël Minelli <michael-jean.minelli@hesge.ch>",
"main": "dist/server.js",
"scripts": {
"clean": "rm -R dist/*",
"build": "npx tsc --project ./",
"start:dev": "npx nodemon src/app.ts",
"start:prod": "NODE_ENV=production npx node dist/app.js"
},
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^16.0.0",
"express": "^4.18.0",
"express-validator": "^6.14.0",
"form-data": "^4.0.0",
"helmet": "^5.0.2",
"http-status-codes": "^2.2.0",
"jsonwebtoken": "^8.5.1",
"mariadb": "^3.0.0",
"morgan": "^1.10.0",
"multer": "^1.4.4",
"mysql2": "^2.3.3",
"node": "^17.7.0",
"npm": "^8.9.0",
"sequelize": "^6.20.1",
"winston": "^3.7.2"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/jsonwebtoken": "^8.5.8",
"@types/morgan": "^1.9.3",
"@types/multer": "^1.4.7",
"@types/node": "^17.0.31",
"nodemon": "^2.0.16",
"ts-node": "^10.7.0",
"typescript": "^4.6.4"
}
}
-- phpMyAdmin SQL Dump
-- version 5.1.1
-- https://www.phpmyadmin.net/
--
-- Hôte : 127.0.0.1:3306
-- Généré le : jeu. 02 juin 2022 à 09:41
-- Version du serveur : 5.7.36
-- Version de PHP : 7.4.26
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Base de données : `geoconnect`
--
CREATE DATABASE IF NOT EXISTS `geoconnect` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `geoconnect`;
-- --------------------------------------------------------
--
-- Structure de la table `event`
--
DROP TABLE IF EXISTS `event`;
CREATE TABLE IF NOT EXISTS `event` (
`idEvent` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
`dateStart` date NOT NULL,
`dateEnd` date NOT NULL,
`datePublish` date NOT NULL,
`latitude` float NOT NULL,
`longitude` float NOT NULL,
`address` varchar(255) NOT NULL,
`maxAttendees` int(11) NOT NULL,
`isActive` tinyint(1) NOT NULL,
PRIMARY KEY (`idEvent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Structure de la table `interest`
--
DROP TABLE IF EXISTS `interest`;
CREATE TABLE IF NOT EXISTS `interest` (
`nameInterest` varchar(255) NOT NULL,
PRIMARY KEY `name` (`nameInterest`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Structure de la table `participation`
--
DROP TABLE IF EXISTS `attendance`;
CREATE TABLE IF NOT EXISTS `attendance` (
`idAttendance` int(11) NOT NULL AUTO_INCREMENT,
`idEvent` int(11) NOT NULL,
`idUser` int(11) NOT NULL,
PRIMARY KEY (`idAttendance`),
KEY `idEvent` (`idEvent`),
KEY `idParticipant` (`idUser`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Structure de la table `profile_interest`
--
DROP TABLE IF EXISTS `user_interest`;
CREATE TABLE IF NOT EXISTS `user_interest` (
`idUser` int(11) NOT NULL,
`nameInterest` varchar(255) NOT NULL,
PRIMARY KEY (`idUser`,`nameInterest`),
KEY `nameInterest` (`nameInterest`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Structure de la table `user`
--
DROP TABLE IF EXISTS `user`;
CREATE TABLE IF NOT EXISTS `user` (
`idUser` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`firstname` varchar(50) NOT NULL,
`birthday` date NOT NULL,
`picture` varchar(255) NOT NULL,
`latitude` float NOT NULL,
`longitude` float NOT NULL,
`address` varchar(255) NOT NULL,
PRIMARY KEY (`idUser`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Contraintes pour les tables déchargées
--
--
-- Contraintes pour la table `participation`
--
ALTER TABLE `attendance`
ADD CONSTRAINT `attendance_ibfk_1` FOREIGN KEY (`idEvent`) REFERENCES `event` (`idEvent`),
ADD CONSTRAINT `attendance_ibfk_2` FOREIGN KEY (`idUser`) REFERENCES `user` (`idUser`);
--
-- Contraintes pour la table `profile_interest`
--
ALTER TABLE `user_interest`
ADD CONSTRAINT `user_interest_ibfk_1` FOREIGN KEY (`nameInterest`) REFERENCES `interest` (`nameInterest`);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
// Read from the .env file
// ATTENTION : This line MUST be the first of this file
require('dotenv').config();
import ClusterManager from './process/ClusterManager';
import Server from './express/Server';
import WorkerRole from './process/WorkerRole';
(new ClusterManager([{
role : WorkerRole.API,
quantity : ClusterManager.CORES,
restartOnFail: true,
loadTask : () => { return new Server(); }
}])).run();
class Config {
private static _instance: Config;
public readonly production: boolean;
public readonly api: {
port: number
};
private constructor() {
this.production = process.env.NODE_ENV === 'production';
this.api = {
port: Number(process.env.API_PORT)
};
}
public static get instance(): Config {
if (!Config._instance) {
Config._instance = new Config();
}
return Config._instance;
}
}
export default Config.instance;
const Event = require('../models/Event');
/**
* Handle users database operations
*/
export class EventController {
static getAll = async () => {
const events = await Event.findAll();
return events;
}
static getById = async (id: number) => {
}
static create = async (body: any) => {
}
static deleteById = async (id: number) => {
}
}
\ No newline at end of file
const Role = require('../models/Role');
/**
* Handle users database operations
*/
export class RoleController {
static getAll = async () => {
}
static getById = async (id: number) => {
}
static create = async (body: any) => {
}
static deleteById = async (id: number) => {
}
}
\ No newline at end of file
const {Sequelize} = require('sequelize');
const database = process.env.DATABASE;
const dialect = process.env.DIALECT;
const username = process.env.USERNAME;
const password = process.env.PASSWORD;
const host = process.env.HOST;
const port = process.env.PORT;
export const sequelize = new Sequelize(database, username, password, {
host,
port,
dialect
});
\ No newline at end of file
import {Express} from 'express-serve-static-core';
import cors from 'cors';
import morganMiddleware from '../logging/MorganMiddleware';
import logger from '../logging/WinstonLogger';
import {AddressInfo} from 'net';
import http from 'http';
import helmet from 'helmet';
import express from 'express';
import WorkerTask from '../process/WorkerTask';
import multer from 'multer';
import Config from '../config/Config';
import BaseRoutes from '../routes/BaseRoutes';
import {sequelize} from "../db/DatabaseInit";
import EventRoutes from "../routes/EventRoutes";
class Server implements WorkerTask {
private readonly backend: Express;
private server: http.Server;
constructor() {
this.backend = express();
this.backend.use(multer().none()); //Used for extract params from body with format "form-data", The none is for say that we do not wait a file in params
this.backend.use(morganMiddleware); //Log API accesses
this.backend.use(helmet()); //Help to secure express, https://helmetjs.github.io/
this.backend.use(cors()); //Allow CORS requests
//TODO: Add routes and middlewares
this.backend.use('/', BaseRoutes);
this.backend.use('/events', EventRoutes);
}
run() {
this.server = this.backend.listen(Config.api.port, '0.0.0.0', () => {
const {
port,
address
} = this.server.address() as AddressInfo;
logger.info(`Server started on http://${address}:${port}`);
});
}
}
export default Server;
import morgan, { StreamOptions } from 'morgan';
import logger from './WinstonLogger';
const stream: StreamOptions = {
write: (message) => logger.http(message)
};
const skip = () => {
return false; //SharedConfig.production;
};
const morganMiddleware = morgan(':method :url :status :res[content-length] - :response-time ms', {
stream,
skip
});
export default morganMiddleware;
import winston from 'winston';
import * as Transport from 'winston-transport';
import Config from '../config/Config';
const levels = {
error: 0,
warn : 1,
info : 2,
http : 3,
debug: 4
};
const level = () => {
return Config.production ? 'warn' : 'debug';
};
const colors = {
error: 'red',
warn : 'yellow',
info : 'green',
http : 'magenta',
debug: 'white'
};
winston.addColors(colors);
const format = winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }), Config.production ? winston.format.uncolorize() : winston.format.colorize({ all: true }), winston.format.printf((info) => `${ info.timestamp } [${ process.pid }] ${ info.level }: ${ info.message }`));
// Set type of logs (console, file, etc.)
let transports: Array<Transport> = [new winston.transports.Console()];
if (Config.production) {
transports = transports.concat([new winston.transports.File({
filename: 'logs/error.log',
level : 'error'
}), new winston.transports.File({ filename: 'logs/all.log' })]);
}
// Create logger instance
const logger = winston.createLogger({
level: level(),
levels,
format,
transports
});
export default logger;
import {DataTypes, Model, Sequelize} from "sequelize";
import {sequelize} from "../db/DatabaseInit";
//Model definition
const Event = sequelize.define('event', {
idEvent: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING,
allowNull: false
},
dateStart: {
type: DataTypes.DATE,
allowNull: false
},
dateEnd: {
type: DataTypes.DATE,
allowNull: false
},
datePublish: {
type: DataTypes.DATE,
allowNull: false
},
latitude: {
type: DataTypes.FLOAT,
allowNull: false
},
longitude: {
type: DataTypes.FLOAT,
allowNull: false
},
address: {
type: DataTypes.STRING,
allowNull: false
},
maxAttendees: {
type: DataTypes.INTEGER,
allowNull: false
},
isActive: {
type: DataTypes.BOOLEAN,
allowNull: false
}
}, {timestamps: false, tableName: 'event'});
module.exports = Event;
\ No newline at end of file
import {DataTypes, Model, Sequelize} from "sequelize";
import {sequelize} from "../db/DatabaseInit";