u
This commit is contained in:
130
src/api/routes/company.js
Normal file
130
src/api/routes/company.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import * as db from '../../db/company.js';
|
||||
import * as googleAuth from '../../db/googleAuth.js';
|
||||
import { clearCachedUser } from '../middleware/auth.js';
|
||||
|
||||
function userPayload(req, authRow) {
|
||||
return {
|
||||
id: authRow.id,
|
||||
email: authRow.email,
|
||||
selectedCompanyId: authRow.selectedCompanyId,
|
||||
...(req.user.picture && { picture: req.user.picture }),
|
||||
};
|
||||
}
|
||||
|
||||
function parseCompanyBody(body) {
|
||||
const { iso639, name, taxrate, reducedtaxrate } = body ?? {};
|
||||
if (!iso639 || !name || taxrate == null || reducedtaxrate == null) {
|
||||
return { error: 'iso639, name, taxrate, and reducedtaxrate are required' };
|
||||
}
|
||||
return { iso639, name, taxrate, reducedtaxrate };
|
||||
}
|
||||
|
||||
function parseCompanyId(id) {
|
||||
const companyId = Number(id);
|
||||
if (!Number.isInteger(companyId) || companyId <= 0) {
|
||||
return { error: 'Invalid company id' };
|
||||
}
|
||||
return { companyId };
|
||||
}
|
||||
|
||||
function companyErrorStatus(error) {
|
||||
if (error.message === 'Company not found') return 404;
|
||||
if (error.message === 'Company name not available') return 409;
|
||||
return 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers company CRUD routes (requires auth middleware).
|
||||
* @param {import('express').Application} app - Express app
|
||||
* @param {string} [basePath=''] - Optional URL prefix for all routes in this module
|
||||
*/
|
||||
export function register(app, basePath = '') {
|
||||
/**
|
||||
* @route GET /company
|
||||
* @description Lists companies for the authenticated user.
|
||||
* @returns {Object} 200 - `{ companies }`
|
||||
*/
|
||||
app.get(`${basePath}/company`, async (req, res) => {
|
||||
try {
|
||||
const companies = await db.listCompanies(req.user.id);
|
||||
res.status(200).json({ companies });
|
||||
} catch (error) {
|
||||
console.error('List companies failed:', error);
|
||||
res.status(500).json({ error: 'Failed to list companies' });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @route POST /company
|
||||
* @description Creates a company.
|
||||
* @body {string} iso639
|
||||
* @body {string} name
|
||||
* @body {number} taxrate
|
||||
* @body {number} reducedtaxrate
|
||||
* @returns {Object} 201 - `{ company }`
|
||||
*/
|
||||
app.post(`${basePath}/company`, async (req, res) => {
|
||||
const body = parseCompanyBody(req.body);
|
||||
if (body.error) {
|
||||
return res.status(400).json({ error: body.error });
|
||||
}
|
||||
|
||||
try {
|
||||
const company = await db.createCompany(req.user.id, body);
|
||||
await googleAuth.setSelectedCompany(req.user.id, company.id);
|
||||
clearCachedUser(req.user.email);
|
||||
const authRow = await googleAuth.getAllowedEmail(req.user.email);
|
||||
res.status(201).json({ company, user: userPayload(req, authRow) });
|
||||
} catch (error) {
|
||||
const status = companyErrorStatus(error);
|
||||
if (status === 500) console.error('Create company failed:', error);
|
||||
res.status(status).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @route PUT /company/:id
|
||||
* @description Updates a company.
|
||||
* @returns {Object} 200 - `{ company }`
|
||||
*/
|
||||
app.put(`${basePath}/company/:id`, async (req, res) => {
|
||||
const parsedId = parseCompanyId(req.params.id);
|
||||
if (parsedId.error) {
|
||||
return res.status(400).json({ error: parsedId.error });
|
||||
}
|
||||
|
||||
const body = parseCompanyBody(req.body);
|
||||
if (body.error) {
|
||||
return res.status(400).json({ error: body.error });
|
||||
}
|
||||
|
||||
try {
|
||||
const company = await db.updateCompany(parsedId.companyId, body);
|
||||
res.status(200).json({ company });
|
||||
} catch (error) {
|
||||
const status = companyErrorStatus(error);
|
||||
if (status === 500) console.error('Update company failed:', error);
|
||||
res.status(status).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @route DELETE /company/:id
|
||||
* @description Deletes a company.
|
||||
* @returns {Object} 204 - No content
|
||||
*/
|
||||
app.delete(`${basePath}/company/:id`, async (req, res) => {
|
||||
const parsedId = parseCompanyId(req.params.id);
|
||||
if (parsedId.error) {
|
||||
return res.status(400).json({ error: parsedId.error });
|
||||
}
|
||||
|
||||
try {
|
||||
await db.deleteCompany(parsedId.companyId);
|
||||
res.sendStatus(204);
|
||||
} catch (error) {
|
||||
console.error('Delete company failed:', error);
|
||||
res.status(500).json({ error: 'Failed to delete company' });
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user