Files
productcatalogue_backend/app.js
T
Inamul-hasan-tec 856b1062ae feat(pim): implement SaaS to PIM tenant and user provisioning
- saas_provisioning_inbox with row-lock idempotency (exactly-once)
- SAAS_PIM_MODULE_SECRET exclusively — no generic-secret fallback
- Owner gate requires is_owner===true AND role_code===TENANT_OWNER (both)
- event_id required on /api/internal/events; missing or bad version → 422
- Unsupported event types → 422, never marked PROCESSED
- SSO role loading scoped through Role.tenant_id (cross-tenant safe)
- Migration: single named unique index on event_id (no duplicate inline)
- Soft deprovision preserves all PIM business data
- 23 live receiver tests + 11 unit tests, 0 failures
- Migration up/down verified clean
- PENDING: real SaaS outbox delivery + one-time SSO (ecosystem test)
2026-09-05 16:52:21 +05:30

63 lines
1.9 KiB
JavaScript

import saasInternalRouter from './src/features/organization/org/saasProvisioning.routes.js';
import express from 'express';
import helmet from 'helmet';
import cors from 'cors';
import compression from 'compression';
import cookieParser from 'cookie-parser';
import morgan from 'morgan';
import swaggerUi from 'swagger-ui-express';
import swaggerSpec from './src/shared/config/swagger.config.js';
import { errorMiddleware } from './src/shared/middleware/error.middleware.js';
import registerRoutes from './src/features/index.js';
import { buildContext } from './src/shared/middleware/context.middleware.js';
const app = express();
// Middlewares
app.use(helmet({
crossOriginResourcePolicy: { policy: 'cross-origin' },
}));
app.use(cors({
origin: true,
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],
allowedHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Requested-With', 'x-tenant-id', 'x-impersonated-tenant-id', 'X-Tenant-Id', 'X-Impersonated-Tenant-Id', 'x-api-key', 'X-Api-Key', '*']
}));
app.options('*', cors());
app.use(compression());
app.use(cookieParser());
app.use(express.json({
verify: (req, _res, buffer) => {
req.rawBody = Buffer.from(buffer);
}
}));
app.use(express.urlencoded({ extended: true }));
app.use(buildContext);
if (process.env.NODE_ENV !== 'test') {
app.use(morgan('dev'));
}
// Swagger setup
app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// Base Health Check
app.get('/health', (req, res) => {
res.status(200).json({ status: 'OK', timestamp: new Date() });
});
// Centralized Feature Router Loader
app.use('/uploads', express.static('uploads', {
setHeaders: (res) => {
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
res.setHeader('Access-Control-Allow-Origin', '*');
}
}));
app.use(saasInternalRouter);
registerRoutes(app);
// Global Error Handler
app.use(errorMiddleware);
export default app;