---
name: doc-md
description: >
  Генерирует внешнюю Markdown-документацию для C#/.NET классов: отдельный
  .md-файл на каждый класс с таблицей свойств, разделом каждого метода
  (параметры, возвращаемое значение, исключения) и сводным описанием класса
  в конце. Структура папок documentation/api/ повторяет структуру solution. Ставит
  гиперссылки на унаследованные типы и на типы из других файлов проекта.
  Используй, когда пользователь говорит «сгенерируй .md для класса», «создай
  внешнюю документацию», «сделай markdown-описание», «doc-md». Это НЕ
  генератор inline XML-doc комментариев (для этого — doc-cs) и НЕ реверс-
  инжиниринг схемы БД (для этого — doc-db).
disable-model-invocation: true
allowed-tools: Read, Grep, Glob, Write, Bash, Task
argument-hint: путь к .cs-файлу, классу или папке (корень solution)
---

# doc-md — генератор внешней Markdown-документации для C# классов

## Алгоритм (трёхпроходный)

> **Pass 1 (реестр типов) выполняется последовательно в главной сессии.**
> Pass 2/3 на больших проектах распараллеливаются субагентами — см. раздел
> «Обработка больших проектов (параллелизм ≤ 10)».

### Pass 1 — обнаружение (Glob + Grep)

1. **Найди все .cs-файлы** в переданном пути: `Glob("**/*.cs")`.
2. **Для каждого файла** извлеки:
   - Объявления классов: `public (partial|abstract|sealed|static)?\s+class\s+(\w+)(\s*:\s*[\w,\s<>]+)?`
   - Пространство имён: `^namespace\s+([\w.]+)`
   - Свойства: `(public|protected|internal)[^;{]+\{[^}]*get[^}]*\}`
   - Методы: `(public|protected|internal)[^(]+\([^)]*\)`
   - Конструкторы: `public\s+ClassName\s*\(`
   - Существующие XML-doc: блоки `/// <summary>…</summary>` над членами
3. **Составь реестр типов проекта** — словарь `ClassName → relative/path/File.cs`.
   Он нужен для разрешения межфайловых ссылок на шаге 3.

### Pass 2 — семантический разбор (LLM)

Для каждого класса сначала сформируй **frontmatter** строго по
`references/frontmatter-schema.md` (первым блоком файла). Поле `tables:`
заполни по SQL-литералам (`INSERT INTO`, `FROM`, `UPDATE`, `DELETE FROM`) и
обращениям `dr["…"]` в теле класса, в формате `СХЕМА.ТАБЛИЦА` — это мост к
`doc-db`. Затем тело:

1. **Заголовок класса:**
   - Имя, пространство имён, модификаторы (`abstract`, `sealed`, `partial`).
   - Базовый класс и список интерфейсов из объявления.

2. **Таблица свойств** — все `public`/`protected` свойства:
   - Колонки: Свойство | Тип | Доступ | Описание.
   - Описание — из `<summary>` XML-doc; если нет — эвристика по имени.
   - Тип: если тип из реестра проекта — уже запомни, ссылку добавишь на Pass 3.

3. **Разделы методов** — каждый `public`/`protected` метод и конструктор:
   - Полная сигнатура заголовком `### \`ReturnType MethodName(params)\``.
   - Одно предложение: что делает и зачем (из `<summary>` или эвристика).
   - Таблица параметров: Параметр | Тип | Описание.
   - **Возвращает:** что и когда; поведение при null / пустой коллекции.
   - **Исключения:** тип — причина (только если явный `throw` или очевиден из ADO.NET).
   - Если метод DA-класса — укажи операцию БД (`INSERT / UPDATE / SELECT / DELETE`) и таблицу.

4. **Сводное описание класса** (раздел в конце):
   - Назначение класса в системе: домен, слой (DA / сервис / маппинг / модель).
   - Основные паттерны использования.
   - Зависимости: какие типы инжектируются или используются.

### Pass 3 — разрешение ссылок и запись

1. **Межфайловые ссылки.** Для каждого типа в таблицах свойств и сигнатурах методов:
   - Если тип есть в реестре проекта → замени на `[ClassName](относительный/путь/ClassName.md)`.
   - Относительный путь считай от расположения текущего `.md`-файла.

2. **Ссылки на наследование.** В заголовке класса:
   - Базовый класс: `**Наследует:** [BaseClass](../path/BaseClass.md)` (если в реестре).
   - Интерфейсы: `**Реализует:** [IFoo](../path/IFoo.md), [IBar](../path/IBar.md)`.
   - Если тип не из этого проекта (BCL, NuGet) — пишем без ссылки, просто имя.

3. **Зеркалирование структуры папок.**
   - Корень вывода: `documentation/api/` в корне solution.
   - Файл `src/DataAccess/Dico/SvItemDao.cs` → `documentation/api/DataAccess/Dico/SvItemDao.md`.
   - Если аргумент — отдельный `.cs`-файл, создай только один `.md` рядом в `documentation/api/`.
   - Создавай папки через `Bash: mkdir -p <путь>` перед записью.

4. **Запись файлов** через `Write`. Один `.md` = один класс. Если в одном `.cs` несколько классов — несколько `.md`-файлов.

5. **Оглавление `documentation/api/index.md`.** После записи всех классов сгенерируй
   или обнови индекс по `assets/index.md.template`: список задокументированных
   классов, сгруппированный по namespace, с колонками Класс | Слой | Таблицы |
   Описание и ссылками на `.md`. Это единая точка входа и индекс для поиска; в
   шапку добавь ссылку на `database.md`. На параллельных прогонах индекс
   собирает **главная сессия** после всех волн субагентов.

## Формат вывода

Полный шаблон — `assets/class.md.template`. Итоговая структура файла:

```markdown
---
title: ClassName
type: class
namespace: My.DataAccess.Dico
layer: data-access
source: src/DataAccess/Dico/ClassName.cs
tables: [DICT.SV_ITEM]
tags: [repository, oracle, crud]
summary: Репозиторий справочника «Уровни доступа».
---

# `ClassName`

**Namespace:** `My.DataAccess.Dico`
**Файл:** [`src/DataAccess/Dico/ClassName.cs`](../../src/DataAccess/Dico/ClassName.cs)
**Наследует:** [`BaseRepo`](../common/BaseRepo.md)
**Реализует:** [`IDisposable`](), [`IRepository<SvItem>`]()

---

## Свойства

| Свойство | Тип | Доступ | Описание |
|---|---|---|---|
| `ConnectionString` | `string` | `public` | Строка подключения к Oracle. |
| `Context` | [`AppContext`](../AppContext.md) | `public` | Контекст приложения. |

---

## Конструкторы

### `ClassName(AppContext context)`

Инициализирует репозиторий с переданным контекстом приложения.

| Параметр | Тип | Описание |
|---|---|---|
| `context` | [`AppContext`](../AppContext.md) | Контекст с настройками подключения. |

---

## Методы

### `long Insert(SvItem m)`

Вставляет новую запись в `DICT.SV_ITEM`.

**Операция БД:** `INSERT` → `DICT.SV_ITEM`.

| Параметр | Тип | Описание |
|---|---|---|
| `m` | [`SvItem`](../models/SvItem.md) | DTO новой записи; `m.Guid` обязателен. |

**Возвращает:** количество вставленных строк (ожидается `1`).

**Исключения:** `OracleException` — при нарушении уникальности `SV_GUID`.

См. также: [`Update`](#updatesvitem-m), [`GetById`](#getbyidlong-id).

---

### `SvItem GetById(long id)`

Возвращает запись справочника по первичному ключу.

**Операция БД:** `SELECT` → `DICT.SV_ITEM WHERE SV_ID = :p_ID`.

| Параметр | Тип | Описание |
|---|---|---|
| `id` | `long` | Первичный ключ `SV_ID`. |

**Возвращает:** экземпляр [`SvItem`](../models/SvItem.md) или `null` если запись не найдена.

---

## Описание класса

`ClassName` — репозиторий доступа к справочнику «Уровни доступа» (`DICT.SV_ITEM`).
Реализует полный CRUD через `Oracle.ManagedDataAccess`. Используется слоем сервисов
для управления ролями пользователей клиентского приложения.

**Зависимости:** [`AppContext`](../AppContext.md), `Oracle.ManagedDataAccess.Client`.

**Используется в:** [`AccessService`](../services/AccessService.md).
```

## Обработка больших проектов (параллелизм ≤ 10)

Опциональный режим. Для небольшого проекта работай последовательно — параллелизм
нужен только когда классов много и важно время прогона.

1. **Pass 1 — только в главной сессии.** Реестр типов (`ClassName → путь`)
   строится один раз до диспетча. Иначе субагенты сгенерируют межфайловые
   ссылки на реестр, который каждый «угадал» по-своему, и cross-links разъедутся.
2. **Раздели классы на группы и обрабатывай волнами не более 10 параллельных
   субагентов (`Task`).** Запусти до 10 вызовов `Task` в одном сообщении,
   дождись завершения волны, затем следующую.
3. **Каждому субагенту в промпте передай:**
   - список его `.cs`-файлов/классов;
   - путь к `references/frontmatter-schema.md` — обязан прочитать до записи,
     иначе имена и регистр полей frontmatter разъедутся между агентами и поиск
     по полю сломается;
   - готовый реестр типов из Pass 1 (для корректных межфайловых ссылок);
   - корень вывода `documentation/api/`.
4. **`index.md` собирает главная сессия** после всех волн — только у неё полный
   список классов.

## Соглашения

- Язык вывода — **русский**. Имена классов, типов и членов — как в коде.
- Не выдумывай описания, которых нет ни в XML-doc, ни в именах. Напиши `—` в таблице.
- Ссылки ставь только на типы из **этого проекта**. BCL и NuGet-типы — без ссылок.
- Относительные пути в ссылках считай от текущего `.md`, не от корня.
- Якорные ссылки (`#method-name`) формируй по правилу GitHub Markdown: lowercase, пробелы → `-`, спецсимволы убрать.
- Если класс `partial` — собери все части в один `.md`.
- Если метод `override` или реализует интерфейс — добавь строку `**Переопределяет:** [BaseClass.MethodName](...)`.

## Что делать НЕ нужно

- Не генерируй inline `///` комментарии в `.cs`-файлах — только `.md`.
- Не пропускай `protected` члены — они важны для понимания наследования.
- Не создавай один большой `README.md` на всё — строго по одному `.md` на класс.
- Не используй абсолютные пути в ссылках.

## Когда отказаться

- Просят добавить `///` в `.cs` — это `doc-cs`, переключайся.
- Просят описать схему БД из SQL-кода — это `doc-db`, переключайся.
