> For the complete documentation index, see [llms.txt](https://docs.podkrepi.bg/general/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.podkrepi.bg/general/architecture/api.md).

# Технически изисквания

## Въведение

Изисквания към техническата разработка на проекта с отворен код Подкрепи.бг.

## Обхват

Да се създаде **безплатна** и **напълно прозрачна** онлайн платформа за дарения, която да може да се използва свободно от граждани и организации.

## Изисквания

### Публичност

* Кодът на Проекта трябва да е публичен и това да не компрометира сигурността;
* Да има публична и лична част на платформата;
* Всеки да може да се регистрира с популярни социални платформи (Google, Facebook);
* Дарителите да имат възможност да останат анонимни, ако желаят;
* Всички работни пароли трябва да се намират извън кода на Проекта.

### Разработка от доброволци

* Да има добра документация:
  * на архитектурата;
  * на връзките между компонентите;
  * на API ниво чрез swagger или подобни инструменти.
* Да се използват разпространени технологии и работни рамки (frameworks);
* Да се използва език със стриктно типизиране;
* Да поддържа бърза разработка на стандартни функционалности;
* Да може да се стартира целият Проект локално, без голямо натоварване и сложност;
* Да има безопасни за разработка среди (dev, staging);
* Да има автоматично:
  * проверка на стила на кода;
  * тестване при създаване на pull request;
  * създаване на контейнери;
  * качване на кода към различните среди.

### **Споделеност**

* По възможност, да се преизползват общи:
  * правила за валидация на frontend и backend;
  * типове на данните;
  * константни стойности;
  * преводи;
  * функционалности.
* По възможност, да се използва един и същи език за програмиране.

### Сигурност

* Да се избягват директни външни промени по базата данни;
* Всеки потребител да има достъп само до своите данни;
* Да има автоматични тестове, които потвърждават липсата на изтичане на данни;
* Всички заявки за включване на код да минават през код ревю процес, включващ повече от един технически координатор.

### Одит и прозрачност

* Всяка промяна на базата данни да се записва;
* Всяко качване или изтриване на файл да се записва;
* Да има вътрешни статистики за употребата на платформата;
* Да се пазят статистиките за определено време;
* Да има скалиране на системата за одит при повишаване на трафика.

### Хранилище за файлове

* Потребителите да имат достъп само до своите и споделените им файлове;
* Потребителите да могат да свалят всичките си файлове при желание (GDPR);
* Да има автоматично резервно копие на файловете във външна за платформата среда.

### Бази данни

* Да се използва установена и стабилна база данни;
* Да се използват миграции на базата данни;
* Да се използват отделни потребители с ограничени права за различни нужди;
* Да се използват общи типове на данните за тип на колоните (домейн, тип);
* Да се използва row level security (RLS), при възможност.

### Инфраструктура

* Да бъде подходящо оразмерена спрямо нуждите на платформата;
* Да поддържа платформата в добро общо състояние;
* Да има добра видимост над натоварването на платформата;
* Да разпределя трафика към различните модули;
* Да бъде осигурена с контрол на достъпа;
* При възможност, да поддържа автоматично скалиране, при повече трафик.

### Възстановяване след бедствие

* Да се съхранява кодът за възстановяване на системата (manifests);
* Да се извършват автоматични резервни копия на базата данни;
* Да се извършват автоматични резервни копия на хранилището за файлове;
* Да има ясна процедура по възстановяване на резервни копия.

### Злоупотреба и атаки

* Да се въведат рейт лимити на входящите заявки;
* Да се използват системи за превенция на DDoS атаки;
* Да има мрежови ограничения за намаляване рисковете от злоупотреби;
* Базите данни да не са достъпни извън Системата;
* Да има валидация на входящите данни на всеки слой.

## Възможни варианти

### Frontend

* TypeScript:
  * [React](https://reactjs.org/)
  * [Next.js](https://nextjs.org/)
* Графична библиотека:
  * [MaterialUI](https://material-ui.com/)

### Backend

* Основен транспорт на данни:
  * REST:
    * [Swagger](https://swagger.io/)
* Работна рамка:
  * TypeScript:
    * [https://nextjs.org/docs/api-routes](https://nextjs.org/docs/api-routes/introduction) (интегриран с фронтенд)
    * <https://nestjs.com/>
    * <https://expressjs.com/>
  * DB driven:
    * [https://postgrest.org/](https://postgrest.org/en/v8.0/)
* База данни:
  * Postgres
  * ORM:
    * <https://www.prisma.io/>
  * Миграции:
    * [Prisma migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate)

### Инфраструктура

* Kubernetes:
  * Управляван от доставчика на облачни услуги
  * On premise
* Docker-compose (локално):
  * On premise

## Какво имаме разработено до момента?

От възможните работни рамки, базирани на TypeScript, най-подходяща се оказа [**NestJS**](https://nestjs.com/)**.**

Бяха взети предвид следните съображения:

* общност на Проекта (<https://github.com/nestjs/nest> 40k ⭐);
* документация;
* примерни проекти;
* транспортни слоеве:
  * [REST](https://docs.nestjs.com/controllers)
  * [GraphQL](https://docs.nestjs.com/graphql/quick-start)
  * [Websocket](https://docs.nestjs.com/websockets/gateways)
* включени стандартни компоненти:
  * [модулярност](https://docs.nestjs.com/modules)
  * сигурност:
    * [валидация](https://docs.nestjs.com/techniques/validation)
    * [автентификация](https://docs.nestjs.com/security/authentication)
    * [оторизация](https://docs.nestjs.com/security/authorization)
    * [rate limiting](https://docs.nestjs.com/security/rate-limiting)
  * [кеширане](https://docs.nestjs.com/techniques/caching)
  * [автоматични тестове](https://docs.nestjs.com/fundamentals/testing)
  * oбработка на грешки
* външни интеграции, които можем да използваме:
  * [Prisma](https://docs.nestjs.com/recipes/prisma)
  * [Swagger](https://docs.nestjs.com/openapi/introduction)
  * [Keycloak](https://github.com/ferrerojosh/nest-keycloak-connect)
  * [Stripe](https://github.com/golevelup/nestjs/tree/master/packages/stripe)
  * [Sentry](https://github.com/ntegral/nestjs-sentry)

### Една база данни

Използвайки **една база** и **една схема,** вместо отделни, ние даваме възможност да се изгради начална работеща версия на приложението, без излишни технически препятствия. Когато се намери подходящ сценарий, който изисква отделни схеми и бази, той ще бъде имплементиран.

Подходящо решение, което да ни позволи бързо действие и еднотипни промени по базата, е [Prisma](https://prisma.io/), свързана с [PostgreSQL](https://www.postgresql.org/).

Чрез това решение ние:

* ще намалим времето за разписване на схемата на базата;
* ще се подсигурим, че връзките между обектите са в синхрон;
* ще генерираме типове за обектите в базата автоматично;
* ще генерираме миграционни скриптове автоматично.

Разбира се, това решение, както и всички останали, би имало недостатъци:

* притежава [познати ограничения](https://www.prisma.io/docs/about/prisma/limitations);
* не можем да използваме абсолютно всичко, което [базата поддържа](https://www.prisma.io/docs/concepts/components/prisma-migrate/prisma-migrate-limitations-issues).

##
