v2: подробные комментарии во всех модулях — что, зачем, контракты
This commit is contained in:
+34
-12
@@ -1,21 +1,41 @@
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// V2 — пользовательский CRUD (фронтенд, только Express)
|
||||
// V2 — Фронтенд обычного пользователя
|
||||
//
|
||||
// Вход: req.clientId, req.email, req.impersonatedBy из resolveContext.
|
||||
// Всегда показывает выбор компании (даже если одна).
|
||||
// НЕ работает с БД напрямую — только через crud API-слой.
|
||||
// ЭТО: Express-роутер, который рендерит HTML и принимает POST-формы.
|
||||
// НЕ: работа с БД (только через crud/), валидация (в crud/).
|
||||
//
|
||||
// ЗАЧЕМ:
|
||||
// 1. Единственное место где генерится HTML для юзера.
|
||||
// 2. Все действия юзера (add/edit/delete) — через POST-формы.
|
||||
// 3. Выбор компании — всегда выпадающий список (даже если одна компания).
|
||||
// 4. Сообщения об ошибках/успехе — через query-параметры (?msg=, ?error=).
|
||||
//
|
||||
// КОНТЕКСТ (из resolveContext middleware):
|
||||
// req.clientId — W-номер текущей компании
|
||||
// req.email — почта юзера
|
||||
// req.impersonatedBy — null или почта админа
|
||||
// req.profiles — список компаний для выпадающего списка
|
||||
//
|
||||
// МАРШРУТЫ:
|
||||
// GET / — список записей + форма добавления
|
||||
// POST /add — добавить CIDR (→ crud.add → 302 с ?msg=)
|
||||
// POST /edit/:id — изменить запись
|
||||
// POST /delete/:id — удалить запись (soft delete)
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const express = require('express');
|
||||
const crud = require('../crud');
|
||||
const crud = require('../crud'); // ← единственная зависимость от данных
|
||||
|
||||
function createUserRouter() {
|
||||
const router = express.Router();
|
||||
|
||||
// ── GET / — главная: список записей + форма ────────────────────────────
|
||||
// ── GET / — главная страница ──────────────────────────────────────────
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const clId = req.clientId;
|
||||
|
||||
// Список компаний для выпадающего списка
|
||||
// Если profiles пуст — создаём fallback из clientId (одна компания)
|
||||
const allCompanies = req.profiles.length > 0
|
||||
? req.profiles
|
||||
: [{ client_id: clId, company_name: req.companyName || clId }];
|
||||
@@ -23,7 +43,7 @@ function createUserRouter() {
|
||||
const includeDeleted = req.query.deleted === '1';
|
||||
const { entries, used, limit } = await crud.list(clId, includeDeleted);
|
||||
|
||||
// Переключение компании
|
||||
// Переключение компании: запоминаем в сессии и редиректим
|
||||
if (req.query.switchTo && allCompanies.find(c => c.client_id === req.query.switchTo)) {
|
||||
req.session.user.activeClientId = req.query.switchTo;
|
||||
return res.redirect('/v2/app');
|
||||
@@ -35,18 +55,19 @@ function createUserRouter() {
|
||||
}
|
||||
});
|
||||
|
||||
// ── POST /add ───────────────────────────────────────────────────────────
|
||||
// ── POST /add — добавить запись ───────────────────────────────────────
|
||||
router.post('/add', async (req, res) => {
|
||||
try {
|
||||
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) {
|
||||
// Ошибка валидации/лимита/дубликата — показываем юзеру
|
||||
res.redirect('/v2/app?error=' + encodeURIComponent(e.message));
|
||||
}
|
||||
});
|
||||
|
||||
// ── POST /edit/:id ──────────────────────────────────────────────────────
|
||||
// ── POST /edit/:id — изменить запись ──────────────────────────────────
|
||||
router.post('/edit/:id', async (req, res) => {
|
||||
try {
|
||||
const result = await crud.edit(parseInt(req.params.id), req.clientId, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy);
|
||||
@@ -57,7 +78,7 @@ function createUserRouter() {
|
||||
}
|
||||
});
|
||||
|
||||
// ── POST /delete/:id ────────────────────────────────────────────────────
|
||||
// ── POST /delete/:id — удалить запись (soft delete) ───────────────────
|
||||
router.post('/delete/:id', async (req, res) => {
|
||||
try {
|
||||
await crud.remove(parseInt(req.params.id), req.clientId, req.email, req.impersonatedBy);
|
||||
@@ -70,8 +91,9 @@ function createUserRouter() {
|
||||
return router;
|
||||
}
|
||||
|
||||
// ── HTML-рендеринг (временный, будет заменён на EJS) ─────────────────────
|
||||
|
||||
// ── renderPage() → HTML ─────────────────────────────────────────────────────
|
||||
// Временный inline HTML (будет заменён на EJS-шаблоны).
|
||||
// Данные: entries, 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>`
|
||||
|
||||
Reference in New Issue
Block a user