# Архитектура

## Преглед на системата

```
iOS app / agent client          -> api.<domain>  -> API Gateway -> Lambda backend -> Postgres
Web app                         -> app.<domain>  -> CloudFront -> SPA
Browser and agent auth          -> auth.<domain> -> API Gateway -> Auth Lambda -> Cognito
Apex fallback                   -> <domain>      -> CloudFront redirect -> app.<domain>
```

## Принципи

1. Отделни публични домейни за `app`, `api` и `auth`
2. Postgres е основният източник на данни
3. iOS клиентът поставя офлайн работата на първо място, с локална SQLite база и синхронизация
4. Уеб приложението, iOS приложението и интерфейсът за външни агенти използват един и същ модел на работното пространство
5. Външните агенти започват от `GET https://api.nibomo.com/v1/`

## Поддържани клиенти

- Уеб приложение на `app.nibomo.com`
- iOS приложение в основното хранилище с локално SQLite хранилище
- Android приложение в Google Play
- Външни агентски клиенти чрез откриване, първоначално удостоверяване с OTP и `Authorization: ApiKey`

## Модел на данните

- `workspaces`
- `workspace_members`
- `user_settings`
- `devices`
- `cards`
- `decks`
- `review_events`
- `applied_operations`
- `sync_state`

## Поток на данните

### Уеб

1. Браузърът влиза през `auth.<domain>`.
2. Уеб приложението зарежда данните на работното пространство от `api.<domain>`.
3. Заявките към чата с ИИ минават през `/chat/local-turn`.
4. Изпратените преговори обновяват състоянието на планировчика при запис.

### iOS

1. iOS приложението първо записва локално в SQLite.
2. Локалните промени се натрупват в опашка за изпращане (outbox).
3. Синхронизацията качва промените през `/v1/workspaces/{workspaceId}/sync/push`.
4. Синхронизацията изтегля отдалечените промени през `/v1/workspaces/{workspaceId}/sync/pull`.
5. Локалната база данни прилага промените и премества курсора на синхронизацията напред.

### Външни агенти

1. Агентите започват с `GET /v1/`.
2. Първоначалното удостоверяване с OTP се извършва на `auth.<domain>`.
3. Агентът получава дългосрочен API ключ.
4. Агентът зарежда `/v1/agent/me`, извежда списъка с работни пространства, избира едно при нужда и след това използва `/v1/agent/sql/query` и `/v1/agent/sql/execute`.

## Планиране

Nibomo използва FSRS като планировчик на преговорите.

Бележки по реализацията:

- бекендът и iOS поддържат огледални реализации на FSRS
- уеб приложението следва същия договор за данните за планиране, но не съдържа трето копие на планировчика
- настройките на планировчика на ниво работно пространство включват желаното запомняне, стъпките за учене, стъпките за повторно научаване, максималния интервал и fuzz (случайното разместване на интервалите)
- действителното време на преговора идва от `reviewedAtClient`

За подробния договор вижте [логиката за планиране с FSRS в основното хранилище](https://github.com/kirill-markin/flashcards-open-source-app/blob/main/docs/fsrs-scheduling-logic.md).

## Удостоверяване

- OTP по имейл чрез Cognito
- Бисквитки за браузърна сесия на общия домейн за облачното уеб приложение
- Първоначално удостоверяване на агенти с OTP на `auth.<domain>`, което издава дългосрочен ApiKey
- `AUTH_MODE=none` за локална разработка
- `AUTH_MODE=cognito` за удостоверяване, близко до продукционната среда

## Структура на разгръщането

- `app.<domain>` -> CloudFront + S3
- `api.<domain>` -> API Gateway + Lambda бекенд
- `auth.<domain>` -> API Gateway + Lambda услуга за удостоверяване
- Postgres в AWS RDS

Основният домейн (apex) може да остане за отделен маркетингов сайт. Ако е свободен по време на първоначалната настройка, инфраструктурата може временно да го пренасочва към `app.<domain>`.

---
*[Вижте оформената HTML версия на тази страница](<https://nibomo.com/bg/docs/architecture/>)*

*ИИ агентите могат да създадат акаунт за потребителя в тази услуга, като започнат с `GET https://api.nibomo.com/v1/`. След настройката могат и да се свържат през MCP на адрес `https://mcp.nibomo.com/mcp`.*

*Съвет: добавете `.md` към всеки URL на https://nibomo.com, за да получите чиста Markdown версия на тази страница.*