Compose-ready workspace: packages/zappier (rate card, portal, Stripe), packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier (CLI app), vendor/zapier-platform, and research/zapier vendor corpus. Gate 0 structure checks pass. Product code and research are not yet wired.
46 lines
1.1 KiB
JavaScript
46 lines
1.1 KiB
JavaScript
/**
|
|
* @module routes/tenantRoutes
|
|
*/
|
|
|
|
import { Router } from 'express';
|
|
import { asyncHandler, AppError } from '../errors.js';
|
|
import {
|
|
selfServeSignup,
|
|
provisionTenant,
|
|
listProvisionedTenants,
|
|
} from '../services/tenantService.js';
|
|
import { config } from '../config.js';
|
|
|
|
export const publicTenantRoutes = Router();
|
|
export const adminTenantRoutes = Router();
|
|
|
|
publicTenantRoutes.post(
|
|
'/signup',
|
|
asyncHandler(async (req, res) => {
|
|
const result = await selfServeSignup(req.body ?? {});
|
|
res.status(201).json(result);
|
|
}),
|
|
);
|
|
|
|
adminTenantRoutes.use((req, _res, next) => {
|
|
const secret = req.headers['x-admin-secret'];
|
|
if (secret !== config.adminSecret) {
|
|
return next(new AppError('Invalid admin secret', { status: 403, code: 'FORBIDDEN' }));
|
|
}
|
|
next();
|
|
});
|
|
|
|
adminTenantRoutes.post(
|
|
'/tenants',
|
|
asyncHandler(async (req, res) => {
|
|
const result = await provisionTenant(req.body ?? {});
|
|
res.status(201).json(result);
|
|
}),
|
|
);
|
|
|
|
adminTenantRoutes.get(
|
|
'/tenants',
|
|
asyncHandler(async (_req, res) => {
|
|
res.json({ tenants: listProvisionedTenants() });
|
|
}),
|
|
);
|