# Документ требований

## Введение

Инструмент командной строки "aa" для автоматического присвоения человекочитаемых идентификаторов задачам и подзадачам в проектах Asana. Инструмент добавляет короткие ID (например, PRJ-5, PRJ-5-1) в начало названия задач, что упрощает их идентификацию и обсуждение в команде.

## Глоссарь

- **Система** (aa): Консольное приложение для управления идентификаторами задач Asana
- **Человекочитаемый ID**: Короткий идентификатор формата CODE-N или CODE-N-M-..., где CODE - код проекта (2-5 заглавных букв), N, M - порядковые номера
- **Корневая задача**: Задача верхнего уровня в проекте (не является подзадачей)
- **Подзадача**: Задача, являющаяся дочерней по отношению к другой задаче
- **Кэш**: Файл .aa.cache.yaml, хранящий информацию о последних выданных идентификаторах
- **Конфиг**: Файл .aa.yml, содержащий настройки проектов и токен Asana
- **Конфликт ID**: Ситуация, когда в Asana обнаружен ID больше, чем последний известный в кэше
- **Dry-run режим**: Режим работы, при котором изменения не применяются, только показываются

## Требования

### Требование 1

**User Story:** Как пользователь, я хочу инициализировать конфигурацию проекта, чтобы начать использовать инструмент aa

#### Критерии приемки

1. WHEN пользователь выполняет команду init без флагов THEN Система SHALL запустить интерактивный режим настройки
2. WHEN пользователь выполняет команду init с флагом --force THEN Система SHALL создать файл .aa.yml с шаблоном без интерактива
3. WHEN файл .aa.yml уже существует THEN Система SHALL завершиться с предупреждением без перезаписи файла
4. WHEN Система создает шаблон конфига в режиме force THEN Система SHALL включить поля asana_token, interactive и список projects с примерами

### Требование 1.5

**User Story:** Как пользователь, я хочу автоматически получить все мои проекты из Asana при инициализации, чтобы не искать их ID вручную

#### Критерии приемки

1. WHEN пользователь выполняет команду init в интерактивном режиме THEN Система SHALL запросить Personal Access Token у пользователя с скрытым вводом
2. WHEN Система получает токен от пользователя THEN Система SHALL выполнить запрос к Asana API для получения всех workspaces пользователя
3. WHEN Система получает workspaces THEN Система SHALL получить все проекты из всех workspaces
4. WHEN Система получает список проектов THEN Система SHALL отфильтровать архивные проекты и использовать только активные проекты
5. WHEN Система получает список активных проектов THEN Система SHALL создать файл .aa.yml со всеми найденными активными проектами
6. WHEN Система добавляет проект в конфиг THEN Система SHALL добавить комментарий с названием проекта
7. WHEN Система добавляет проект в конфиг THEN Система SHALL добавить комментарий со ссылкой на проект в Asana формата https://app.asana.com/0/{asana_id}
8. WHEN Система добавляет проект в конфиг THEN Система SHALL использовать placeholder код который пользователь заменит на код длиной от 2 до 5 заглавных букв
9. WHEN Система создает конфиг в интерактивном режиме THEN Система SHALL установить поле interactive в значение false

### Требование 2

**User Story:** Как пользователь, я хочу сканировать проекты для определения текущего состояния ID, чтобы синхронизировать локальный кэш с Asana

#### Критерии приемки

1. WHEN пользователь выполняет команду scan THEN Система SHALL загрузить и валидировать конфигурацию из файла .aa.yml
2. WHEN Система валидирует конфигурацию THEN Система SHALL проверить наличие всех обязательных полей через Pydantic модель
3. WHEN Система сканирует проект THEN Система SHALL получить все задачи проекта из Asana API отсортированные по дате создания
4. WHEN Система анализирует задачи проекта THEN Система SHALL извлечь существующие ID из названий задач используя регулярное выражение
5. WHEN Система определяет последний ID THEN Система SHALL найти максимальный номер среди существующих ID или установить 0 если ID отсутствуют
6. WHEN Система обнаруживает конфликт ID THEN Система SHALL завершиться с ошибкой и сообщением о конфликте
7. WHEN сканирование завершено успешно THEN Система SHALL сохранить структуру счетчиков в файл .aa.cache.yaml

### Требование 3

**User Story:** Как пользователь, я хочу автоматически присваивать ID всем задачам без идентификаторов, чтобы все задачи в проекте имели человекочитаемые ID

#### Критерии приемки

1. WHEN пользователь выполняет команду update THEN Система SHALL выполнить процесс сканирования для проверки конфликтов
2. WHEN Система обрабатывает задачи THEN Система SHALL пропустить задачи, у которых уже есть ID в названии
3. WHEN Система присваивает ID корневой задаче THEN Система SHALL добавить идентификатор формата CODE-N в начало названия задачи
4. WHEN Система присваивает ID подзадаче THEN Система SHALL добавить идентификатор формата CODE-N-M в начало названия подзадачи
5. WHEN Система присваивает ID вложенной подзадаче THEN Система SHALL добавить идентификатор формата CODE-N-M-K в начало названия
6. WHEN Система обновляет название задачи THEN Система SHALL отправить изменение в Asana API
7. WHEN Система присваивает новый ID THEN Система SHALL обновить соответствующий счетчик в кэше
8. WHEN обработка всех задач завершена THEN Система SHALL сохранить обновленный кэш в файл .aa.cache.yaml

### Требование 4

**User Story:** Как пользователь, я хочу работать с несколькими проектами одновременно, чтобы управлять ID во всех моих проектах из одного конфига

#### Критерии приемки

1. WHEN пользователь запускает команду без указания проекта THEN Система SHALL обработать все проекты из конфигурации
2. WHEN пользователь указывает код проекта через параметр THEN Система SHALL обработать только указанный проект
3. WHEN Система обрабатывает несколько проектов THEN Система SHALL использовать соответствующий код для каждого проекта
4. WHEN Система работает с проектом THEN Система SHALL использовать соответствующий asana_id из конфигурации

### Требование 5

**User Story:** Как пользователь, я хочу использовать dry-run режим, чтобы проверить какие изменения будут применены без фактического изменения задач

#### Критерии приемки

1. WHEN пользователь указывает флаг --dry-run THEN Система SHALL выполнить все операции анализа без изменения задач в Asana
2. WHEN Система работает в dry-run режиме THEN Система SHALL вывести список задач и ID которые будут присвоены
3. WHEN Система работает в dry-run режиме THEN Система SHALL не сохранять изменения в файл кэша
4. WHEN Система работает в dry-run режиме THEN Система SHALL не отправлять запросы на изменение задач в Asana API

### Требование 6

**User Story:** Как пользователь, я хочу видеть подробные логи работы системы, чтобы отлаживать проблемы и понимать что происходит

#### Критерии приемки

1. WHEN пользователь указывает флаг --debug THEN Система SHALL установить уровень логирования DEBUG
2. WHEN Система работает в debug режиме THEN Система SHALL выводить детальную информацию о каждом API запросе
3. WHEN Система работает в debug режиме THEN Система SHALL выводить информацию о каждой обрабатываемой задаче
4. WHEN Система работает без флага --debug THEN Система SHALL выводить только основные сообщения уровня INFO

### Требование 7

**User Story:** Как пользователь, я хочу указывать путь к файлу конфигурации, чтобы использовать разные конфиги для разных окружений

#### Критерии приемки

1. WHEN пользователь не указывает путь к конфигу THEN Система SHALL использовать файл .aa.yml в текущей директории
2. WHEN пользователь указывает параметр --config THEN Система SHALL использовать указанный файл конфигурации
3. WHEN указанный файл конфигурации не существует THEN Система SHALL завершиться с ошибкой и сообщением о отсутствии файла

### Требование 8

**User Story:** Как пользователь, я хочу чтобы система корректно обрабатывала иерархию задач, чтобы ID отражали структуру задач

#### Критерии приемки

1. WHEN Система обрабатывает корневую задачу THEN Система SHALL использовать счетчик last_root для определения следующего номера
2. WHEN Система обрабатывает подзадачу THEN Система SHALL использовать счетчик родительской задачи из секции subtasks
3. WHEN Система обрабатывает подзадачу без записи в кэше THEN Система SHALL инициализировать счетчик значением 0
4. WHEN Система сохраняет кэш THEN Система SHALL сохранить структуру с полями last_root и subtasks для каждого проекта

### Требование 9

**User Story:** Как пользователь, я хочу чтобы система обрабатывала конфликты ID, чтобы избежать дублирования или пропусков номеров

#### Критерии приемки

1. WHEN Система обнаруживает ID больше чем last_root в кэше THEN Система SHALL завершиться с ошибкой
2. WHEN пользователь указывает флаг --ignore-conflicts THEN Система SHALL обновить счетчики до максимальных найденных значений и продолжить работу
3. WHEN Система обнаруживает дублирующиеся ID THEN Система SHALL завершиться с ошибкой и указать конфликтующие задачи

### Требование 10

**User Story:** Как разработчик, я хочу чтобы система имела модульную архитектуру, чтобы код был легко поддерживаемым и расширяемым

#### Критерии приемки

1. WHEN Система организует код THEN Система SHALL разделить команды CLI в отдельные модули
2. WHEN Система организует код THEN Система SHALL выделить работу с Asana API в отдельный модуль
3. WHEN Система организует код THEN Система SHALL выделить работу с конфигурацией в отдельный модуль
4. WHEN Система организует код THEN Система SHALL выделить работу с кэшем в отдельный модуль
5. WHEN Система организует код THEN Система SHALL использовать Pydantic для валидации структур данных

### Требование 11

**User Story:** Как пользователь, я хочу использовать минимальное количество зависимостей, чтобы упростить установку и поддержку инструмента

#### Критерии приемки

1. WHEN Система определяет зависимости THEN Система SHALL использовать только библиотеки click, httpx, pydantic и pyyaml
2. WHEN Система работает с YAML THEN Система SHALL использовать библиотеку pyyaml
3. WHEN Система выполняет HTTP запросы THEN Система SHALL использовать библиотеку httpx

### Требование 12

**User Story:** Как пользователь, я хочу чтобы система работала асинхронно, чтобы обработка множества задач выполнялась эффективно

#### Критерии приемки

1. WHEN Система выполняет запросы к Asana API THEN Система SHALL использовать асинхронные HTTP запросы через httpx
2. WHEN Система обрабатывает множество задач THEN Система SHALL выполнять операции параллельно используя asyncio
3. WHEN Система обновляет задачи THEN Система SHALL отправлять запросы асинхронно для ускорения обработки
4. WHEN Система реализует команды CLI THEN Система SHALL использовать async/await синтаксис для всех операций ввода-вывода

### Требование 13

**User Story:** Как пользователь, я хочу использовать современный менеджер пакетов uv, чтобы упростить установку и управление зависимостями

#### Критерии приемки

1. WHEN Система определяет инструменты управления проектом THEN Система SHALL использовать uv в качестве менеджера пакетов
2. WHEN Система настраивает проект THEN Система SHALL использовать pyproject.toml для конфигурации с поддержкой uv
3. WHEN пользователь устанавливает инструмент THEN пользователь SHALL использовать команду uv для установки
4. WHEN Система регистрирует консольную команду THEN Система SHALL определить entry point aa в pyproject.toml для запуска через uv
