# Код провайдера меняется на сессию вызовом собственного адреса хранилища внутри процесса

- **Дата:** 2026-08-12
- **Источник:** [../../openspec/changes/archive/2026-08-12-oidc-login/design.md](../../openspec/changes/archive/2026-08-12-oidc-login/design.md),
  раздел «Вход и возврат ведёт наш код, разбор ответа — хранилище»
- **Статус:** заменено на [ADR-2026-08-22-login-by-trusted-header](ADR-2026-08-22-login-by-trusted-header.md)

## Решение

Обработчик возврата от провайдера зовёт **собственный адрес хранилища**
`auth-with-oauth2` внутри процесса, через его же роутер, а не по сети и не
разбирая ответ провайдера своими руками.

## Почему

Решение [ADR-2026-08-11-pocketbase-storage-with-admin-panel](ADR-2026-08-11-pocketbase-storage-with-admin-panel.md)
отдало разбор ответа провайдера хранилищу: только тогда учётные записи заводятся
сами и видны в панели. Это решение не пересматривается — пересматривается способ
до него дотянуться.

Проверка исходников библиотеки версии 0.39.10 показала, что обмен наружу не
экспортирован: он живёт неэкспортированной функцией за собственным маршрутом.
Остались три формы, и владелец выбрал первую:

> (а) внутрипроцессный вызов собственного маршрута `auth-with-oauth2`: решение
> 2026-08-11 соблюдено дословно, цена — петля «наш обработчик → наш роутер → наш
> обработчик», разбор JSON-ответа и потеря типизированной ошибки; (б) сборка
> обмена из экспортированных кусков с сохранением записи и связи через `app.Save`:
> прямой код без петли, цена — пересмотр решения 2026-08-11 отдельным ADR; (в)
> отложить вход до появления фронтенда.

Запись заводится как **намеренный отказ от очевидного подхода**: собрать обмен
своими руками выглядит проще и дешевле, и предложение вернётся, если причина не
записана.

## Последствия

- `+` разбор ответа провайдера, заведение учётной записи и связь её с внешним
  провайдером остаются за хранилищем — решение 2026-08-11 соблюдено дословно, а
  не «по духу».
- `+` наш код не знает ни одного поля ответа провайдера: обновление библиотеки
  под смену формата ответа доезжает само.
- `−` петля через собственный роутер: обработчик зовёт сервис, частью которого
  сам является. Это новый для проекта вид узла, и его придётся объяснять на
  каждом следующем изменении.
- `−` ответ разбирается текстом, типизированная ошибка теряется: причина отказа
  обмена доступна только кодом состояния.
- `−` роутер хранилища пришлось собирать **один раз** и держать полем: его
  сборка вешает обработчики на само приложение и без идентификатора, поэтому
  повторная не заменяет прежние. Ревью кода нашло это построенным путём —
  анонимный запрос копил обработчики без предела, а каждое сохранение задачи
  конвейером проходило по всем накопленным.
