183 lines
4.9 KiB
TypeScript
183 lines
4.9 KiB
TypeScript
import { Router, Request, Response, NextFunction } from 'express';
|
|
import { stripPassword } from '../lib/inboxGuard';
|
|
import { AppError } from '../middleware/errorHandler';
|
|
import {
|
|
assignSatelliteSchema,
|
|
campaignListQuerySchema,
|
|
createCampaignSchema,
|
|
updateCampaignSchema,
|
|
} from '../models/campaign.schemas';
|
|
import {
|
|
assignSatellite,
|
|
CampaignError,
|
|
createCampaign,
|
|
deleteCampaign,
|
|
getCampaignById,
|
|
listCampaigns,
|
|
listSatellites,
|
|
pauseCampaign,
|
|
resumeCampaign,
|
|
startCampaign,
|
|
unassignSatellite,
|
|
updateCampaign,
|
|
} from '../services/campaign.service';
|
|
|
|
const router = Router();
|
|
|
|
function handleCampaignError(err: unknown, next: NextFunction) {
|
|
if (err instanceof CampaignError) {
|
|
next(new AppError(err.statusCode, err.message));
|
|
return;
|
|
}
|
|
next(err);
|
|
}
|
|
|
|
function sanitizeCampaign(campaign: Awaited<ReturnType<typeof getCampaignById>>) {
|
|
return {
|
|
...campaign,
|
|
primaryMailbox: stripPassword(campaign.primaryMailbox),
|
|
satellites: campaign.satellites.map((s) => ({
|
|
...s,
|
|
satelliteMailbox: stripPassword(s.satelliteMailbox),
|
|
})),
|
|
};
|
|
}
|
|
|
|
router.post('/', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const data = createCampaignSchema.parse(req.body);
|
|
const campaign = await createCampaign(data);
|
|
res.status(201).json(sanitizeCampaign(campaign));
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.get('/', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const filters = campaignListQuerySchema.parse(req.query);
|
|
const campaigns = await listCampaigns(filters);
|
|
res.json(
|
|
campaigns.map((c) => ({
|
|
...c,
|
|
primaryMailbox: stripPassword(c.primaryMailbox),
|
|
satellites: c.satellites.map((s) => ({
|
|
...s,
|
|
satelliteMailbox: stripPassword(s.satelliteMailbox),
|
|
})),
|
|
})),
|
|
);
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const campaign = await getCampaignById(req.params.id);
|
|
res.json(sanitizeCampaign(campaign));
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.patch('/:id', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const data = updateCampaignSchema.parse(req.body);
|
|
const campaign = await updateCampaign(req.params.id, data);
|
|
res.json({
|
|
...campaign,
|
|
primaryMailbox: stripPassword(campaign.primaryMailbox),
|
|
satellites: campaign.satellites.map((s) => ({
|
|
...s,
|
|
satelliteMailbox: stripPassword(s.satelliteMailbox),
|
|
})),
|
|
});
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
await deleteCampaign(req.params.id);
|
|
res.status(204).send();
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.post('/:id/start', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const campaign = await startCampaign(req.params.id);
|
|
res.json({
|
|
...campaign,
|
|
primaryMailbox: stripPassword(campaign.primaryMailbox),
|
|
satellites: campaign.satellites.map((s) => ({
|
|
...s,
|
|
satelliteMailbox: stripPassword(s.satelliteMailbox),
|
|
})),
|
|
});
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.post('/:id/pause', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const campaign = await pauseCampaign(req.params.id);
|
|
res.json(sanitizeCampaign(campaign));
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.post('/:id/resume', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const campaign = await resumeCampaign(req.params.id);
|
|
res.json(sanitizeCampaign(campaign));
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.get('/:id/satellites', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const satellites = await listSatellites(req.params.id);
|
|
res.json(
|
|
satellites.map((s) => ({
|
|
...s,
|
|
satelliteMailbox: stripPassword(s.satelliteMailbox),
|
|
})),
|
|
);
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.post('/:id/satellites', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { mailboxId, weight } = assignSatelliteSchema.parse(req.body);
|
|
const link = await assignSatellite(req.params.id, mailboxId, weight);
|
|
res.status(201).json({
|
|
...link,
|
|
satelliteMailbox: stripPassword(link.satelliteMailbox),
|
|
});
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
});
|
|
|
|
router.delete(
|
|
'/:id/satellites/:mailboxId',
|
|
async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
await unassignSatellite(req.params.id, req.params.mailboxId);
|
|
res.status(204).send();
|
|
} catch (err) {
|
|
handleCampaignError(err, next);
|
|
}
|
|
},
|
|
);
|
|
|
|
export default router;
|