Add API endpoint for patching a project

This commit is contained in:
D. Berge
2023-08-30 13:47:02 +02:00
parent b4f23822c4
commit 6721b1b96b
6 changed files with 108 additions and 3 deletions

View File

@@ -98,6 +98,7 @@ app.map({
},
'/project/:project/configuration': {
get: [ mw.auth.access.write, mw.project.configuration.get ], // Get project configuration
patch: [ mw.auth.access.write, mw.project.configuration.patch ], // Modify project configuration
},
/*

View File

@@ -3,6 +3,6 @@ module.exports = {
get: require('./get'),
// post: require('./post'),
// put: require('./put'),
// patch: require('./patch'),
patch: require('./patch'),
// delete: require('./delete'),
};

View File

@@ -0,0 +1,16 @@
const { project } = require('../../../../lib/db');
module.exports = async function (req, res, next) {
try {
// TODO
// Implement If-Match header requirements
res.send(await project.configuration.patch(req.params.project, req.body));
next();
} catch (err) {
next(err);
}
};

View File

@@ -3,6 +3,6 @@ module.exports = {
get: require('./get'),
// post: require('./post'),
// put: require('./put'),
// patch: require('./patch'),
patch: require('./patch'),
// delete: require('./delete'),
};

View File

@@ -0,0 +1,54 @@
const { setSurvey } = require('../../connection');
const { deepMerge } = require('../../../utils');
const { modify } = require('../create');
async function patch (projectId, payload, opts = {}) {
let client;
try {
client = await setSurvey(); // Use public schema
const text = `
SELECT meta
FROM projects
WHERE pid = $1;
`;
const res = await client.query(text, [projectId]);
const source = res.rows[0].meta;
if (!source) {
throw { status: 404, message: "Not found" };
}
if (("id" in payload) && (projectId != payload.id)) {
throw {
status: 422,
message: "Project ID cannot be changed in this Dougal version"
}
}
if (("name" in payload) && (source.name != payload.name)) {
throw {
status: 422,
message: "Project name cannot be changed in this Dougal version"
}
}
const dest = deepMerge(source, payload);
await modify(projectId, dest);
return dest;
} catch (err) {
if (err.code == "42P01") {
throw { status: 404, message: "Not found" };
} else {
throw err;
}
} finally {
client.release();
}
}
module.exports = patch;

View File

@@ -128,6 +128,22 @@ async function addProjectToList (projectDefinition) {
}
}
async function updateProject (projectId, projectDefinition) {
const sql = `
UPDATE public.projects
SET
name = $2,
meta = $3
WHERE pid = $1;
`;
const values = [ projectId, projectDefinition.name, projectDefinition ];
try {
return await pool.query(sql, values);
} catch (err) {
throw err;
}
}
async function create (projectDefinition) {
const syntaxOk = checkSyntax(projectDefinition);
@@ -154,8 +170,26 @@ async function create (projectDefinition) {
}
async function modify (projectId, projectDefinition) {
const syntaxOk = checkSyntax(projectDefinition);
if (syntaxOk !== true) {
throw { status: 400, message: syntaxOk };
} else {
try {
const res = await updateProject(projectId, projectDefinition);
} catch (err) {
DEBUG(err);
throw { status: 500, message: err.message ?? "Failed to update project definition", detail: err.detail }
}
}
}
module.exports = {
checkSyntax,
create
create,
modify
};