diff --git a/.env.example b/.env.example index 0b33b40..548c802 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,6 @@ -PORT = \ No newline at end of file +DBNAME=database +DBUSER=postgres +DBPASSWORD=password +PORT=5432 +DBHOST=127.0.0.1 +SECRETKEY=any_secret \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1606528..03ccdab 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ pids *.seed *.pid.lock +# My DB config +src/api/db/config/config.js + # Directory for instrumented libs generated by jscoverage/JSCover lib-cov diff --git a/config.example.js b/config.example.js deleted file mode 100644 index 8d2620e..0000000 --- a/config.example.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - "username": "username", - "password": "password", - "database": "databaseName", - "host": "127.0.0.1", - "dialect": "postgres" -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b964439..5e98c35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "body-parser": "^1.20.1", "dotenv": "^16.0.3", "express": "^4.18.2", + "faker": "^5.5.3", "pg": "^8.8.0", "pg-hstore": "^2.3.4", "sequelize": "^6.25.3" @@ -4177,6 +4178,11 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "node_modules/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5433,9 +5439,9 @@ } }, "node_modules/loader-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", - "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -11501,6 +11507,11 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -12405,9 +12416,9 @@ "peer": true }, "loader-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", - "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", diff --git a/package.json b/package.json index 1499ac3..f4b2dfe 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,9 @@ "scripts": { "start": "nodemon --exec babel-node ./src/server.js", "watch:dev": "nodemon ./src/server.js", + "migrate": "sequelize db:migrate", + "migrate:undo": "sequelize db:migrate:undo:all", + "seed": "sequelize db:seed:all", "build": "rm -rf ./build && babel -d ./build ./src -s", "lint": "eslint --ext .js .", "lint:check": "eslint .", @@ -20,6 +23,7 @@ "body-parser": "^1.20.1", "dotenv": "^16.0.3", "express": "^4.18.2", + "faker": "^5.5.3", "pg": "^8.8.0", "pg-hstore": "^2.3.4", "sequelize": "^6.25.3" diff --git a/src/db/migrations/20221030101534-create-notice.js b/src/db/migrations/20221030101534-create-notice.js index 0546275..7aa66b7 100644 --- a/src/db/migrations/20221030101534-create-notice.js +++ b/src/db/migrations/20221030101534-create-notice.js @@ -5,13 +5,23 @@ module.exports = { await queryInterface.createTable('Notices', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, notice: { type: Sequelize.STRING }, + classId: { + type: Sequelize.UUID, + allowNull:false, + foreignKey:true + }, + teacherId: { + type: Sequelize.UUID, + allowNull:false, + foreignKey:true + }, createdAt: { allowNull: false, type: Sequelize.DATE diff --git a/src/db/migrations/20221030101627-create-assignment-score.js b/src/db/migrations/20221030101627-create-assignment-score.js index 0bd0b09..1b4c113 100644 --- a/src/db/migrations/20221030101627-create-assignment-score.js +++ b/src/db/migrations/20221030101627-create-assignment-score.js @@ -5,9 +5,9 @@ module.exports = { await queryInterface.createTable('AssignmentScores', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, assignmentId: { type:Sequelize.STRING, @@ -17,11 +17,12 @@ module.exports = { type:Sequelize.STRING, allowNull:false }, - studentId: { - type:Sequelize.STRING, - allowNull:false + teacherId: { + type: Sequelize.UUID, + allowNull:false, + foreignKey:true }, - teacher: { + studentId: { type:Sequelize.STRING, allowNull:false }, diff --git a/src/db/migrations/20221030101644-create-assignment.js b/src/db/migrations/20221030101644-create-assignment.js index 2eb1c55..a05221e 100644 --- a/src/db/migrations/20221030101644-create-assignment.js +++ b/src/db/migrations/20221030101644-create-assignment.js @@ -5,9 +5,9 @@ module.exports = { await queryInterface.createTable('Assignments', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, assignment: { type: Sequelize.STRING @@ -16,6 +16,10 @@ module.exports = { type: Sequelize.STRING, allowNull:false }, + teacherId:{ + type: Sequelize.UUID, + allowNull:false + }, studentId:{ type: Sequelize.STRING, allowNull:false diff --git a/src/db/migrations/20221030101744-create-role.js b/src/db/migrations/20221030101744-create-role.js index 54efd47..59ecb5f 100644 --- a/src/db/migrations/20221030101744-create-role.js +++ b/src/db/migrations/20221030101744-create-role.js @@ -5,9 +5,9 @@ module.exports = { await queryInterface.createTable('Roles', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, role: { type: Sequelize.STRING diff --git a/src/db/migrations/20221030101838-create-class-teacher.js b/src/db/migrations/20221030101838-create-class-teacher.js index a7efd88..871de47 100644 --- a/src/db/migrations/20221030101838-create-class-teacher.js +++ b/src/db/migrations/20221030101838-create-class-teacher.js @@ -5,13 +5,18 @@ module.exports = { await queryInterface.createTable('ClassTeachers', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, classId: { type: Sequelize.STRING }, + teacherId:{ + type: Sequelize.UUID, + allowNull:false, + foreignKey:true + }, createdAt: { allowNull: false, type: Sequelize.DATE diff --git a/src/db/migrations/20221030101917-create-class.js b/src/db/migrations/20221030101917-create-class.js index 539d29d..7938bab 100644 --- a/src/db/migrations/20221030101917-create-class.js +++ b/src/db/migrations/20221030101917-create-class.js @@ -5,13 +5,17 @@ module.exports = { await queryInterface.createTable('Classes', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, className: { type: Sequelize.STRING }, + year: { + type:Sequelize.STRING, + allowNull:false + }, createdAt: { allowNull: false, type: Sequelize.DATE diff --git a/src/db/migrations/20221030102005-create-class-student.js b/src/db/migrations/20221030102005-create-class-student.js index 6d4a512..bea5287 100644 --- a/src/db/migrations/20221030102005-create-class-student.js +++ b/src/db/migrations/20221030102005-create-class-student.js @@ -1,22 +1,24 @@ 'use strict'; - -const { DataTypes } = require('sequelize'); - /** @type {import('sequelize-cli').Migration} */ module.exports = { async up(queryInterface, Sequelize) { await queryInterface.createTable('ClassStudents', { id: { allowNull: false, - autoIncrement: true, primaryKey: true, - type: Sequelize.UUID + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 }, studentId:{ type: Sequelize.UUID, allowNull:false, foreignKey:true }, + classId:{ + type: Sequelize .UUID, + allowNull:false, + foreignKey:true + }, createdAt: { allowNull: false, type: Sequelize.DATE diff --git a/src/db/models/classstudent.js b/src/db/models/classstudent.js index d4d2874..c4afc74 100644 --- a/src/db/models/classstudent.js +++ b/src/db/models/classstudent.js @@ -20,14 +20,18 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, allowNull:false, - unique:true, primaryKey: true }, studentId:{ type: DataTypes.UUID, allowNull:false, foreignKey:true - } + }, + classId:{ + type: DataTypes.UUID, + allowNull:false, + foreignKey:true + }, }, { sequelize, modelName: 'ClassStudent', diff --git a/src/db/models/classteacher.js b/src/db/models/classteacher.js index 49d0dae..5f883ca 100644 --- a/src/db/models/classteacher.js +++ b/src/db/models/classteacher.js @@ -15,10 +15,11 @@ module.exports = (sequelize, DataTypes) => { } } ClassTeacher.init({ - id:{ + id: { + allowNull: false, + primaryKey: true, type: DataTypes.UUID, - allowNull:false, - primaryKey: true + defaultValue: DataTypes.UUIDV4 }, teacherId:{ type: DataTypes.UUID, diff --git a/src/db/models/notice.js b/src/db/models/notice.js index f91bab5..74b57d8 100644 --- a/src/db/models/notice.js +++ b/src/db/models/notice.js @@ -16,6 +16,11 @@ module.exports = (sequelize, DataTypes) => { } } Notice.init({ + id: { + allowNull: false, + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4 + }, notice: { type:DataTypes.STRING, allowNull:false, diff --git a/src/db/seeders/20221117052621-User.js b/src/db/seeders/20221117052621-User.js new file mode 100644 index 0000000..2f72668 --- /dev/null +++ b/src/db/seeders/20221117052621-User.js @@ -0,0 +1,50 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +//import bcrypt from 'bcrypt' +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + await queryInterface.bulkInsert('Users', [{ + id: "c7a9122e-6694-11ed-9022-0242ac120005", + first_name: 'John', + last_name: 'Doe', + second_name: 'Nok', + email: 'example@example2.com', + roleId:'c7a9122e-6694-11ed-9022-0242ac120001', + password: 'nok', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: "c7a9122e-6694-11ed-9022-0242ac120006", + first_name: 'John', + last_name: 'Doe', + second_name: 'Nok', + email: 'example@example3.com', + roleId: 'c7a9122e-6694-11ed-9022-0242ac120003', + password: 'nok', + createdAt: new Date(), + updatedAt: new Date() + }], {}); + + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + await queryInterface.bulkDelete('Users', null, {}); + } +}; diff --git a/src/db/seeders/20221117052728-Role.js b/src/db/seeders/20221117052728-Role.js new file mode 100644 index 0000000..f6ccb3e --- /dev/null +++ b/src/db/seeders/20221117052728-Role.js @@ -0,0 +1,44 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + await queryInterface.bulkInsert('Roles', [{ + id: "c7a9122e-6694-11ed-9022-0242ac120001", + role: 'Admin', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: "c7a9122e-6694-11ed-9022-0242ac120002", + role: 'Student', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: "c7a9122e-6694-11ed-9022-0242ac120003", + role: 'Teacher', + createdAt: new Date(), + updatedAt: new Date() + }], {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + await queryInterface.bulkDelete('Roles', null, {}); + } +}; diff --git a/src/db/seeders/20221117052755-Notice.js b/src/db/seeders/20221117052755-Notice.js new file mode 100644 index 0000000..c8cca3f --- /dev/null +++ b/src/db/seeders/20221117052755-Notice.js @@ -0,0 +1,40 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') + +faker.seed(123); +const notices = [...Array(100)].map((notice) => ( + { + id: faker.datatype.uuid(), + notice: faker.lorem.sentences(3), + classId: faker.datatype.uuid(), + teacherId: faker.datatype.uuid(), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + return await queryInterface.bulkInsert('Notices', notices, {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + return await queryInterface.bulkDelete('People', null, {}); + } +}; diff --git a/src/db/seeders/20221117052807-Message.js b/src/db/seeders/20221117052807-Message.js new file mode 100644 index 0000000..ac54f37 --- /dev/null +++ b/src/db/seeders/20221117052807-Message.js @@ -0,0 +1,42 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') + +faker.seed(123); +const messages = [...Array(100)].map((message) => ( + { + id: faker.datatype.uuid(), + message: faker.lorem.sentence(), + senderId: faker.datatype.uuid(), + receiverId: faker.datatype.uuid(), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + return await queryInterface.bulkInsert('Messages', messages, {}); + + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + return await queryInterface.bulkDelete('Messages', null, {}); + } +}; diff --git a/src/db/seeders/20221117052826-ClassTeacher.js b/src/db/seeders/20221117052826-ClassTeacher.js new file mode 100644 index 0000000..fcea8d3 --- /dev/null +++ b/src/db/seeders/20221117052826-ClassTeacher.js @@ -0,0 +1,39 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') + +faker.seed(123); +const classTeachers = [...Array(100)].map((classTeacher) => ( + { + id: faker.datatype.uuid(), + teacherId: faker.datatype.uuid(), + classId: faker.datatype.uuid(), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + return await queryInterface.bulkInsert('ClassTeachers', classTeachers, {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + return await queryInterface.bulkDelete('ClassTeachers', null, {}); + } +}; diff --git a/src/db/seeders/20221117052849-ClassStudent.js b/src/db/seeders/20221117052849-ClassStudent.js new file mode 100644 index 0000000..1439f3c --- /dev/null +++ b/src/db/seeders/20221117052849-ClassStudent.js @@ -0,0 +1,39 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') + +faker.seed(123); +const classStudents = [...Array(100)].map((classStudent) => ( + { + id: faker.datatype.uuid(), + studentId: faker.datatype.uuid(), + classId: faker.datatype.uuid(), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + return await queryInterface.bulkInsert('ClassStudents', classStudents, {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + return await queryInterface.bulkDelete('People', null, {}); + } +}; diff --git a/src/db/seeders/20221117052907-Class.js b/src/db/seeders/20221117052907-Class.js new file mode 100644 index 0000000..fe8598c --- /dev/null +++ b/src/db/seeders/20221117052907-Class.js @@ -0,0 +1,39 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') + +faker.seed(123); +const classes = [...Array(100)].map((classs) => ( + { + id: faker.datatype.uuid(), + className: faker.datatype.uuid(), + year: faker.date.between(), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + return await queryInterface.bulkInsert('Classes', classes, {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + return await queryInterface.bulkDelete('Classes', null, {}); + } +}; diff --git a/src/db/seeders/20221117052927-Assignment.js b/src/db/seeders/20221117052927-Assignment.js new file mode 100644 index 0000000..ea6ef48 --- /dev/null +++ b/src/db/seeders/20221117052927-Assignment.js @@ -0,0 +1,41 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') +faker.seed(123); + +const assignments = [...Array(100)].map((assignment) => ( + { + id: faker.datatype.uuid(), + teacherId: faker.datatype.uuid(), + classId: faker.datatype.uuid(), + studentId: faker.datatype.uuid(), + assignment: faker.system.filePath('pdf'), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + return await queryInterface.bulkInsert('Assignments', assignments, {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + await queryInterface.bulkDelete('Assignments', null, {}); + } +}; diff --git a/src/db/seeders/20221117052946-AssignmentScore.js b/src/db/seeders/20221117052946-AssignmentScore.js new file mode 100644 index 0000000..c8dce40 --- /dev/null +++ b/src/db/seeders/20221117052946-AssignmentScore.js @@ -0,0 +1,41 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +const faker = require('faker') +faker.seed(123); + +const assignmentScores = [...Array(100)].map((assignmentScore) => ( + { + id: faker.datatype.uuid(), + teacherId: faker.datatype.uuid(), + assignmentId: faker.datatype.uuid(), + studentId: faker.datatype.uuid(), + score: faker.datatype.number(100), + createdAt: new Date(), + updatedAt: new Date() + } +)) +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add seed commands here. + * + * Example: + * await queryInterface.bulkInsert('People', [{ + * name: 'John Doe', + * isBetaMember: false + * }], {}); + */ + await queryInterface.bulkInsert('AssignmentScores', assignmentScores, {}); + }, + + async down (queryInterface, Sequelize) { + /** + * Add commands to revert seed here. + * + * Example: + * await queryInterface.bulkDelete('People', null, {}); + */ + await queryInterface.bulkDelete('AssignmentScores', null, {}); + } +};