feat: comprehensive project structure improvements and Cloud for Sovereignty landing zone

- Add Cloud for Sovereignty landing zone architecture and deployment
- Implement complete legal document management system
- Reorganize documentation with improved navigation
- Add infrastructure improvements (Dockerfiles, K8s, monitoring)
- Add operational improvements (graceful shutdown, rate limiting, caching)
- Create comprehensive project structure documentation
- Add Azure deployment automation scripts
- Improve repository navigation and organization
This commit is contained in:
defiQUG
2025-11-13 09:32:55 -08:00
parent 92cc41d26d
commit 6a8582e54d
202 changed files with 22699 additions and 981 deletions

View File

@@ -0,0 +1,105 @@
/**
* Graceful shutdown utilities
* Handles signal processing, connection draining, and in-flight request completion
*/
import { createLogger } from './logger';
const logger = createLogger('graceful-shutdown');
export interface GracefulShutdownOptions {
timeout?: number; // Maximum time to wait for shutdown (default: 30s)
onShutdown?: () => Promise<void>; // Custom shutdown hook
}
/**
* Setup graceful shutdown for a Fastify server
*/
export function setupGracefulShutdown(
server: { close: () => Promise<void> },
options: GracefulShutdownOptions = {}
): void {
const { timeout = 30000, onShutdown } = options;
const shutdown = async (signal: string): Promise<void> => {
logger.info({ signal }, 'Received shutdown signal, starting graceful shutdown...');
// Stop accepting new connections
server.close = (() => {
const originalClose = server.close.bind(server);
return async () => {
logger.info('Server closed, no longer accepting new connections');
return originalClose();
};
})();
try {
// Wait for in-flight requests with timeout
const shutdownPromise = Promise.all([
// Wait for server to close
server.close().catch((err) => {
logger.warn({ err }, 'Error closing server');
}),
// Run custom shutdown hook if provided
onShutdown?.().catch((err) => {
logger.warn({ err }, 'Error in shutdown hook');
}),
]);
// Apply timeout
await Promise.race([
shutdownPromise,
new Promise<void>((resolve) => {
setTimeout(() => {
logger.warn('Shutdown timeout reached, forcing exit');
resolve();
}, timeout);
}),
]);
logger.info('Graceful shutdown complete');
process.exit(0);
} catch (err) {
logger.error({ err }, 'Error during graceful shutdown');
process.exit(1);
}
};
// Handle termination signals
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
// Handle uncaught exceptions
process.on('uncaughtException', (err) => {
logger.error({ err }, 'Uncaught exception, shutting down');
shutdown('uncaughtException').catch(() => {
process.exit(1);
});
});
// Handle unhandled promise rejections
process.on('unhandledRejection', (reason) => {
logger.error({ reason }, 'Unhandled rejection, shutting down');
shutdown('unhandledRejection').catch(() => {
process.exit(1);
});
});
}
/**
* Create a connection drainer for database connections
*/
export function createConnectionDrainer(
pool: { end: () => Promise<void> }
): () => Promise<void> {
return async () => {
logger.info('Draining database connections...');
try {
await pool.end();
logger.info('Database connections drained');
} catch (err) {
logger.warn({ err }, 'Error draining database connections');
}
};
}

View File

@@ -10,6 +10,8 @@ export * from './middleware';
export * from './validation';
export * from './auth';
export * from './rate-limit-credential';
export * from './rate-limiting';
export * from './graceful-shutdown';
export * from './rate-limit-entra';
export * from './authorization';
export * from './compliance';

View File

@@ -0,0 +1,173 @@
/**
* Global rate limiting implementation
* Supports per-user, per-IP, and global rate limits
*/
import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { createLogger } from './logger';
const logger = createLogger('rate-limiting');
export interface RateLimitOptions {
maxRequests?: number;
windowMs?: number;
keyGenerator?: (request: FastifyRequest) => string;
skipOnError?: boolean;
}
interface RateLimitStore {
[key: string]: {
count: number;
resetTime: number;
};
}
const store: RateLimitStore = {};
/**
* Create a rate limit key from request
*/
function generateKey(request: FastifyRequest, options: RateLimitOptions): string {
if (options.keyGenerator) {
return options.keyGenerator(request);
}
// Default: use IP address
const ip = request.ip || request.socket.remoteAddress || 'unknown';
return `rate-limit:${ip}`;
}
/**
* Check if request should be rate limited
*/
function checkRateLimit(
key: string,
maxRequests: number,
windowMs: number
): { allowed: boolean; remaining: number; resetTime: number } {
const now = Date.now();
const entry = store[key];
// Clean expired entries periodically
if (Math.random() < 0.01) {
// 1% chance to clean up
Object.keys(store).forEach((k) => {
if (store[k]!.resetTime < now) {
delete store[k];
}
});
}
if (!entry || entry.resetTime < now) {
// Create new window
store[key] = {
count: 1,
resetTime: now + windowMs,
};
return {
allowed: true,
remaining: maxRequests - 1,
resetTime: now + windowMs,
};
}
if (entry.count >= maxRequests) {
return {
allowed: false,
remaining: 0,
resetTime: entry.resetTime,
};
}
entry.count++;
return {
allowed: true,
remaining: maxRequests - entry.count,
resetTime: entry.resetTime,
};
}
/**
* Rate limiting middleware
*/
export async function rateLimit(
request: FastifyRequest,
reply: FastifyReply,
options: RateLimitOptions = {}
): Promise<void> {
const {
maxRequests = 100,
windowMs = 60000, // 1 minute default
skipOnError = true,
} = options;
try {
const key = generateKey(request, options);
const result = checkRateLimit(key, maxRequests, windowMs);
// Set rate limit headers
reply.header('X-RateLimit-Limit', maxRequests.toString());
reply.header('X-RateLimit-Remaining', result.remaining.toString());
reply.header('X-RateLimit-Reset', new Date(result.resetTime).toISOString());
if (!result.allowed) {
logger.warn({ key, ip: request.ip }, 'Rate limit exceeded');
reply.code(429).send({
error: 'Too Many Requests',
message: 'Rate limit exceeded. Please try again later.',
retryAfter: Math.ceil((result.resetTime - Date.now()) / 1000),
});
return;
}
} catch (err) {
if (skipOnError) {
logger.warn({ err }, 'Rate limit check failed, allowing request');
return;
}
throw err;
}
}
/**
* Register global rate limiting plugin
*/
export async function registerGlobalRateLimit(
server: FastifyInstance,
options: RateLimitOptions = {}
): Promise<void> {
server.addHook('onRequest', async (request, reply) => {
await rateLimit(request, reply, options);
});
}
/**
* Per-user rate limiting
*/
export function createUserRateLimit(maxRequests: number, windowMs: number) {
return async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {
const userId = (request as any).user?.id || (request as any).user?.sub;
if (!userId) {
return; // No user, skip rate limiting
}
await rateLimit(request, reply, {
maxRequests,
windowMs,
keyGenerator: () => `rate-limit:user:${userId}`,
});
};
}
/**
* Per-IP rate limiting
*/
export function createIPRateLimit(maxRequests: number, windowMs: number) {
return async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {
await rateLimit(request, reply, {
maxRequests,
windowMs,
keyGenerator: (req) => `rate-limit:ip:${req.ip || req.socket.remoteAddress || 'unknown'}`,
});
};
}