BusiKM — Architektura techniczna

Dokument opisuje architekturę systemu BusiKM — platformy do zarządzania ewidencją przebiegu pojazdów dla firm transportowych i biur rachunkowych.


1. Diagram architektury systemu

+---------------------+     +---------------------+
|   Aplikacja Mobile  |     |    Panel Webowy      |
|  (React Native /    |     |  (Next.js 14 /       |
|   Expo SDK 52+)     |     |   Vercel)            |
+----------+----------+     +----------+----------+
           |                           |
           |        HTTPS/WSS          |
           +----------+   +------------+
                      |   |
                      v   v
              +-------+---+--------+
              |   API Gateway /    |
              |   Daphne (ASGI)    |
              |   port 8000        |
              +--------+-----------+
                       |
          +------------+-------------+
          |                          |
          v                          v
+---------+----------+   +-----------+---------+
|  Django 5.x + DRF  |   |  Celery Workers     |
|  drf-spectacular    |   |  - default          |
|  RBAC / Middleware  |   |  - reports           |
+----+-----+----+----+   |  Celery Beat (cron) |
     |     |    |         +--+-------+----------+
     |     |    |            |       |
     v     v    v            v       v
+----+-+ +-+----+-+  +------+--+ +--+-------+
| PG16 | | Mongo7 |  | Redis 7 | | S3/MinIO |
| rel. | | GPS /  |  | cache   | | pliki    |
| data | | logi   |  | broker  | | PDF/img  |
+------+ +--------+  | blackl. | +----------+
                      +---------+

2. Stack technologiczny

WarstwaTechnologiaUzasadnienie
BackendDjango 5.x + DRFDojrzały ekosystem, ORM, migracje, wbudowany admin
API Docsdrf-spectacular (OpenAPI 3.0)Automatyczna dokumentacja, generowanie klienta TS
Async/WSDaphne (ASGI)WebSocket dla powiadomień w czasie rzeczywistym
Task QueueCelery + Celery BeatRaporty PDF, obliczenia dystansu, zadania cykliczne
MobileReact Native + Expo SDK 52+Jeden codebase iOS/Android, OTA updates, EAS Build
Routing (mob)Expo Router v4File-based routing, deep linking, typowane ścieżki
State (mob)ZustandLekki, minimalny boilerplate, kompatybilny z React Native
HTTP (mob)AxiosInterceptory, automatyczny refresh tokenów
WebNext.js 14 App RouterSSR/SSG, React Server Components, optymalizacja SEO
CSSTailwind CSSUtility-first, szybki prototyping, brak CSS-in-JS runtime
Data (web)SWRCache-first fetching, rewalidacja, mutacje optymistyczne
WykresyRechartsDeklaratywne wykresy React, responsywność
MapyMapbox GLWizualizacja tras GPS, klastry, heatmapy
DB relacyjnaPostgreSQL 16ACID, partycjonowanie, full-text search, JSON support
DB dokumentowaMongoDB 7Dane GPS/logi — elastyczny schemat, geo-indeksy, time-series
Cache/BrokerRedis 7Cache sesji, broker Celery, blacklist JWT, kontekst AF
StorageS3 (DigitalOcean Spaces) / MinIOKompatybilność S3 API, MinIO lokalnie, Spaces na produkcji
MonitoringSentry + Prometheus + GrafanaBłędy (Sentry), metryki (Prometheus), dashboardy (Grafana)
UptimeUptime KumaMonitoring dostępności endpointów, alerty
CI/CDGitHub Actions + EAS Build + VercelAutomatyzacja buildów, deploymentów, testów

3. Backend (Django + DRF + Celery + Daphne)

3.1 Struktura projektu

backend/
  config/           # settings, urls, asgi/wsgi, celery
  apps/
    accounts/       # User, Company, Role, auth JWT
    vehicles/       # Vehicle, VehicleDocument
    trips/          # Trip, GPSPoint, DistanceCalculation
    reports/        # Report, PDFExport, ReportSchedule
    integrations/   # AbstractFKIntegration, providers
    notifications/  # WebSocket consumers, push
  core/             # mixins, permissions, generators, middleware

3.2 Django + DRF

  • Django 5.x — framework backendowy z ORM, migracjami i panelem admin.
  • DRF — serializatory, viewsety, paginacja (CursorPagination dla list GPS).
  • drf-spectacular — generowanie schematu OpenAPI 3.0, UI Swagger/Redoc.
  • Każdy viewset dziedziczy po CompanyScopedMixin (filtrowanie po firmie).
  • Uprawnienia oparte na RBAC z czterema rolami systemowymi.

3.3 Celery + Celery Beat

Trzy kolejki workerów:

WorkerKolejkaZadania
celery-defaultdefaultPowiadomienia, e-maile, integracje FK
celery-reportsreportsGenerowanie PDF (WeasyPrint), eksporty CSV/XLSX
celery-beat(scheduler)Raporty cykliczne, czyszczenie tokenów, backupy

3.4 Daphne (ASGI/WebSocket)

  • Daphne obsługuje połączenia WebSocket dla powiadomień real-time.
  • Django Channels z warstwami Redis jako channel layer.
  • Consumers: NotificationConsumer, TripTrackingConsumer.
  • Autentykacja WS przez token JWT w query string.

4. Mobile (React Native + Expo)

4.1 Architektura

mobile/
  app/                  # Expo Router v4 (file-based routing)
    (auth)/             # ekrany logowania/rejestracji
    (tabs)/             # główna nawigacja tabowa
      trips/            # lista/szczegóły przejazdów
      vehicles/         # zarządzanie pojazdami
      reports/          # raporty i eksporty
      settings/         # ustawienia profilu
  components/           # komponenty współdzielone
  stores/               # Zustand stores
  services/             # API client (Axios), GPS service
  hooks/                # custom hooks

4.2 Kluczowe mechanizmy

  • Expo SDK 52+ z prebuildowanymi modułami natywnymi.
  • Expo Router v4 — nawigacja oparta na plikach, typowane parametry tras.
  • Zustand — stan globalny: useAuthStore, useTripStore, useSettingsStore.
  • Axios z interceptorami — automatyczny refresh JWT, retry na 401.
  • expo-location — śledzenie GPS w tle (background location tracking).
  • expo-task-manager — zadania w tle dla rejestracji punktów GPS.
  • EAS Build — natywne buildy iOS/Android w chmurze.
  • OTA Updates — aktualizacje JS bez przechodzenia przez App Store.

5. Web (Next.js 14)

5.1 Architektura

web/
  app/
    (auth)/             # logowanie, rejestracja
    (dashboard)/        # panel główny
      trips/            # przejazdy — tabela, filtry, mapa
      vehicles/         # flota pojazdów
      reports/          # raporty z wykresami (Recharts)
      company/          # ustawienia firmy, użytkownicy
      integrations/     # konfiguracja FK
    api/                # route handlers (proxy/BFF)
  components/           # shadcn/ui + komponenty własne
  lib/                  # API client, utilities, hooks

5.2 Kluczowe mechanizmy

  • App Router — React Server Components, streaming, Suspense.
  • SWR — fetching danych z automatyczną rewalidacją i cache.
  • Tailwind CSS — utility-first styling, ciemny motyw, responsywność.
  • Recharts — wykresy: przebieg miesięczny, koszty, porównania pojazdów.
  • Mapbox GL — wizualizacja tras na mapie, heatmapy intensywności.
  • Generowany klient API (orval) — typowany, zsynchronizowany ze schematem OpenAPI.

6. Strategia bazodanowa

6.1 Rozdzielenie odpowiedzialności

+------------------+    +------------------+    +------------------+
|  PostgreSQL 16   |    |   MongoDB 7      |    |    Redis 7       |
+------------------+    +------------------+    +------------------+
| - Użytkownicy    |    | - Punkty GPS     |    | - Cache sesji    |
| - Firmy          |    | - Logi aktywności|    | - Broker Celery  |
| - Pojazdy        |    | - Surowe dane    |    | - JWT blacklist  |
| - Przejazdy      |    |   telemetryczne  |    | - Kontekst AF    |
| - Raporty        |    | - Audyt zmian    |    | - Rate limiting  |
| - Integracje FK  |    |                  |    | - Channel layer  |
| - Uprawnienia    |    |                  |    |   (WebSocket)    |
+------------------+    +------------------+    +------------------+
    ACID / ORM             Geo-indeksy            TTL / Pub-Sub
    Migracje               Time-series            In-memory

6.2 Przepływ danych GPS

Telefon (GPS)
     |
     v
POST /api/trips/{id}/gps-points/
     |
     v
Django (walidacja, serializacja)
     |
     +---> MongoDB (zapis surowych punktów GPS)
     |
     v
Celery task: calculate_distance
     |
     +---> Odczyt punktów z MongoDB
     |     Algorytm: Haversine + filtr Kalmana
     |
     +---> PostgreSQL (update Trip.distance_km)
     |
     +---> WebSocket: powiadomienie o aktualizacji

7. Storage (S3 / MinIO)

  • Produkcja: DigitalOcean Spaces (kompatybilne z S3 API).
  • Lokal/dev: MinIO w kontenerze Docker.
  • django-storages — jednolity interfejs default_file_storage.

Przechowywane obiekty:

Bucket / prefixZawartość
media/avatars/Zdjęcia profilowe użytkowników
media/documents/Skany dokumentów pojazdów
reports/pdf/Wygenerowane raporty PDF
reports/csv/Eksporty CSV/XLSX
backups/Kopie zapasowe baz danych

Pliki są podpisywane (presigned URLs) z TTL 15 minut.


8. Wzorce architektoniczne

8.1 RBAC — Role-Based Access Control

Cztery role systemowe:

RolaOpisUprawnienia
driverKierowcaCRUD własnych przejazdów, odczyt auta
ownerWłaściciel firmyPełny dostęp do zasobów firmy
accountantKsięgowy wewnętrznyRaporty, przejazdy, pojazdy (RO)
accounting_firmBiuro rachunkoweDostęp do wielu firm klientów

Implementacja: custom permission classes DRF (IsDriver, IsOwner, IsAccountant, IsAccountingFirm) + dekoratory na viewsetach.

8.2 CompanyScopedMixin

class CompanyScopedMixin:
    """Automatyczne filtrowanie querysetu po firmie użytkownika."""

    def get_queryset(self):
        qs = super().get_queryset()
        return qs.filter(company=self.request.user.active_company)

Każdy viewset operujący na danych firmowych dziedziczy po tym mixinie. Eliminuje ryzyko wycieku danych między firmami (tenant isolation).

8.3 TenantContextMiddleware

Middleware dla roli accounting_firm — biuro rachunkowe obsługujące wielu klientów.

class TenantContextMiddleware:
    """Przełączanie kontekstu firmy dla biur rachunkowych."""

    def __call__(self, request):
        if request.user.role == 'accounting_firm':
            company_id = request.headers.get('X-Company-Context')
            # Walidacja: czy AF ma dostęp do tej firmy
            request.user.active_company = self._resolve(company_id)
        # Kontekst przechowywany w Redis (TTL 8h)

8.4 AbstractFKIntegration

Wzorzec Strategy dla integracji z systemami FK (finansowo-księgowymi).

class AbstractFKIntegration(ABC):
    """Bazowa klasa dla integracji z systemami FK."""

    @abstractmethod
    def export_trips(self, trips, format): ...

    @abstractmethod
    def sync_vehicles(self, company): ...

    @abstractmethod
    def generate_ewidencja(self, month, year): ...

# Konkretne implementacje:
class OptimaPKIntegration(AbstractFKIntegration): ...
class SymfoniaIntegration(AbstractFKIntegration): ...
class WFirmaIntegration(AbstractFKIntegration): ...

8.5 BasePDFGenerator

Generowanie dokumentów PDF z polskimi fontami.

class BasePDFGenerator:
    """WeasyPrint HTML -> PDF z fontami Noto Sans."""

    template_name: str
    font_family = 'Noto Sans'  # pełne wsparcie polskich znaków

    def generate(self, context) -> bytes:
        html = render_to_string(self.template_name, context)
        return weasyprint.HTML(string=html).write_pdf()

# Użycie:
class TripReportPDF(BasePDFGenerator):
    template_name = 'reports/trip_report.html'

9. API-first (OpenAPI → generowany klient)

9.1 Pipeline

Django ViewSet + Serializer
         |
         v
drf-spectacular (schema generation)
         |
         v
/api/schema/ (OpenAPI 3.0 JSON/YAML)
         |
         v
orval (code generation)
         |
    +----+----+
    |         |
    v         v
 Mobile    Web
 (Axios)   (SWR/fetch)
 typed     typed
 client    client

9.2 Zasady

  • Schema generowana automatycznie z serializatorów i viewsetów DRF.
  • orval generuje typowanego klienta TypeScript z hookami SWR (web) i funkcjami Axios (mobile).
  • Każda zmiana API wymaga aktualizacji schematu i regeneracji klienta.
  • CI sprawdza, czy wygenerowany klient jest aktualny (orval --check).

10. Git flow i branching strategy

10.1 Diagram przepływu

feature/*  ----+
bugfix/*   ----|---> develop ---> staging ---> main
hotfix/*   ----+         |           |           |
                         |           |           |
                    auto-deploy  auto-deploy  manual
                    (dev env)    (QA env)     (prod)

10.2 Branche i ochrona

BranchDeployOchrona
feature/*PR do develop
developdev (auto)1 approve
stagingstaging (auto)1 approve + CI green
mainprod (manual)2 approves + CI green

10.3 Konwencja commitów

feat(trips): dodaj filtrowanie przejazdów po dacie
fix(auth): napraw refresh token rotation
docs(api): zaktualizuj schemę OpenAPI
chore(ci): dodaj krok lintowania w pipeline

Format: <type>(<scope>): <opis> (Conventional Commits).


11. Infrastruktura

11.1 Docker Compose (lokalne środowisko)

services:                   # 10+ kontenerów
  web:                      # Django + Daphne (ASGI)
  celery:                   # Worker - default queue
  celery-beat:              # Scheduler periodycznych tasków
  celery-reports:           # Worker - reports queue (WeasyPrint)
  postgres:                 # PostgreSQL 16
  redis:                    # Redis 7
  mongo:                    # MongoDB 7
  minio:                    # S3-compatible storage (lokal)
  prometheus:               # Zbieranie metryk
  grafana:                  # Dashboardy monitoringu

11.2 CI/CD Pipeline

git push (feature branch)
     |
     v
GitHub Actions
     |
     +---> Lint (ruff, eslint, prettier)
     |---> Testy (pytest, jest, detox)
     |---> Build schema OpenAPI
     |---> Sprawdź wygenerowanego klienta
     |
     v
Merge do develop/staging
     |
     +---> Docker build + push (GHCR)
     |---> Deploy na środowisko (auto)
     |
     v
Merge do main (manual approval)
     |
     +---> Deploy produkcyjny
     |---> EAS Build (mobile — App Store / Google Play)
     |---> Vercel deploy (web)

11.3 Diagram autentykacji JWT

Klient                    API                    Redis
  |                        |                       |
  |-- POST /auth/login --> |                       |
  |                        |-- weryfikacja ------> |
  |<-- access + refresh -- |                       |
  |                        |                       |
  |-- GET /api/trips ----> |                       |
  |   (Authorization:      |                       |
  |    Bearer <access>)    |-- sprawdź blacklist ->|
  |                        |<- OK ----------------|
  |<-- 200 dane ---------- |                       |
  |                        |                       |
  |-- POST /auth/refresh ->|                       |
  |   (refresh token)      |-- blacklist stary --->|
  |                        |<- zapisano -----------|
  |<-- nowy access --------| (rotation)            |
  |    + nowy refresh      |                       |

12. Konwencje kodu

12.1 Backend (Python)

  • Formatter: ruff format (kompatybilny z Black).
  • Linter: ruff check z zestawem reguł (pyflakes, isort, pep8-naming).
  • Testy: pytest + factory_boy + faker. Pokrycie minimum 80%.
  • Nazewnictwo: snake_case dla modułów/funkcji, PascalCase dla klas.
  • Docstringi: Google style na publicznych metodach.
  • Type hints: wymagane w sygnaturach funkcji.

12.2 Mobile (TypeScript / React Native)

  • Formatter/Linter: ESLint + Prettier.
  • Testy: Jest (unit) + Detox (E2E).
  • Nazewnictwo: camelCase dla zmiennych/funkcji, PascalCase dla komponentów.
  • Komponenty: funkcyjne z hookami, brak klas.
  • Stan: Zustand stores w dedykowanych plikach (stores/).

12.3 Web (TypeScript / Next.js)

  • Formatter/Linter: ESLint + Prettier + eslint-plugin-tailwindcss.
  • Testy: Jest/Vitest (unit), Playwright (E2E).
  • Komponenty: React Server Components domyślnie, 'use client' tylko gdy potrzebne.
  • Styling: Tailwind utility classes, brak inline styles.
  • Importy: aliasy ścieżkowe (@/components, @/lib).

12.4 Wspólne zasady

  • Każdy PR musi przejść review i CI przed merge.
  • Brak commitów bezpośrednio na develop, staging, main.
  • Zmienne środowiskowe w .env (nigdy w kodzie).
  • Sekrety w GitHub Secrets / Doppler.
  • Logowanie strukturalne (JSON) na produkcji.

Ostatnia aktualizacja: 15 kwietnia 2026