diff --git a/src/controller/review-object.controller/index.js b/src/controller/review-object.controller/index.js new file mode 100644 index 00000000..e13cb5b3 --- /dev/null +++ b/src/controller/review-object.controller/index.js @@ -0,0 +1,10 @@ +const router = require('express').Router() +const controller = require('./review-object.controller') +const mw = require('../../middleware/middleware') + +router.get('/review/org/:identifier', mw.useRegistry(), mw.validateUser, mw.onlySecretariat, controller.getReviewObjectByOrgIdentifier) +router.get('/review/orgs', mw.useRegistry(), mw.validateUser, mw.onlySecretariat, controller.getAllReviewObjects) +router.put('/review/org/:uuid', mw.useRegistry(), mw.validateUser, mw.onlySecretariat, controller.updateReviewObjectByReviewUUID) +router.post('/review/org/', mw.useRegistry(), mw.validateUser, mw.onlySecretariat, controller.createReviewObject) + +module.exports = router diff --git a/src/controller/review-object.controller/review-object.controller.js b/src/controller/review-object.controller/review-object.controller.js new file mode 100644 index 00000000..7248b7cc --- /dev/null +++ b/src/controller/review-object.controller/review-object.controller.js @@ -0,0 +1,80 @@ + +const validateUUID = require('uuid').validate +async function getReviewObjectByOrgIdentifier (req, res, next) { + const repo = req.ctx.repositories.getReviewObjectRepository() + const identifier = req.params.identifier + const identifierIsUUID = validateUUID(identifier) + if (!identifier) { + return res.status(400).json({ message: 'Missing identifier parameter' }) + } + let value + // We may want this to be something different, but for now we are just testing + if (identifierIsUUID) { + value = await repo.getOrgReviewObjectByOrgUUID(identifier) + } else { + value = await repo.getOrgReviewObjectByOrgShortname(identifier) + } + return res.status(200).json(value) +} + +async function getAllReviewObjects (req, res, next) { + const repo = req.ctx.repositories.getReviewObjectRepository() + const value = await repo.getAllReviewObjects() + return res.status(200).json(value) +} + +async function updateReviewObjectByReviewUUID (req, res, next) { + const repo = req.ctx.repositories.getReviewObjectRepository() + const UUID = req.params.uuid + const orgRepo = req.ctx.repositories.getBaseOrgRepository() + const body = req.body + + const result = orgRepo.validateOrg(body.new_review_data) + if (!result.isValid) { + return res.status(400).json({ message: 'Invalid new_review_data', errors: result.errors }) + } + + const value = await repo.updateReviewOrgObject(body, UUID) + + if (!value) { + return res.status(404).json({ message: `No review object found with UUID ${UUID}` }) + } + return res.status(200).json(value) +} + +async function createReviewObject (req, res, next) { + const repo = req.ctx.repositories.getReviewObjectRepository() + const orgRepo = req.ctx.repositories.getBaseOrgRepository() + const body = req.body + + if (body.uuid) { + return res.status(400).json({ message: 'Do not pass in a uuid key when creating a review object' }) + } + + if (!body.target_object_uuid) { + return res.status(400).json({ message: 'Missing required field target_object_uuid' }) + } + + if (!body.new_review_data) { + return res.status(400).json({ message: 'Missing required field new_review_data' }) + } + + // Validate the data going into "new_review_data" + const result = orgRepo.validateOrg(body.new_review_data) + if (!result.isValid) { + return res.status(400).json({ message: 'Invalid new_review_data', errors: result.errors }) + } + + const value = await repo.createReviewOrgObject(body) + + if (!value) { + return res.status(500).json({ message: 'Failed to create review object' }) + } + return res.status(200).json(value) +} +module.exports = { + getReviewObjectByOrgIdentifier, + getAllReviewObjects, + updateReviewObjectByReviewUUID, + createReviewObject +} diff --git a/src/model/reviewobject.js b/src/model/reviewobject.js new file mode 100644 index 00000000..a5436cd2 --- /dev/null +++ b/src/model/reviewobject.js @@ -0,0 +1,19 @@ +const mongoose = require('mongoose') +const aggregatePaginate = require('mongoose-aggregate-paginate-v2') +const MongoPaging = require('mongo-cursor-pagination') + +const schema = { + uuid: String, + target_object_uuid: String, + status: String, + new_review_data: Object // This should be a object containing the new org data in the format of the base org model or one of its descriminators (e.g. CNAOrg, ADPOrg) +} + +const ReviewOrgSchema = new mongoose.Schema(schema, { collection: 'ReviewObject', timestamps: { createdAt: 'created', updatedAt: 'last_updated' } }) + +ReviewOrgSchema.plugin(aggregatePaginate) + +// Cursor pagination +ReviewOrgSchema.plugin(MongoPaging.mongoosePlugin) +const ReviewObject = mongoose.model('ReviewObject', ReviewOrgSchema) +module.exports = ReviewObject diff --git a/src/repositories/repositoryFactory.js b/src/repositories/repositoryFactory.js index 38dc6450..67aa6ef4 100644 --- a/src/repositories/repositoryFactory.js +++ b/src/repositories/repositoryFactory.js @@ -7,6 +7,7 @@ const RegistryUserRepository = require('./registryUserRepository') const RegistryOrgRepository = require('./registryOrgRepository') const BaseOrgRepository = require('./baseOrgRepository') const BaseUserRepository = require('./baseUserRepository') +const ReviewObjectRepository = require('./reviewObjectRepository') class RepositoryFactory { getOrgRepository () { @@ -53,6 +54,11 @@ class RepositoryFactory { const repo = new BaseUserRepository() return repo } + + getReviewObjectRepository () { + const repo = new ReviewObjectRepository() + return repo + } } module.exports = RepositoryFactory diff --git a/src/repositories/reviewObjectRepository.js b/src/repositories/reviewObjectRepository.js new file mode 100644 index 00000000..fd5f69cf --- /dev/null +++ b/src/repositories/reviewObjectRepository.js @@ -0,0 +1,75 @@ +const ReviewObjectModel = require('../model/reviewobject') +const BaseRepository = require('./baseRepository') +const BaseOrgRepository = require('./baseOrgRepository') +const uuid = require('uuid') + +class ReviewObjectRepository extends BaseRepository { + async findOneByOrgShortName (orgShortName, options = {}) { + const baseOrgRepository = new BaseOrgRepository() + const org = await baseOrgRepository.findOneByShortName(orgShortName) + if (!org) { + throw new Error(`No organization found with short name ${orgShortName}`) + } + const reviewObject = await ReviewObjectModel.find({ target_object_uuid: org.UUID }, null, options) + + return reviewObject || null + } + + async findOneByUUID (UUID, options = {}) { + const reviewObject = await ReviewObjectModel.findOne({ uuid: UUID }, null, options) + return reviewObject || null + } + + async getAllReviewObjects (options = {}) { + const reviewObjects = await ReviewObjectModel.find({}, null, options) + return reviewObjects || [] + } + + async deleteReviewObjectByUUID (UUID, options = {}) { + const result = await ReviewObjectModel.deleteOne({ uuid: UUID }, options) + return result.deletedCount + } + + async getOrgReviewObjectByOrgShortname (orgShortName, options = {}) { + const baseOrgRepository = new BaseOrgRepository() + const org = await baseOrgRepository.findOneByShortName(orgShortName) + if (!org) { + throw new Error(`No organization found with short name ${orgShortName}`) + } + const reviewObject = await ReviewObjectModel.findOne({ target_object_uuid: org.UUID }, null, options) + + return reviewObject || null + } + + async getOrgReviewObjectByOrgUUID (orgUUID, options = {}) { + const baseOrgRepository = new BaseOrgRepository() + const org = await baseOrgRepository.findOneByUUID(orgUUID) + if (!org) { + throw new Error(`No organization found with UUID ${orgUUID}`) + } + const reviewObject = await ReviewObjectModel.findOne({ target_object_uuid: org.UUID }, null, options) + + return reviewObject || null + } + + async createReviewOrgObject (body, options = {}) { + console.log('Creating review object for organization:', body.target_object_uuid) + body.uuid = uuid.v4() + const reviewObject = new ReviewObjectModel(body) + const result = await reviewObject.save(options) + return result.toObject() + } + + async updateReviewOrgObject (body, UUID, options = {}) { + console.log('Updating review object with UUID:', UUID) + const reviewObject = await this.findOneByUUID(UUID, options) + + // For each item waiting for approval, for testing we are going to just do shortname + reviewObject.new_review_data.short_name = body.new_review_data.short_name || reviewObject.new_review_data.short_name + + const result = await reviewObject.save(options) + return result.toObject() + } +} + +module.exports = ReviewObjectRepository diff --git a/src/routes.config.js b/src/routes.config.js index 7ce0fb50..46b3149f 100644 --- a/src/routes.config.js +++ b/src/routes.config.js @@ -9,6 +9,7 @@ const SystemController = require('./controller/system.controller') const UserController = require('./controller/user.controller') const RegistryUserController = require('./controller/registry-user.controller') const RegistryOrgController = require('./controller/registry-org.controller') +const ReviewObjectController = require('./controller/review-object.controller') var options = { swaggerOptions: { @@ -34,6 +35,7 @@ module.exports = async function configureRoutes (app) { app.use('/api/', UserController) app.use('/api/', RegistryUserController) app.use('/api/', RegistryOrgController) + app.use('/api/', ReviewObjectController) app.get('/api-docs/openapi.json', (req, res) => res.json(openApiSpecification)) app.use('/api-docs', swaggerUi.serveFiles(null, options), swaggerUi.setup(null, setupOptions)) app.use('/schemas/', SchemasController)