Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions compliance/complianceCollector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Compliance Data Collector
// Collects user activity, access logs, financial transactions, and security events for audit reporting
const AuditEvent = require('../models/auditEvent');
const FinancialTransaction = require('../models/FinancialTransaction');
const User = require('../models/User');

module.exports = {
async collectUserActivity(userId, startDate, endDate) {
// Collect user activity logs
return AuditEvent.find({ userId, timestamp: { $gte: startDate, $lte: endDate } });
},
async collectAccessLogs(startDate, endDate) {
// Collect access logs
return AuditEvent.find({ type: 'access', timestamp: { $gte: startDate, $lte: endDate } });
},
async collectFinancialTransactions(startDate, endDate) {
// Collect financial transactions
return FinancialTransaction.find({ timestamp: { $gte: startDate, $lte: endDate } });
},
async collectSecurityEvents(startDate, endDate) {
// Collect security events
return AuditEvent.find({ type: 'security', timestamp: { $gte: startDate, $lte: endDate } });
}
};
22 changes: 22 additions & 0 deletions compliance/reportGenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Compliance Report Generator
// Generates reports for GDPR, PCI DSS, SOX
const ComplianceReport = require('../models/complianceReport');
const complianceCollector = require('./complianceCollector');

module.exports = {
async generateGDPRReport(userId, startDate, endDate) {
const activity = await complianceCollector.collectUserActivity(userId, startDate, endDate);
// Format GDPR report
return ComplianceReport.create({ type: 'GDPR', userId, data: activity });
},
async generatePCIDSSReport(startDate, endDate) {
const transactions = await complianceCollector.collectFinancialTransactions(startDate, endDate);
// Format PCI DSS report
return ComplianceReport.create({ type: 'PCI DSS', data: transactions });
},
async generateSOXReport(startDate, endDate) {
const accessLogs = await complianceCollector.collectAccessLogs(startDate, endDate);
// Format SOX report
return ComplianceReport.create({ type: 'SOX', data: accessLogs });
}
};
19 changes: 19 additions & 0 deletions compliance/scheduler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Compliance Report Scheduler
// Schedules automated report generation and submission
const reportGenerator = require('./reportGenerator');
const submissionService = require('./submissionService');

module.exports = {
async scheduleGDPRReport(userId, startDate, endDate, submissionMethod, destination) {
const report = await reportGenerator.generateGDPRReport(userId, startDate, endDate);
return submissionService[`submitReportVia${submissionMethod}`](report._id, destination);
},
async schedulePCIDSSReport(startDate, endDate, submissionMethod, destination) {
const report = await reportGenerator.generatePCIDSSReport(startDate, endDate);
return submissionService[`submitReportVia${submissionMethod}`](report._id, destination);
},
async scheduleSOXReport(startDate, endDate, submissionMethod, destination) {
const report = await reportGenerator.generateSOXReport(startDate, endDate);
return submissionService[`submitReportVia${submissionMethod}`](report._id, destination);
}
};
25 changes: 25 additions & 0 deletions compliance/submissionService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Compliance Submission Service
// Submits reports to regulators via API, email, or file export
const ComplianceReport = require('../models/complianceReport');
const nodemailer = require('nodemailer');
const fs = require('fs');

module.exports = {
async submitReportViaAPI(reportId, apiEndpoint) {
const report = await ComplianceReport.findById(reportId);
// Simulate API submission
// ...
return { status: 'submitted', method: 'API', endpoint: apiEndpoint };
},
async submitReportViaEmail(reportId, email) {
const report = await ComplianceReport.findById(reportId);
// Simulate email submission
// ...
return { status: 'submitted', method: 'email', recipient: email };
},
async exportReportToFile(reportId, filePath) {
const report = await ComplianceReport.findById(reportId);
fs.writeFileSync(filePath, JSON.stringify(report));
return { status: 'exported', filePath };
}
};
18 changes: 18 additions & 0 deletions dashboard/compliance.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Compliance Reporting Dashboard</title>
<link rel="stylesheet" href="compliance.css">
</head>
<body>
<h1>Automated Compliance Reporting</h1>
<div id="report-controls">
<button onclick="generateReport('GDPR')">Generate GDPR Report</button>
<button onclick="generateReport('PCI DSS')">Generate PCI DSS Report</button>
<button onclick="generateReport('SOX')">Generate SOX Report</button>
</div>
<div id="report-results"></div>
<script src="compliance.js"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions dashboard/compliance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Compliance Dashboard JS
function generateReport(type) {
let endpoint = '';
if (type === 'GDPR') endpoint = '/api/compliance/gdpr';
if (type === 'PCI DSS') endpoint = '/api/compliance/pci-dss';
if (type === 'SOX') endpoint = '/api/compliance/sox';
fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: 'u1', startDate: '2026-01-01', endDate: '2026-03-01' })
})
.then(r => r.json())
.then(data => {
document.getElementById('report-results').innerHTML = `<pre>${JSON.stringify(data, null, 2)}</pre>`;
});
}
// ...more dashboard features...
12 changes: 12 additions & 0 deletions models/auditEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Audit Event Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const AuditEventSchema = new Schema({
userId: { type: String },
type: { type: String },
details: { type: Schema.Types.Mixed },
timestamp: { type: Date, default: Date.now }
});

module.exports = mongoose.model('AuditEvent', AuditEventSchema);
12 changes: 12 additions & 0 deletions models/complianceReport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Compliance Report Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ComplianceReportSchema = new Schema({
type: { type: String, enum: ['GDPR', 'PCI DSS', 'SOX'], required: true },
userId: { type: String },
data: { type: Schema.Types.Mixed },
createdAt: { type: Date, default: Date.now }
});

module.exports = mongoose.model('ComplianceReport', ComplianceReportSchema);
168 changes: 45 additions & 123 deletions routes/compliance.js
Original file line number Diff line number Diff line change
@@ -1,128 +1,50 @@
// Compliance Reporting API Routes
const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const complianceEngine = require('../services/complianceEngine');
const forensicAuditService = require('../services/forensicAuditService');
const TaxAuditPack = require('../models/TaxAuditPack');
const ComplianceRule = require('../models/ComplianceRule');

/**
* Get Compliance Dashboard Stats
*/
router.get('/dashboard', auth, async (req, res) => {
try {
const auditPacks = await TaxAuditPack.find({ userId: req.user._id }).sort({ createdAt: -1 }).limit(5);
const activeRules = await ComplianceRule.countDocuments({ isActive: true });

res.json({
success: true,
data: {
auditPacks,
activeRulesCount: activeRules,
complianceScore: 94 // Mock score
}
});
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
});

/**
* Generate New Audit Pack
*/
router.post('/generate-audit', auth, async (req, res) => {
try {
const { start, end } = req.body;
const pack = await forensicAuditService.generateAuditPack(req.user._id, {
start: new Date(start),
end: new Date(end)
});
res.json({ success: true, data: pack });
} catch (err) {
res.status(400).json({ success: false, error: err.message });
}
});

/**
* Evaluate Transaction Tax (Preview)
*/
router.post('/evaluate', auth, async (req, res) => {
try {
const evaluation = await complianceEngine.evaluateTransactionTax(req.body);
res.json({ success: true, data: evaluation });
} catch (err) {
res.status(400).json({ success: false, error: err.message });
}
});

/**
* Manage Compliance Rules (Admin)
*/
router.post('/rules', auth, async (req, res) => {
try {
const rule = new ComplianceRule(req.body);
await rule.save();
res.json({ success: true, data: rule });
} catch (err) {
res.status(400).json({ success: false, error: err.message });
}
});

router.get('/rules', auth, async (req, res) => {
try {
const rules = await ComplianceRule.find({}).sort({ jurisdiction: 1 });
res.json({ success: true, data: rules });
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
});

// ============================================
// GLOBAL NEXUS SURFACE ROUTES (Issue #961)
// ============================================

/**
* GET /api/compliance/nexus
* Returns all active tax nexus configurations (Global Nexus Surface visualization).
*/
router.get('/nexus', auth, async (req, res) => {
try {
const TaxNexus = require('../models/TaxNexus');
const nexusList = await TaxNexus.find({ isActive: true })
.populate('policyNodeId', 'name action priority')
.sort({ jurisdictionCode: 1 });
res.json({ success: true, count: nexusList.length, data: nexusList });
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
});

/**
* POST /api/compliance/nexus/detect
* Detect which tax jurisdictions apply to a given transaction context.
*/
router.post('/nexus/detect', auth, async (req, res) => {
try {
const nexusSwitchgear = require('../services/nexusSwitchgear');
const resolution = await nexusSwitchgear.resolve(req.body);
res.json({ success: true, data: resolution });
} catch (err) {
res.status(400).json({ success: false, error: err.message });
}
});

/**
* POST /api/compliance/nexus/sync
* Manually trigger a global tax-rate sync (admin).
*/
router.post('/nexus/sync', auth, async (req, res) => {
try {
const nexusUpdateJob = require('../jobs/nexusUpdateJob');
await nexusUpdateJob.syncGlobalRates();
res.json({ success: true, message: 'Tax nexus rates synced successfully.' });
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
const reportGenerator = require('../compliance/reportGenerator');
const scheduler = require('../compliance/scheduler');
const submissionService = require('../compliance/submissionService');

// Generate GDPR report
router.post('/gdpr', async (req, res) => {
const { userId, startDate, endDate } = req.body;
const report = await reportGenerator.generateGDPRReport(userId, startDate, endDate);
res.json({ success: true, report });
});

// Generate PCI DSS report
router.post('/pci-dss', async (req, res) => {
const { startDate, endDate } = req.body;
const report = await reportGenerator.generatePCIDSSReport(startDate, endDate);
res.json({ success: true, report });
});

// Generate SOX report
router.post('/sox', async (req, res) => {
const { startDate, endDate } = req.body;
const report = await reportGenerator.generateSOXReport(startDate, endDate);
res.json({ success: true, report });
});

// Schedule report generation and submission
router.post('/schedule', async (req, res) => {
const { type, userId, startDate, endDate, submissionMethod, destination } = req.body;
let result;
if (type === 'GDPR') {
result = await scheduler.scheduleGDPRReport(userId, startDate, endDate, submissionMethod, destination);
} else if (type === 'PCI DSS') {
result = await scheduler.schedulePCIDSSReport(startDate, endDate, submissionMethod, destination);
} else if (type === 'SOX') {
result = await scheduler.scheduleSOXReport(startDate, endDate, submissionMethod, destination);
}
res.json({ success: true, result });
});

// Export report to file
router.post('/export', async (req, res) => {
const { reportId, filePath } = req.body;
const result = await submissionService.exportReportToFile(reportId, filePath);
res.json({ success: true, result });
});

module.exports = router;
16 changes: 16 additions & 0 deletions utils/complianceLogger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Compliance Logger Utility
// Logs compliance-relevant events for audit trails
const fs = require('fs');
const path = require('path');
const logFile = path.join(__dirname, '../logs/compliance.log');

function log(message) {
fs.appendFileSync(logFile, message + '\n');
}

function complianceEventLogger(event) {
const entry = `${new Date().toISOString()} ${JSON.stringify(event)}`;
log(entry);
}

module.exports = { log, complianceEventLogger };