v2: разделение слоёв — crud/index.js API-слой, user/ и test/ через crud

This commit is contained in:
2026-06-13 06:55:18 +04:00
parent 4b5ccc6a4c
commit 3c061b6c4b
6 changed files with 267 additions and 240 deletions
+11 -18
View File
@@ -1,11 +1,13 @@
// ═══════════════════════════════════════════════════════════════════════════════
// V2 — пользовательский CRUD
// Вход: req.v2_* из resolveContext (email, clientId, allClientIds, profiles, ...)
// V2 — пользовательский CRUD (фронтенд, только Express)
//
// Вход: req.clientId, req.email, req.impersonatedBy из resolveContext.
// Всегда показывает выбор компании (даже если одна).
// НЕ работает с БД напрямую — только через crud API-слой.
// ═══════════════════════════════════════════════════════════════════════════════
const express = require('express');
const q = require('../db/queries');
const crud = require('../crud');
function createUserRouter() {
const router = express.Router();
@@ -18,11 +20,8 @@ function createUserRouter() {
? req.profiles
: [{ client_id: clId, company_name: req.companyName || clId }];
const company = await q.getOrCreateCompany(clId, allCompanies.find(c => c.client_id === clId)?.company_name || clId);
const includeDeleted = req.query.deleted === '1';
const entries = await q.listEntries(company.id, includeDeleted);
const limit = await q.getLimit(company);
const used = entries.filter(e => !e.deleted_at).length;
const { entries, used, limit } = await crud.list(clId, includeDeleted);
// Переключение компании
if (req.query.switchTo && allCompanies.find(c => c.client_id === req.query.switchTo)) {
@@ -30,7 +29,7 @@ function createUserRouter() {
return res.redirect('/v2/app');
}
res.send(renderPage({ entries, company, limit, used, allCompanies, clId, user: req.user, includeDeleted }));
res.send(renderPage({ entries, limit, used, allCompanies, clId, user: req.user, includeDeleted }));
} catch (e) {
res.status(500).send('<h2>Ошибка</h2><pre>' + e.message + '</pre><a href="/v2/app">Назад</a>');
}
@@ -39,9 +38,7 @@ function createUserRouter() {
// ── POST /add ───────────────────────────────────────────────────────────
router.post('/add', async (req, res) => {
try {
const clId = req.clientId;
const company = await q.getOrCreateCompany(clId, clId);
const result = await q.createEntry(company.id, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy);
const result = await crud.add(req.clientId, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy);
const msg = result.wasNormalized ? 'Добавлено (адрес нормализован)' : 'Добавлено';
res.redirect('/v2/app?msg=' + encodeURIComponent(msg));
} catch (e) {
@@ -52,9 +49,7 @@ function createUserRouter() {
// ── POST /edit/:id ──────────────────────────────────────────────────────
router.post('/edit/:id', async (req, res) => {
try {
const clId = req.clientId;
const company = await q.getOrCreateCompany(clId, clId);
const result = await q.updateEntry(parseInt(req.params.id), company.id, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy);
const result = await crud.edit(parseInt(req.params.id), req.clientId, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy);
const msg = result.wasNormalized ? 'Изменено (адрес нормализован)' : 'Изменено';
res.redirect('/v2/app?msg=' + encodeURIComponent(msg));
} catch (e) {
@@ -65,9 +60,7 @@ function createUserRouter() {
// ── POST /delete/:id ────────────────────────────────────────────────────
router.post('/delete/:id', async (req, res) => {
try {
const clId = req.clientId;
const company = await q.getOrCreateCompany(clId, clId);
await q.deleteEntry(parseInt(req.params.id), company.id, req.email, req.impersonatedBy);
await crud.remove(parseInt(req.params.id), req.clientId, req.email, req.impersonatedBy);
res.redirect('/v2/app?msg=Удалено');
} catch (e) {
res.redirect('/v2/app?error=' + encodeURIComponent(e.message));
@@ -79,7 +72,7 @@ function createUserRouter() {
// ── HTML-рендеринг (временный, будет заменён на EJS) ─────────────────────
function renderPage({ entries, company, limit, used, allCompanies, clId, user, includeDeleted }) {
function renderPage({ entries, limit, used, allCompanies, clId, user, includeDeleted }) {
const companyOptions = allCompanies.map(c =>
`<option value="${c.client_id}" ${c.client_id === clId ? 'selected' : ''}>${c.company_name || c.client_id} (${c.client_id})</option>`
).join('');