Files
makemd/server/src/api/routes/finance.ts

149 lines
6.8 KiB
TypeScript
Raw Normal View History

import { Router } from 'express';
import { requirePermission } from '../../core/guards/rbac.guard';
import { requireTraceContext } from '../../core/guards/trace-context.guard';
import { CommodityHedgingService } from '../../services/core/CommodityHedgingService';
import { PoolSourcingService } from '../../services/integration/PoolSourcingService';
import { SovereignCreditPoolService } from '../../services/sovereignty/SovereignCreditPoolService';
import { SovereigntySettlementService } from '../../services/sovereignty/SovereigntySettlementService';
import { PricingController } from '../controllers/PricingController';
import { SettlementController } from '../controllers/SettlementController';
import { ReconciliationController } from '../controllers/ReconciliationController';
const router = Router();
/**
* [BIZ_ARB_01]
*/
router.post('/calculate', requireTraceContext, PricingController.calculate);
/**
* [BIZ_FIN_12]
*/
router.post('/fx/lock-rate', requireTraceContext, requirePermission('finance:write'), PricingController.lockRate);
router.get('/fx/gain-loss', requireTraceContext, requirePermission('finance:read'), PricingController.getFXGainLoss);
/**
* [BIZ_FIN_08] (Settlement)
*/
router.get('/settlement/summary', requireTraceContext, requirePermission('finance:read'), SettlementController.getSummary);
router.get('/settlement/:orderId', requireTraceContext, requirePermission('finance:read'), SettlementController.settleOrder);
/**
* [BIZ_FIN_01]
*/
router.get('/reconcile/:orderId', requireTraceContext, PricingController.reconcile);
/**
* [BIZ_FIN_01]
*/
router.get('/playback', requireTraceContext, PricingController.getPlayback);
/**
* [BIZ_SOV_03] (Sovereignty Settlement)
*/
router.post('/sovereignty/settle', requireTraceContext, requirePermission('finance:write'), async (req, res) => {
try {
const { tenantId, traceId } = (req as any).traceContext;
const { amount, currency } = req.body;
const hash = await SovereigntySettlementService.initiateSettlement(tenantId, amount, currency, traceId);
res.json({ success: true, data: { settlementHash: hash } });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
router.get('/sovereignty/history', requireTraceContext, requirePermission('finance:read'), async (req, res) => {
try {
const { tenantId } = (req as any).traceContext;
const history = await SovereigntySettlementService.getSettlementHistory(tenantId);
res.json({ success: true, data: history });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
/**
* [BIZ_FIN_20] (Sovereign Credit Pool)
*/
router.post('/sovereignty/credit/init', requireTraceContext, requirePermission('finance:admin'), async (req, res) => {
try {
const { tenantId, traceId } = (req as any).traceContext;
await SovereignCreditPoolService.initializeCreditPool(tenantId, traceId);
res.json({ success: true, message: 'Sovereign credit pool initialized' });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
router.post('/sovereignty/credit/refresh', requireTraceContext, requirePermission('finance:admin'), async (req, res) => {
try {
const { tenantId, traceId } = (req as any).traceContext;
await SovereignCreditPoolService.refreshCreditLimit(tenantId, traceId);
res.json({ success: true, message: 'Sovereign credit limit refreshed based on latest reputation' });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
/**
* [BIZ_FIN_14] (Commodity Hedging)
*/
router.post('/hedging/create', requireTraceContext, requirePermission('finance:write'), async (req, res) => {
try {
const { tenantId, traceId } = (req as any).traceContext;
const { commodityType, quantity, strikePrice, expiryDate } = req.body;
const id = await CommodityHedgingService.createHedgingPosition(tenantId, commodityType, quantity, strikePrice, new Date(expiryDate), traceId);
res.json({ success: true, data: { positionId: id } });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
router.get('/hedging/active', requireTraceContext, requirePermission('finance:read'), async (req, res) => {
try {
const { tenantId } = (req as any).traceContext;
const positions = await CommodityHedgingService.getActivePositions(tenantId);
res.json({ success: true, data: positions });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
/**
* [BIZ_FIN_18] (Pool Sourcing)
*/
router.post('/pool/join', requireTraceContext, requirePermission('finance:write'), async (req, res) => {
try {
const { tenantId, traceId } = (req as any).traceContext;
const { commodityType, quantity } = req.body;
await PoolSourcingService.joinPool(tenantId, commodityType, quantity, traceId);
res.json({ success: true, message: 'Joined procurement pool successfully' });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
router.get('/pool/active', requireTraceContext, requirePermission('finance:read'), async (req, res) => {
try {
const pools = await PoolSourcingService.getActivePools();
res.json({ success: true, data: pools });
} catch (err: any) {
res.status(500).json({ success: false, error: err.message });
}
});
/**
* [BE-F101]
*/
router.post('/reconciliation', requireTraceContext, requirePermission('finance:write'), ReconciliationController.createReconciliation);
router.get('/reconciliation', requireTraceContext, requirePermission('finance:read'), ReconciliationController.getReconciliations);
router.get('/reconciliation/:id', requireTraceContext, requirePermission('finance:read'), ReconciliationController.getReconciliationById);
router.post('/reconciliation/:id/exception', requireTraceContext, requirePermission('finance:write'), ReconciliationController.handleException);
router.post('/reconciliation/batch', requireTraceContext, requirePermission('finance:write'), ReconciliationController.batchReconciliation);
router.get('/reconciliation/summary', requireTraceContext, requirePermission('finance:read'), ReconciliationController.getReconciliationSummary);
router.post('/reconciliation/auto', requireTraceContext, requirePermission('finance:write'), ReconciliationController.autoReconciliation);
router.get('/reconciliation/export', requireTraceContext, requirePermission('finance:read'), ReconciliationController.exportReconciliationReport);
router.post('/reconciliation/init', requireTraceContext, requirePermission('finance:admin'), ReconciliationController.initReconciliationTable);
export default router;