67 lines
5.0 KiB
Markdown
67 lines
5.0 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: Процесс и доступ
|
||
`jira-hub serve` SHALL запускать один процесс: HTTP на `0.0.0.0:<port>` (по умолчанию 8790), база и настройки в
|
||
`~/.local/share/jira-hub/` (переопределяется `JIRA_HUB_HOME`). Все маршруты API SHALL требовать
|
||
`Authorization: Bearer <token>`: агентский токен открывает только `/agent/*`, клиентский — всё остальное. Исключение —
|
||
раздача веб-приложения (`GET /app`, `GET /app/…`) и перенаправления `GET /`, `GET /links`: это статические файлы без
|
||
данных, они отдаются без токена. Ответы API — JSON, ошибки — `{error, detail}` с кодами 400 (неверное тело или
|
||
`Content-Length`), 401, 404, 409, 413 (тело больше предела), 422, 500 (внутренняя ошибка); реле общей папки
|
||
дополнительно отвечает 502. Методы, кроме GET, POST и PUT, отвечают 501 стандартной страницей `http.server`, не JSON.
|
||
|
||
#### Scenario: Чужой токен
|
||
- **WHEN** агентским токеном вызван `GET /issues`
|
||
- **THEN** 401
|
||
|
||
#### Scenario: Неподдерживаемый метод
|
||
- **WHEN** `DELETE /issues/AURORA-1`
|
||
- **THEN** 501, тело не JSON; база не меняется
|
||
|
||
#### Scenario: Страница без токена
|
||
- **WHEN** `GET /app/board` без заголовка `Authorization`, сборка приложения есть
|
||
- **THEN** 200, `Content-Type: text/html; charset=utf-8`, тело — `index.html` сборки; данных зеркала в нём нет
|
||
|
||
## ADDED Requirements
|
||
|
||
### Requirement: Раздача веб-приложения
|
||
Хаб SHALL отдавать собранное веб-приложение (спека `web-app`) из каталога пакета `src/jira_hub/web/app/`, читая файлы
|
||
с диска на каждый запрос:
|
||
- `GET /app/assets/<путь>` — файл из `assets/` сборки; путь, который после разрешения выходит за `assets/` или не
|
||
существует, — 404; `Content-Type` по расширению (`.js` — `text/javascript; charset=utf-8`, `.css` —
|
||
`text/css; charset=utf-8`, `.svg` — `image/svg+xml`, `.png` — `image/png`, `.ico` — `image/x-icon`, `.woff2` —
|
||
`font/woff2`, `.map` — `application/json`, прочее — `application/octet-stream`);
|
||
`Cache-Control: public, max-age=31536000, immutable`;
|
||
- любой другой `GET /app` или `GET /app/…` — `index.html` сборки, `text/html; charset=utf-8`, `Cache-Control: no-cache`;
|
||
- если `index.html` сборки нет — на любой `GET /app…` 503 `text/html; charset=utf-8` с текстом, что приложение не
|
||
собрано и нужно выполнить `make web` в каталоге jira-hub;
|
||
- `GET /` и `GET /links` — 302 с `Location: /app/board`.
|
||
Сборка приложения не хранится в git; её создаёт `make web`.
|
||
|
||
#### Scenario: Файл сборки
|
||
- **WHEN** в сборке есть `assets/index-abc123.js`, запрошен `GET /app/assets/index-abc123.js`
|
||
- **THEN** 200, `Content-Type: text/javascript; charset=utf-8`, `Cache-Control` с `immutable`, тело — содержимое файла
|
||
|
||
#### Scenario: Путь приложения
|
||
- **WHEN** запрошен `GET /app/issues/AURORA-1620`
|
||
- **THEN** 200, тело — `index.html` сборки, `Cache-Control: no-cache`
|
||
|
||
#### Scenario: Выход за каталог сборки
|
||
- **WHEN** запрошен `GET /app/assets/../../api.py` (в том числе в виде `%2e%2e`)
|
||
- **THEN** 404, содержимое файлов вне `assets/` не отдаётся
|
||
|
||
#### Scenario: Приложение не собрано
|
||
- **WHEN** каталога сборки нет, запрошен `GET /app/board`
|
||
- **THEN** 503, тело — HTML с подсказкой `make web`
|
||
|
||
#### Scenario: Старый адрес доски
|
||
- **WHEN** запрошен `GET /links` или `GET /`
|
||
- **THEN** 302, `Location: /app/board`
|
||
|
||
## REMOVED Requirements
|
||
|
||
### Requirement: Страница доски связей
|
||
**Reason**: страница `links.html` заменена страницей «Доска» веб-приложения (спека `web-app`, требование «Доска связей»);
|
||
поведение перенесено без изменений, кроме закрытых недочётов jira-hub#20 и действия «Открыть карточку».
|
||
**Migration**: `GET /` и `GET /links` перенаправляют на `/app/board`; токен (`jira-hub-token`) и раскладки
|
||
(`graph-<имя>…`) в `localStorage` читаются приложением под теми же ключами.
|