feat: add isolated read-only gray deployment

This commit is contained in:
john
2026-07-21 17:07:13 +08:00
parent 280cae028b
commit 816af97bb0
5 changed files with 259 additions and 0 deletions
+12
View File
@@ -113,6 +113,8 @@ export function createAdminApp(services) {
} = services;
const app = express();
app.set('trust proxy', 1);
const readOnlyMode = services.readOnlyMode
?? /^(1|true|yes|on)$/i.test(String(process.env.ADM_READ_ONLY_MODE ?? ''));
const isSecureRequest = (req) =>
req.secure || req.get('x-forwarded-proto')?.split(',')[0]?.trim() === 'https';
@@ -150,6 +152,13 @@ export function createAdminApp(services) {
);
}
const requireWritableMode = (req, res, next) => {
if (readOnlyMode && !['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
return res.status(423).json({ message: '当前为灰度只读模式,禁止修改生产数据' });
}
next();
};
app.get('/health', (_req, res) => {
res.json({ ok: true, service: 'memind_adm' });
});
@@ -206,6 +215,8 @@ export function createAdminApp(services) {
next();
}));
adminApi.use(requireWritableMode);
const requireAdmin = (req, res, next) => {
if (!req.currentUser || req.currentUser.role !== 'admin') {
res.status(403).json({ message: '需要管理员权限' });
@@ -1123,6 +1134,7 @@ export function createAdminApp(services) {
req.currentUser = me;
next();
}));
opsApi.use(requireWritableMode);
opsApi.use(resolveSessionUser);
opsApi.use('/ops/v1', services.createOpsApi({ jsonBody, plazaOps: services.plazaOps }));
app.use('/api', opsApi);