This commit is contained in:
xfarrow 2024-10-21 16:37:51 +02:00
parent b0bfd1fe59
commit ba4f1a5d8b
8 changed files with 57 additions and 26 deletions

View File

@ -14,19 +14,20 @@
const knex = require('../utils/knex_config');
const OrganizationAdmin = require('../models/organization_admin_model');
async function insert(requester, organizationId, title, description, requirements, salary, salaryFrequency, salaryCurrency, location, tags) {
async function insert(requester, organizationId, title, description, salaryMin, salaryMax, salaryFrequency, salaryCurrency, location, remote, contractType, tags) {
const isAdmin = await OrganizationAdmin.isAdmin(requester, organizationId);
if (isAdmin) {
return await knex.transaction(async (tr) => {
const jobOffer = await tr('JobOffer').insert({
organization_id: organizationId,
title,
description,
requirements,
salary,
salary: salaryMin != null ? knex.raw(`int4range('[${salaryMin}, ${salaryMax}]')`) : null,
salary_frequency: salaryFrequency,
salary_currency: salaryCurrency,
location,
organization_id: organizationId,
salary_currency: salaryCurrency
remote,
contract_type: contractType
})
.returning('*');

View File

@ -13,6 +13,13 @@
const knex = require('../utils/knex_config');
/**
* Given an array of strings, return an array of
* database tags
*
* @param {*} tags
* @returns
*/
async function findByTags(tags) {
if(!tags){
return null;

View File

@ -35,16 +35,30 @@ async function insert(req, res) {
}
const tags = await Tag.findByTags(req.body.tags);
let salaryMin = null;
let salaryMax = null;
if (req.body.salary != null && req.body.salary.length >= 1) {
salaryMin = req.body.salary[0];
if (req.body.salary.length == 2) {
salaryMax = req.body.salary[1];
} else {
salaryMax = salaryMin;
}
}
const insertedJobOffer = await JobOffer.insert(
req.jwt.person_id,
req.params.id, // organization id
req.body.title,
req.body.description,
req.body.requirements,
req.body.salary,
req.body.salary_frequency,
req.body.salary_currency,
salaryMin,
salaryMax,
req.body.salaryFrequency,
req.body.salaryCurrency,
req.body.location,
req.body.remote,
req.body.contractType,
tags);
if (insertedJobOffer) {

View File

@ -32,7 +32,7 @@ async function addOrganizationAdmin(req, res) {
errors: errors.array()
});
}
const success = await organizationAdmin.insert(req.body.person_id, req.params.organizationId, req.jwt.person_id);
const success = await organizationAdmin.insert(req.body.personId, req.params.organizationId, req.jwt.person_id);
if (success) {
return res.status(204).send();
}

View File

@ -24,23 +24,34 @@ const insertValidator = [
check('title').trim().notEmpty().escape().isLength({
max: 2048
}),
check('description').trim().escape().isLength({
check('description').optional().trim().escape().isLength({
max: 4096
}),
check('requirements').trim().escape().isLength({
max: 4096
check('salary').optional().isArray().withMessage('Salary must be an array').custom((value) => {
if (value.length < 1 || value.length > 2) {
throw new Error('Salary array must have between 1 and 2 elements');
}
if (value !== null && !value.every((element) => typeof element === 'number')) {
throw new Error('Salary array elements must be numbers');
}
return true;
}),
check('salary').trim().notEmpty().escape().isCurrency(),
check('salary_frequency').trim().notEmpty().escape().isLength({
check('salaryFrequency').trim().notEmpty().escape().isLength({
max: 64
}),
check('salary_currency').trim().notEmpty().escape().isLength({
check('salaryCurrency').optional().trim().notEmpty().escape().isLength({
max: 64
}),
check('location').trim().escape().isLength({
check('location').optional().trim().escape().isLength({
max: 256
}),
check('tags').custom(tags => {
check('remote').optional().trim().escape().isLength({
max: 256
}),
check('contractType').trim().escape().isLength({
max: 256
}),
check('tags').optional().custom(tags => {
if (!Array.isArray(tags)) {
throw new Error('tags must be an array');
}

View File

@ -17,7 +17,7 @@ const {
} = require("express-validator");
const addOrganizationAdminValidator = [
check('person_id').trim().notEmpty().escape(),
check('personId').trim().notEmpty().escape(),
check('organizationId').trim().notEmpty().escape()
];

View File

@ -23,8 +23,7 @@ const createOrganizationValidator = [
check('location').trim().escape().isLength({
max: 256
}),
check('description').optional().trim().escape(),
check('isHiring').optional().isBoolean()
check('description').optional().trim().escape()
];
const updateOrganizationValidator = [
@ -34,8 +33,7 @@ const updateOrganizationValidator = [
check('location').trim().escape().isLength({
max: 256
}),
check('description').optional().trim().escape(),
check('isHiring').optional().isBoolean()
check('description').optional().trim().escape()
];
const deleteOrGetOrganizationValidator = [

View File

@ -3,7 +3,7 @@ CREATE TYPE SalaryCurrency as ENUM ('EUR', 'USD', 'GBP');
CREATE TYPE RemotePosition as ENUM ('YES', 'NO', 'NOT_SPECIFIED', 'PARTIALLY');
CREATE TYPE ContractType as ENUM ('FULL-TIME','PART-TIME','INTERNSHIP','CONTRACT','FREELANCE','TEMPORARY','SEASONAL','APPRENTICESHIP','VOLUNTEER','ZERO-HOURS','FIXED-TERM','CASUAL','PROBATIONARY','SECONDMENT','JOB-SHARING');
CREATE TYPE ExperienceType as ENUM ('EDUCATION', 'WORK', 'VOLOUNTEER');
CREATE TYPE SalaryFrequency as ENUM ('WEEKLY', 'YEARLY');
CREATE TYPE SalaryFrequency as ENUM ('HOURLY', 'WEEKLY', 'YEARLY');
CREATE TYPE InfoType AS ENUM ('EMAIL', 'PHONE', 'WEBSITE', 'GIT', 'MASTODON', 'YOUTUBE', 'FACEBOOK', 'INSTAGRAM', 'OTHER');
-- Table: Person