new features

This commit is contained in:
Matthias Hochmeister
2026-03-23 18:43:30 +01:00
parent 202a658b8d
commit 1b13e4f89e
31 changed files with 1022 additions and 517 deletions

View File

@@ -265,6 +265,41 @@ router.delete(
}
);
// ---------------------------------------------------------------------------
// Reset / Truncate endpoints (no olderThanDays, just ?confirm=true)
// ---------------------------------------------------------------------------
type ResetTarget = 'reset-bestellungen' | 'reset-ausruestung-anfragen' | 'reset-issues' | 'issues-all';
const RESET_TARGETS: Record<ResetTarget, (confirm: boolean) => Promise<{ count: number; deleted: boolean }>> = {
'reset-bestellungen': (c) => cleanupService.resetBestellungenSequence(c),
'reset-ausruestung-anfragen': (c) => cleanupService.resetAusruestungAnfragenSequence(c),
'reset-issues': (c) => cleanupService.resetIssuesSequence(c),
'issues-all': (c) => cleanupService.resetIssuesSequence(c),
};
router.delete(
'/cleanup/:resetTarget(reset-bestellungen|reset-ausruestung-anfragen|reset-issues|issues-all)',
authenticate,
requirePermission('admin:write'),
async (req: Request, res: Response): Promise<void> => {
try {
const target = req.params.resetTarget as ResetTarget;
const handler = RESET_TARGETS[target];
if (!handler) {
res.status(400).json({ success: false, message: `Unknown reset target: ${target}` });
return;
}
const confirm = req.query.confirm === 'true';
const result = await handler(confirm);
res.json({ success: true, data: result });
} catch (error) {
logger.error('Reset failed', { error, target: req.params.resetTarget });
res.status(500).json({ success: false, message: 'Reset failed' });
}
}
);
// ---------------------------------------------------------------------------
// DELETE /api/admin/users/:userId/sync-data — selective sync data deletion
// ---------------------------------------------------------------------------

View File

@@ -0,0 +1,44 @@
import { Router } from 'express';
import ausruestungsanfrageController from '../controllers/ausruestungsanfrage.controller';
import { authenticate } from '../middleware/auth.middleware';
import { requirePermission } from '../middleware/rbac.middleware';
const router = Router();
// ---------------------------------------------------------------------------
// Catalog Items
// ---------------------------------------------------------------------------
router.get('/items', authenticate, requirePermission('ausruestungsanfrage:view'), ausruestungsanfrageController.getItems.bind(ausruestungsanfrageController));
router.get('/items/:id', authenticate, requirePermission('ausruestungsanfrage:view'), ausruestungsanfrageController.getItemById.bind(ausruestungsanfrageController));
router.post('/items', authenticate, requirePermission('ausruestungsanfrage:manage_catalog'), ausruestungsanfrageController.createItem.bind(ausruestungsanfrageController));
router.patch('/items/:id', authenticate, requirePermission('ausruestungsanfrage:manage_catalog'), ausruestungsanfrageController.updateItem.bind(ausruestungsanfrageController));
router.delete('/items/:id', authenticate, requirePermission('ausruestungsanfrage:manage_catalog'), ausruestungsanfrageController.deleteItem.bind(ausruestungsanfrageController));
router.get('/categories', authenticate, requirePermission('ausruestungsanfrage:view'), ausruestungsanfrageController.getCategories.bind(ausruestungsanfrageController));
// ---------------------------------------------------------------------------
// Overview
// ---------------------------------------------------------------------------
router.get('/overview', authenticate, requirePermission('ausruestungsanfrage:view_overview'), ausruestungsanfrageController.getOverview.bind(ausruestungsanfrageController));
// ---------------------------------------------------------------------------
// Requests
// ---------------------------------------------------------------------------
router.get('/requests', authenticate, requirePermission('ausruestungsanfrage:approve_requests'), ausruestungsanfrageController.getRequests.bind(ausruestungsanfrageController));
router.get('/requests/my', authenticate, ausruestungsanfrageController.getMyRequests.bind(ausruestungsanfrageController));
router.get('/requests/:id', authenticate, ausruestungsanfrageController.getRequestById.bind(ausruestungsanfrageController));
router.post('/requests', authenticate, requirePermission('ausruestungsanfrage:create_request'), ausruestungsanfrageController.createRequest.bind(ausruestungsanfrageController));
router.patch('/requests/:id/status', authenticate, requirePermission('ausruestungsanfrage:approve_requests'), ausruestungsanfrageController.updateRequestStatus.bind(ausruestungsanfrageController));
router.delete('/requests/:id', authenticate, requirePermission('ausruestungsanfrage:approve_requests'), ausruestungsanfrageController.deleteRequest.bind(ausruestungsanfrageController));
// ---------------------------------------------------------------------------
// Linking requests to orders
// ---------------------------------------------------------------------------
router.post('/requests/:id/link', authenticate, requirePermission('ausruestungsanfrage:link_orders'), ausruestungsanfrageController.linkToOrder.bind(ausruestungsanfrageController));
router.delete('/requests/:id/link/:bestellungId', authenticate, requirePermission('ausruestungsanfrage:link_orders'), ausruestungsanfrageController.unlinkFromOrder.bind(ausruestungsanfrageController));
export default router;

View File

@@ -19,5 +19,6 @@ router.put('/admin/group/:groupName', authenticate, requirePermission('admin:wri
router.delete('/admin/group/:groupName', authenticate, requirePermission('admin:write'), permissionController.deleteGroup.bind(permissionController));
router.put('/admin/bulk', authenticate, requirePermission('admin:write'), permissionController.setBulkPermissions.bind(permissionController));
router.put('/admin/maintenance/:featureGroupId', authenticate, requirePermission('admin:write'), permissionController.setMaintenanceFlag.bind(permissionController));
router.get('/debug/:userId', authenticate, requirePermission('admin:write'), permissionController.debugUser.bind(permissionController));
export default router;

View File

@@ -1,44 +0,0 @@
import { Router } from 'express';
import shopController from '../controllers/shop.controller';
import { authenticate } from '../middleware/auth.middleware';
import { requirePermission } from '../middleware/rbac.middleware';
const router = Router();
// ---------------------------------------------------------------------------
// Catalog Items
// ---------------------------------------------------------------------------
router.get('/items', authenticate, requirePermission('shop:view'), shopController.getItems.bind(shopController));
router.get('/items/:id', authenticate, requirePermission('shop:view'), shopController.getItemById.bind(shopController));
router.post('/items', authenticate, requirePermission('shop:manage_catalog'), shopController.createItem.bind(shopController));
router.patch('/items/:id', authenticate, requirePermission('shop:manage_catalog'), shopController.updateItem.bind(shopController));
router.delete('/items/:id', authenticate, requirePermission('shop:manage_catalog'), shopController.deleteItem.bind(shopController));
router.get('/categories', authenticate, requirePermission('shop:view'), shopController.getCategories.bind(shopController));
// ---------------------------------------------------------------------------
// Overview
// ---------------------------------------------------------------------------
router.get('/overview', authenticate, requirePermission('shop:view_overview'), shopController.getOverview.bind(shopController));
// ---------------------------------------------------------------------------
// Requests
// ---------------------------------------------------------------------------
router.get('/requests', authenticate, requirePermission('shop:approve_requests'), shopController.getRequests.bind(shopController));
router.get('/requests/my', authenticate, shopController.getMyRequests.bind(shopController));
router.get('/requests/:id', authenticate, shopController.getRequestById.bind(shopController));
router.post('/requests', authenticate, requirePermission('shop:create_request'), shopController.createRequest.bind(shopController));
router.patch('/requests/:id/status', authenticate, requirePermission('shop:approve_requests'), shopController.updateRequestStatus.bind(shopController));
router.delete('/requests/:id', authenticate, requirePermission('shop:approve_requests'), shopController.deleteRequest.bind(shopController));
// ---------------------------------------------------------------------------
// Linking requests to orders
// ---------------------------------------------------------------------------
router.post('/requests/:id/link', authenticate, requirePermission('shop:link_orders'), shopController.linkToOrder.bind(shopController));
router.delete('/requests/:id/link/:bestellungId', authenticate, requirePermission('shop:link_orders'), shopController.unlinkFromOrder.bind(shopController));
export default router;