Baraba: Завръщането на Джедая

Как една счетоводна система прерасна от експеримент в боен изтребител


В Началото: Nim-lang и първите стъпки

Всяка велика история започва с експеримент. Baraba не е изключение.

Първоначалната идея беше проста – създаване на модерна, бърза и елегантна счетоводна система за българския пазар. Изборът на технология падна върху Nim – език, който обещаваше скоростта на C с елегантността на Python.

# Първите редове код на Baraba (2024)
proc calculateVAT(amount: float, rate: float = 0.20): float =
  result = amount * rate

Nim беше интересен избор. Компилира се до C, изключително бърз е, има чист синтаксис. Но… реалността на production системите е различна от playground експериментите.

Какво научихме от Nim:

  • Екосистемата има значение – Nim има страхотен потенциал, но библиотеките за enterprise приложения са ограничени
  • Community support е критичен – когато нещо се счупи в 3 сутринта, искаш да намериш отговор в Stack Overflow
  • Web frameworks имат значение – Jester е добър, но не е Rails/Lucky/Phoenix

Не съжаляваме за времето с Nim. Той ни научи да мислим за performance от ден първи. Но беше време за еволюция.


Завръщането: Crystal + Leptos = Джедайски Изтребител

https://baraba.org

Ако Nim беше нашият X-Wing – надежден, но ограничен – то новият стек е Millennium Falcon с хипердрайв.

Backend: Crystal с Lucky Framework

# Същата VAT калкулация, но в production-ready система
class Api::Invoices::Calculate < ApiAction
  post "/api/invoices/calculate" do
    invoice = InvoiceQuery.new.find(params.get(:id))

    vat_amount = invoice.net_amount * invoice.vat_rate.percentage / 100

    json({
      net: invoice.net_amount,
      vat: vat_amount,
      gross: invoice.net_amount + vat_amount
    })
  end
end

Защо Crystal?

  • Ruby синтаксис, C скорост – пишеш като Ruby, изпълнява се като C
  • Type safety – компилаторът хваща грешките преди production
  • Lucky Framework – „Rails, но по-добре“ с вградена type safety
  • Avram ORM – най-безопасният ORM, който сме използвали

Crystal компилира до native binary. Няма VM, няма garbage collection pauses, няма „warming up“. Стартира и работи.

Frontend: Leptos + Rust/WASM

#[component]
pub fn InvoiceForm() -> impl IntoView {
    let (amount, set_amount) = create_signal(0.0);
    let vat = move || amount.get() * 0.20;

    view! {
        <input type="number"
               on:input=move |ev| set_amount(event_target_value(&ev).parse().unwrap_or(0.0))
        />
        <p>"ДДС: " {vat} " лв."</p>
    }
}

Защо Leptos + WASM?

  • Rust в браузъра – същата памет safety като backend
  • Fine-grained reactivity – само това, което се променя, се рендира
  • No virtual DOM – директни DOM манипулации, максимална скорост
  • 2.8MB WASM binary – целият frontend в един оптимизиран файл

Архитектура: Как всичко работи заедно

┌─────────────────────────────────────────────────────────────┐
│                        CADDY PROXY                          │
│                    (Auto HTTPS/TLS)                         │
│                     baraba.org:443                          │
└─────────────────┬───────────────────────┬───────────────────┘
                  │                       │
                  ▼                       ▼
┌─────────────────────────┐   ┌───────────────────────────────┐
│     FRONTEND            │   │         BACKEND               │
│  ┌───────────────────┐  │   │  ┌─────────────────────────┐  │
│  │   Leptos/WASM     │  │   │  │   Crystal/Lucky         │  │
│  │   ─────────────   │  │   │  │   ─────────────────     │  │
│  │   • Rust          │  │   │  │   • Type-safe API       │  │
│  │   • Reactive UI   │  │   │  │   • Avram ORM           │  │
│  │   • No JS bloat   │  │   │  │   • JWT Auth            │  │
│  └───────────────────┘  │   │  │   • SAF-T Export        │  │
│         nginx:80        │   │  └─────────────────────────┘  │
└─────────────────────────┘   │           :3000               │
                              └───────────────┬───────────────┘
                                              │
                                              ▼
                              ┌───────────────────────────────┐
                              │        POSTGRESQL 16          │
                              │  ┌─────────────────────────┐  │
                              │  │   • Companies           │  │
                              │  │   • Accounts            │  │
                              │  │   • Journal Entries     │  │
                              │  │   • SAF-T Nomenclatures │  │
                              │  │   • 60+ tables          │  │
                              │  └─────────────────────────┘  │
                              │     Block Storage Volume      │
                              └───────────────────────────────┘

Функционалности: Какво може Baraba

Основни модули

МодулОписание
СметкопланПълен български сметкоплан с връзка към SAF-T кодове
ДневникСчетоводни записи с автоматично балансиране
ФактуриИздаване, осчетоводяване, ДДС калкулации
КонтрагентиКлиенти и доставчици с VIES проверка
ДДСДневници за покупки/продажби, справки-декларации
ДМАДълготрайни материални активи с амортизации
СкладСтокови наличности, FIFO/LIFO/Average
SAF-TПълен експорт по българския стандарт

SAF-T Compliance

Baraba е изградена с мисъл за SAF-T (Standard Audit File for Tax) от самото начало:

  • 360 стандартни сметки от НАП номенклатурата
  • 48 данъчни кода за всички видове ДДС операции
  • 19 типа фактури по SAF-T стандарта
  • 83 мерни единици по ISO стандартите
  • 28 региона на България
  • Автоматичен XML експорт за НАП

Multi-tenant архитектура

┌──────────────────────────────────────────┐
│              Потребител                   │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐   │
│  │ Фирма 1 │  │ Фирма 2 │  │ Фирма 3 │   │
│  │ (Admin) │  │ (Счет.) │  │ (View)  │   │
│  └─────────┘  └─────────┘  └─────────┘   │
└──────────────────────────────────────────┘

Един потребител може да има достъп до множество фирми с различни роли:

  • Super Admin – пълен достъп до всичко
  • Admin – управление на фирмата
  • Счетоводител – счетоводни операции
  • Наблюдател – само четене

Техническа документация

Системни изисквания

Production:

  • Docker & Docker Compose
  • 2GB RAM минимум (4GB препоръчително)
  • 20GB дисково пространство
  • PostgreSQL 16

Development:

  • Crystal 1.17+
  • Rust nightly (за Leptos)
  • Node.js 18+ (за sass)
  • PostgreSQL 14+

API Endpoints

Автентикация

# Вход
POST /api/auth/signin
Content-Type: application/json

{
  "user": {
    "email": "user@example.com",
    "password": "secret"
  }
}

# Response
{
  "success": true,
  "token": "eyJ0eXAiOiJKV1Q...",
  "user": {
    "id": 1,
    "email": "user@example.com"
  }
}

Сметки

# Списък сметки
GET /api/companies/{id}/accounts
Authorization: Bearer {token}

# Създаване на сметка
POST /api/companies/{id}/accounts
{
  "code": "401",
  "name": "Доставчици",
  "saft_account_id": 123
}

Счетоводни записи

# Нов запис
POST /api/companies/{id}/journal_entries
{
  "date": "2026-02-01",
  "description": "Фактура №123",
  "lines": [
    {"account_id": 1, "debit": 1000.00},
    {"account_id": 2, "credit": 833.33},
    {"account_id": 3, "credit": 166.67}
  ]
}

SAF-T Export

# Генериране на SAF-T файл
POST /api/companies/{id}/saft/export
{
  "start_date": "2026-01-01",
  "end_date": "2026-12-31",
  "type": "full"  // или "monthly"
}

Database Schema (основни таблици)

-- Фирми
companies (
  id, name, eik, vat_number,
  address, city, country,
  currency, fiscal_year_start_month,
  owner_id, settings
)

-- Сметки (per company)
accounts (
  id, company_id, code, name,
  account_type, saft_account_id,
  parent_id, is_active
)

-- Счетоводни записи
journal_entries (
  id, company_id, entry_number, date,
  description, is_posted, user_id,
  counterpart_id, vat_period
)

-- Редове на записи
journal_lines (
  id, journal_entry_id, account_id,
  debit, credit, description
)

-- SAF-T сметки (глобални)
saft_accounts (
  id, code, name,
  section_code, section_name,
  group_code, group_name
)

Docker Deployment

# docker-compose.prod.yml
services:
  db:
    image: postgres:16-alpine
    volumes:
      - /mnt/block-storage/postgres:/var/lib/postgresql/data

  backend:
    build:
      context: .
      dockerfile: docker/backend.Dockerfile
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/baraba
      - LUCKY_ENV=production

  frontend:
    build:
      context: .
      dockerfile: docker/frontend.Dockerfile

Environment Variables

VariableDescriptionDefault
DATABASE_URLPostgreSQL connection stringrequired
SECRET_KEY_BASEJWT signing keyrequired
LUCKY_ENVEnvironment (development/production)development
PORTBackend port3000
APP_DOMAINApplication domainlocalhost
SEND_GRID_KEYSendGrid API key for emailsoptional

Performance Benchmarks

Тествано на VPS с 2 vCPU, 4GB RAM:

ОперацияВремеRPS
API Login15ms650
List Accounts8ms1200
Create Journal Entry12ms800
SAF-T Export (1000 entries)2.3s
Frontend Initial Load1.2s
WASM Binary Size2.8MB

Пътна карта

v1.1 (Q1 2026)

  • [ ] Интеграция с банкови API (Open Banking)
  • [ ] Автоматичен импорт на банкови извлечения
  • [ ] OCR сканиране на фактури

v1.2 (Q2 2026)

  • [ ] Мобилно приложение (Tauri + Leptos)
  • [ ] Офлайн режим с sync
  • [ ] Push notifications

v2.0 (Q3 2026)

  • [ ] AI асистент за осчетоводяване
  • [ ] Автоматично разпознаване на контрагенти
  • [ ] Предиктивни анализи

Заключение

Baraba не е просто счетоводен софтуер. Тя е доказателство, че можеш да изградиш enterprise-grade система с модерни технологии, без да жертваш производителност или developer experience.

От Nim до Crystal + Leptos, пътят беше дълъг, но си заслужаваше. Сега имаме система, която:

  • Стартира за милисекунди – native binary, без VM
  • Консумира минимум памет – ~50MB RAM в idle
  • Скалира хоризонтално – stateless backend
  • Отговаря на българските изисквания – SAF-T ready

Силата е с нас. И с вас, ако решите да пробвате.


Линкове:


Публикувано: Февруари 2026
Автор: Baraba Team

Вашият коментар