FRE-4533: Merge apps/{api,web,mobile} and shared-db into ShieldAI repo
Merge FrenoCorp apps into ShieldAI packages/: - packages/api: merged routes (notifications), middleware (auth, rate-limit, error, logging), config, services (darkwatch, spamshield, voiceprint), tests - packages/web: new SolidJS web app stub - packages/mobile: new SolidJS mobile app stub - packages/shared-db: new Prisma DB package (separate from existing packages/db) - pnpm-workspace.yaml: restored (apps/* removed, already covered by packages/*) Next: reconcile packages/shared-db with packages/db, and fix server.ts correlationRoutes import
This commit is contained in:
106
packages/api/src/index.ts
Normal file
106
packages/api/src/index.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import Fastify from 'fastify';
|
||||
import cors from '@fastify/cors';
|
||||
import helmet from '@fastify/helmet';
|
||||
import { authMiddleware } from './middleware/auth.middleware';
|
||||
import { rateLimitMiddleware } from './middleware/rate-limit.middleware';
|
||||
import { spamRateLimitMiddleware } from './middleware/spam-rate-limit.middleware';
|
||||
import { errorHandlingMiddleware } from './middleware/error-handling.middleware';
|
||||
import { loggingMiddleware } from './middleware/logging.middleware';
|
||||
import { apiEnv, loggingConfig } from './config/api.config';
|
||||
import { routes } from './routes';
|
||||
|
||||
const fastify = Fastify({
|
||||
logger: loggingConfig,
|
||||
ignoreTrailingSlash: true,
|
||||
maxParamLength: 500,
|
||||
});
|
||||
|
||||
// Register plugins
|
||||
async function registerPlugins() {
|
||||
// CORS configuration
|
||||
await fastify.register(cors, {
|
||||
origin: apiEnv.CORS_ORIGIN,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Security headers
|
||||
await fastify.register(helmet, {
|
||||
global: true,
|
||||
contentSecurityPolicy: false,
|
||||
});
|
||||
|
||||
// Rate limiting
|
||||
await fastify.register(rateLimitMiddleware);
|
||||
|
||||
// SpamShield rate limiting (Redis-backed)
|
||||
await fastify.register(spamRateLimitMiddleware);
|
||||
|
||||
// Authentication
|
||||
await fastify.register(authMiddleware);
|
||||
|
||||
// Logging
|
||||
await fastify.register(loggingMiddleware);
|
||||
|
||||
// Error handling
|
||||
await fastify.register(errorHandlingMiddleware);
|
||||
}
|
||||
|
||||
// Register routes
|
||||
async function registerRoutes() {
|
||||
await fastify.register(routes, { prefix: '/api/v1' });
|
||||
}
|
||||
|
||||
// Health check endpoint
|
||||
fastify.get('/health', async () => {
|
||||
return { status: 'ok', timestamp: new Date().toISOString() };
|
||||
});
|
||||
|
||||
// Root endpoint
|
||||
fastify.get('/', async () => {
|
||||
return {
|
||||
name: 'FrenoCorp API Gateway',
|
||||
version: '1.0.0',
|
||||
environment: apiEnv.NODE_ENV,
|
||||
};
|
||||
});
|
||||
|
||||
// Start server
|
||||
async function start() {
|
||||
await registerPlugins();
|
||||
await registerRoutes();
|
||||
|
||||
try {
|
||||
await fastify.listen({
|
||||
port: apiEnv.PORT,
|
||||
host: apiEnv.HOST,
|
||||
});
|
||||
|
||||
console.log(`🚀 API Gateway running at http://${apiEnv.HOST}:${apiEnv.PORT}`);
|
||||
console.log(`📝 Environment: ${apiEnv.NODE_ENV}`);
|
||||
console.log(`📊 Rate limit window: ${apiEnv.API_RATE_LIMIT_WINDOW}ms`);
|
||||
console.log(`📈 Max requests: ${apiEnv.API_RATE_LIMIT_MAX_REQUESTS}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Graceful shutdown
|
||||
const gracefulShutdown = async (signal: string) => {
|
||||
console.log(`\n🛑 ${signal} received, shutting down gracefully...`);
|
||||
await fastify.close();
|
||||
console.log('✅ Server closed');
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
|
||||
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
||||
|
||||
// Export for testing
|
||||
export { fastify };
|
||||
|
||||
// Start if running directly
|
||||
if (process.argv[1] === new URL(import.meta.url).pathname) {
|
||||
start();
|
||||
}
|
||||
Reference in New Issue
Block a user