Browse Source

chore: фронт :3107, API :3001 (Docker, Vite, CORS, доки)

- compose: testing-web 3107:80, testing-backend 3001:3001, PORT+FRONTEND_URL
- nginx → testing-backend:3001; Vite 3107, proxy /api → 3001
- server default PORT 3001; Dockerfile EXPOSE 3001; CORS dev — localhost:3107
- README, журнал, user guide

Made-with: Cursor
dev
Константин Лебединский 2 weeks ago
parent
commit
47279c72e3
  1. 2
      README.md
  2. 3
      backend/.env.example
  3. 2
      backend/Dockerfile
  4. 3
      backend/src/app.js
  5. 2
      backend/src/server.js
  6. 13
      docker-compose.dev.yml
  7. 2
      docs/DEV_CONTOUR_USER_GUIDE.md
  8. 6
      docs/revision_task/TESTING_JOURNAL.md
  9. 2
      frontend/nginx-default.conf
  10. 6
      frontend/vite.config.js

2
README.md

@ -129,7 +129,7 @@
4. Миграции: из каталога `backend/`: `npm run migrate`, затем `npm start` (и фронт из `frontend/``npm run dev`). 4. Миграции: из каталога `backend/`: `npm run migrate`, затем `npm start` (и фронт из `frontend/``npm run dev`).
**Docker (UI + API + общий Postgres):** поднять `Postgres_TG_Bots` (сеть `hr_postgres_dev_net`), создать БД `clinic_tests`, затем из корня `TestingWebApp`: **Docker (UI + API + общий Postgres):** поднять `Postgres_TG_Bots` (сеть `hr_postgres_dev_net`), создать БД `clinic_tests`, затем из корня `TestingWebApp`:
`docker compose -f docker-compose.dev.yml up --build` — интерфейс **http://localhost:8080** (Nginx проксирует `/api` в backend), API с хоста **http://localhost:3107** (контейнер слушает `3107`; см. [docker-compose.dev.yml](docker-compose.dev.yml), миграции в entrypoint). В БД `clinic_tests` для локального логина нужен активный `users` с bcrypt-паролем, либо включите `HR_AUTH=1` + `HR_DATABASE_URL` в compose/`.env` (см. `backend/.env.example`). `docker compose -f docker-compose.dev.yml up --build` — интерфейс **http://localhost:3107** (Nginx проксирует `/api` в backend), API с хоста **http://localhost:3001** (см. [docker-compose.dev.yml](docker-compose.dev.yml), миграции в entrypoint). Локальный `npm run dev` фронта (Vite) — тоже **:3107**, прокси `/api` на **:3001**. В БД `clinic_tests` для локального логина нужен активный `users` с bcrypt-паролем, либо включите `HR_AUTH=1` + `HR_DATABASE_URL` в compose/`.env` (см. `backend/.env.example`). В `backend/.env` задайте `PORT=3001`, если поднимаете API отдельно от compose.
`docker compose -f docker-compose.dev.yml down` — остановка. `docker compose -f docker-compose.dev.yml down` — остановка.

3
backend/.env.example

@ -24,6 +24,9 @@ DATABASE_URL=postgresql://hr_bot_user:hrbot123@localhost:5432/clinic_tests
JWT_SECRET=change_me_in_production JWT_SECRET=change_me_in_production
# Порт HTTP API (как в docker-compose: 3001)
# PORT=3001
# A.1: HR login (Werkzeug password, staff by web_login = username в public.users) # A.1: HR login (Werkzeug password, staff by web_login = username в public.users)
# В Docker (docker-compose.dev.yml) по умолчанию HR_AUTH=1 и HR_DATABASE_URL на hr_bot_test. # В Docker (docker-compose.dev.yml) по умолчанию HR_AUTH=1 и HR_DATABASE_URL на hr_bot_test.
# HR_AUTH=1 # HR_AUTH=1

2
backend/Dockerfile

@ -3,6 +3,6 @@ WORKDIR /app
COPY package.json package-lock.json* ./ COPY package.json package-lock.json* ./
RUN npm ci RUN npm ci
COPY . . COPY . .
EXPOSE 3107 EXPOSE 3001
RUN chmod +x docker-entrypoint.sh RUN chmod +x docker-entrypoint.sh
ENTRYPOINT ["./docker-entrypoint.sh"] ENTRYPOINT ["./docker-entrypoint.sh"]

3
backend/src/app.js

@ -16,9 +16,8 @@ export function createApp() {
? [process.env.FRONTEND_URL] ? [process.env.FRONTEND_URL]
: [] : []
: [ : [
'http://localhost:5173', 'http://localhost:3107',
'http://localhost:3000', 'http://localhost:3000',
'http://localhost:8080',
]; ];
app.use( app.use(
cors({ cors({

2
backend/src/server.js

@ -1,7 +1,7 @@
import { createApp } from './app.js'; import { createApp } from './app.js';
const app = createApp(); const app = createApp();
const PORT = process.env.PORT || 3107; const PORT = process.env.PORT || 3001;
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`); console.log(`Server is running on port ${PORT}`);
console.log(`Environment: ${process.env.NODE_ENV || 'development'}`); console.log(`Environment: ${process.env.NODE_ENV || 'development'}`);

13
docker-compose.dev.yml

@ -6,7 +6,7 @@
# #
# Запуск: из каталога TestingWebApp # Запуск: из каталога TestingWebApp
# docker compose -f docker-compose.dev.yml up --build # docker compose -f docker-compose.dev.yml up --build
# UI: http://localhost:8080 ( /api → backend ) # UI: http://localhost:3107 (Nginx: /api → backend:3001), API с хоста: http://localhost:3001
services: services:
testing-backend: testing-backend:
@ -20,16 +20,17 @@ services:
environment: environment:
DATABASE_URL: postgresql://hr_bot_user:hrbot123@hr_postgres_dev:5432/clinic_tests DATABASE_URL: postgresql://hr_bot_user:hrbot123@hr_postgres_dev:5432/clinic_tests
JWT_SECRET: ${JWT_SECRET:-testing_webapp_jwt_dev} JWT_SECRET: ${JWT_SECRET:-testing_webapp_jwt_dev}
# development: httpOnly-cookie без Secure (иначе на http://localhost:8080 логин не сработает) # development: httpOnly-cookie без Secure (иначе на http://localhost:3107 логин не сработает)
NODE_ENV: development NODE_ENV: development
FRONTEND_URL: http://localhost:8080 FRONTEND_URL: http://localhost:3107
PORT: "3001"
# Вход теми же учётками, что в HR: проверка пароля в hr_bot_test + привязка сотрудника по web_login. # Вход теми же учётками, что в HR: проверка пароля в hr_bot_test + привязка сотрудника по web_login.
# Без HR_AUTH / HR_DATABASE_URL логин ищется только в clinic_tests.users (локальные dev-учётки). # Без HR_AUTH / HR_DATABASE_URL логин ищется только в clinic_tests.users (локальные dev-учётки).
HR_AUTH: ${HR_AUTH:-1} HR_AUTH: ${HR_AUTH:-1}
HR_DATABASE_URL: postgresql://hr_bot_user:hrbot123@hr_postgres_dev:5432/hr_bot_test HR_DATABASE_URL: postgresql://hr_bot_user:hrbot123@hr_postgres_dev:5432/hr_bot_test
# С хоста API: localhost:3107 (то же, что в frontend/vite proxy на локальный dev) # Прямой доступ к API с хоста (Vite proxy в dev: см. frontend/vite.config.js)
ports: ports:
- "3107:3107" - "3001:3001"
networks: networks:
- app - app
- postgres - postgres
@ -42,7 +43,7 @@ services:
depends_on: depends_on:
- testing-backend - testing-backend
ports: ports:
- "8080:80" - "3107:80"
networks: networks:
- app - app

2
docs/DEV_CONTOUR_USER_GUIDE.md

@ -2,7 +2,7 @@
**Для кого:** тот, кто **проверяет** интерфейс на своей машине или на общем dev-сервере, без погрузки в код. **Для кого:** тот, кто **проверяет** интерфейс на своей машине или на общем dev-сервере, без погрузки в код.
**Адрес по умолчанию:** [http://localhost:8080](http://localhost:8080) — если вы подняли проект командой `docker compose -f docker-compose.dev.yml up` из корня репозитория. Страница и API с одного адреса: запросы к `/api/…` идут на бэкенд за прокси. **Адрес по умолчанию:** [http://localhost:3107](http://localhost:3107) — если вы подняли проект командой `docker compose -f docker-compose.dev.yml up` из корня репозитория. В браузере откройте **:3107** (интерфейс); запросы к `/api/…` с этой страницы идут на бэкенд через Nginx. Прямой адрес API с вашего ПК: **http://localhost:3001** (если смотрите health или тестируете curl).
Если кто-то дал **другой URL** (например, внутренний хост клиники) — откройте его; логика та же. Если кто-то дал **другой URL** (например, внутренний хост клиники) — откройте его; логика та же.

6
docs/revision_task/TESTING_JOURNAL.md

@ -10,7 +10,7 @@
**Ветка / коммит последней привязки:** `dev` (обновлять при релизе на проверку; актуализация документации 2026-04-24 — [../PROJECT_STATUS.md](../PROJECT_STATUS.md)) **Ветка / коммит последней привязки:** `dev` (обновлять при релизе на проверку; актуализация документации 2026-04-24 — [../PROJECT_STATUS.md](../PROJECT_STATUS.md))
**Адрес стенда:** `http://localhost:8080` (UI; при стеке `docker compose -f docker-compose.dev.yml up` — тот же origin для `/api/…`). **Адрес стенда:** `http://localhost:3107` (UI; при стеке `docker compose -f docker-compose.dev.yml up` — тот же origin для `/api/…` через Nginx; прямой API с хоста — `http://localhost:3001`).
**Актуальный UI (после 2026-04-24):** старт прохождения — **не** с карточки теста, а со **списка «Тесты»**: в каждой строке **справа** кнопка **«Пройти»**; **слева** — ссылка на карточку. Под названием — **«Автор: Вы»** или **«Автор: Фамилия И. О.»**; в шапке — **Фамилия И. О.**, полное ФИО в подсказке. После **«Завершить тест»** — **разбор** по вопросам; у автора в карточке — **«Прогоны и разбор»** по завершённым попыткам. Шаги **S1-07** и **S1-13** в таблице ниже описывают **старый** вариант («Старт/Начать попытку» на карточке) — оставлены в журнале как история. Регресс по новому потоку — **S1-14** и далее. **Актуальный UI (после 2026-04-24):** старт прохождения — **не** с карточки теста, а со **списка «Тесты»**: в каждой строке **справа** кнопка **«Пройти»**; **слева** — ссылка на карточку. Под названием — **«Автор: Вы»** или **«Автор: Фамилия И. О.»**; в шапке — **Фамилия И. О.**, полное ФИО в подсказке. После **«Завершить тест»** — **разбор** по вопросам; у автора в карточке — **«Прогоны и разбор»** по завершённым попыткам. Шаги **S1-07** и **S1-13** в таблице ниже описывают **старый** вариант («Старт/Начать попытку» на карточке) — оставлены в журнале как история. Регресс по новому потоку — **S1-14** и далее.
@ -42,8 +42,8 @@
|-----|------------------------------|-----------|------| |-----|------------------------------|-----------|------|
| S1-00 | Открыть `TESTING_JOURNAL.md`, просмотреть верх и раздел B; в таблице — строка S1-00 «ожидает…» | ОК | 2026-04-23 | | S1-00 | Открыть `TESTING_JOURNAL.md`, просмотреть верх и раздел B; в таблице — строка S1-00 «ожидает…» | ОК | 2026-04-23 |
| S1-01 | Открыть `card1.md`, убедиться, что есть блок про V.1 / V.2 / V.3 (сохранение / форк) | ОК | 2026-04-24 | | S1-01 | Открыть `card1.md`, убедиться, что есть блок про V.1 / V.2 / V.3 (сохранение / форк) | ОК | 2026-04-24 |
| S1-02 | Открыть в браузере `http://localhost:8080` — должна загрузиться **страница входа** (заголовок «Клинические тесты» / «Войдите в систему», поля логин и пароль, кнопка «Войти») | ОК | 2026-04-23 | | S1-02 | Открыть в браузере `http://localhost:3107` — должна загрузиться **страница входа** (заголовок «Клинические тесты» / «Войдите в систему», поля логин и пароль, кнопка «Войти») | ОК | 2026-04-23 |
| S1-03 | В браузере открыть `http://localhost:8080/api/health` — в ответе виден JSON c полем `status` со значением `ok` (страница не «404» и не пустая ошибка) | ОК | 2026-04-23 | | S1-03 | В браузере открыть `http://localhost:3107/api/health` (или `http://localhost:3001/api/health` при прямом доступе к API) — в ответе виден JSON c полем `status` со значением `ok` (страница не «404» и не пустая ошибка) | ОК | 2026-04-23 |
| S1-04 | С экрана входа войти: учётка **вашей** среды (локальный `users` в `clinic_tests` **или** при `HR_AUTH=1` — логин HR). После **«Войти»** должен открыться экран **«Тесты»** с **шапкой** (слева бренд, справа **Фамилия И. О.**/роль и кнопка **«Выйти»**; не обязательно полное тройное ФИО в одну строку). Список тестов может быть пустым. | ОК | 2026-04-24 | | S1-04 | С экрана входа войти: учётка **вашей** среды (локальный `users` в `clinic_tests` **или** при `HR_AUTH=1` — логин HR). После **«Войти»** должен открыться экран **«Тесты»** с **шапкой** (слева бренд, справа **Фамилия И. О.**/роль и кнопка **«Выйти»**; не обязательно полное тройное ФИО в одну строку). Список тестов может быть пустым. | ОК | 2026-04-24 |
| S1-05 | На экране «Тесты» в поле **«Новый тест — название»** ввести любое имя, нажать **«Создать»**. Должен открыться экран карточки теста (ссылка «← к списку», блок **Версии**, черновик и т.д.). | ОК | 2026-04-24 | | S1-05 | На экране «Тесты» в поле **«Новый тест — название»** ввести любое имя, нажать **«Создать»**. Должен открыться экран карточки теста (ссылка «← к списку», блок **Версии**, черновик и т.д.). | ОК | 2026-04-24 |
| S1-06 | На карточке теста в блоке **«Черновик (V.3)»** (при необходимости изменить текст вопроса) нажать **«Сохранить черновик»**. Под кнопкой появляется пояснение (например, что черновик применён) или пусто без ошибки на красном. Раздел **Версии** остаётся / обновляется без сообщения «Доступ запрещён». | ОК | 2026-04-24 | | S1-06 | На карточке теста в блоке **«Черновик (V.3)»** (при необходимости изменить текст вопроса) нажать **«Сохранить черновик»**. Под кнопкой появляется пояснение (например, что черновик применён) или пусто без ошибки на красном. Раздел **Версии** остаётся / обновляется без сообщения «Доступ запрещён». | ОК | 2026-04-24 |

2
frontend/nginx-default.conf

@ -8,7 +8,7 @@ server {
} }
client_max_body_size 10m; client_max_body_size 10m;
location /api/ { location /api/ {
proxy_pass http://testing-backend:3107; proxy_pass http://testing-backend:3001;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;

6
frontend/vite.config.js

@ -4,11 +4,11 @@ import react from '@vitejs/plugin-react';
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
server: { server: {
port: 5173, port: 3107,
// Тот же порт, что у API на хосте (docker-compose: 3107:3107) или `npm run dev` в backend // UI на 3107; API на 3001 (docker compose и `npm run dev` в backend)
proxy: { proxy: {
'/api': { '/api': {
target: 'http://localhost:3107', target: 'http://localhost:3001',
changeOrigin: true, changeOrigin: true,
}, },
}, },

Loading…
Cancel
Save