feat: справочник компаний из api.tnsu.kz вместо копии в коде

Список юрлиц группы меняется без нашего участия, а две копии в репозитории
(COMPANY_OPTIONS во фронте и COMPANY_NAMES на сервере) неизбежно разошлись
бы с источником и между собой. Теперь единственный источник —
/Dictionary/Companies:

- GET /companies проксирует справочник, чтобы токен не утекал в браузер;
- имя компании для колонки Company резолвится по нему же, на сервере;
- в кэше 10 минут — новое юрлицо подхватится без перезапуска сервиса.

Пока список грузится, в select показывается «Загружаем…»; если не
загрузился — ошибка в слоте обязательного поля, а не пустой список.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-24 13:06:09 +05:00
parent e9ae3d5bab
commit b4a10510e1
8 changed files with 146 additions and 73 deletions
+13
View File
@@ -1,4 +1,5 @@
import express from 'express';
import { getCompanies } from './companies';
import { config } from './config';
import { getAppOnlyToken } from './graphAuth';
import { submitFeedback } from './sharepoint';
@@ -22,6 +23,18 @@ app.get('/diag/token', async (_req, res) => {
}
});
// Справочник компаний для выпадающего списка формы. Ходит в api.tnsu.kz за
// нас, чтобы токен не утекал в браузер, и отдаёт список как есть.
app.get('/companies', async (_req, res) => {
try {
res.status(200).json(await getCompanies());
} catch (error) {
const message = (error as Error).message;
console.error('Не удалось получить справочник компаний:', message);
res.status(502).json({ ok: false, error: message });
}
});
app.post('/feedback', async (req, res) => {
try {
await submitFeedback(req.body);