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

## Въведение

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

## Обхват

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

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

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

* Кодът на Проекта трябва да е публичен и това да не компрометира сигурността;
* Да има публична и лична част на платформата;
* Всеки да може да се регистрира с популярни социални платформи (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).

##


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.podkrepi.bg/general/architecture/api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
