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

## Огляд системи

```
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-клієнт працює за принципом offline-first: локальна 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. Запити до AI-чату проходять через `/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
- Cookie браузерної сесії на спільному домені для хмарного вебзастосунку
- Початкове налаштування агента за 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

Кореневий домен може залишатися за окремим маркетинговим сайтом. Якщо під час початкового розгортання він вільний, інфраструктура може тимчасово перенаправляти його на `app.<domain>`.

---
*[Відкрити оформлену HTML\-версію цієї сторінки](<https://nibomo.com/uk/docs/architecture/>)*

*AI-агенти можуть створити акаунт користувача в цьому сервісі, почавши з `GET https://api.nibomo.com/v1/`. Після налаштування вони також можуть підключитися по MCP за адресою `https://mcp.nibomo.com/mcp`.*

*Порада: додайте `.md` до будь-якого URL на https://nibomo.com, щоб отримати чисту Markdown-версію сторінки.*