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
| Warstwa | Technologia | Uzasadnienie |
|---|---|---|
| Backend | Django 5.x + DRF | Dojrzały ekosystem, ORM, migracje, wbudowany admin |
| API Docs | drf-spectacular (OpenAPI 3.0) | Automatyczna dokumentacja, generowanie klienta TS |
| Async/WS | Daphne (ASGI) | WebSocket dla powiadomień w czasie rzeczywistym |
| Task Queue | Celery + Celery Beat | Raporty PDF, obliczenia dystansu, zadania cykliczne |
| Mobile | React Native + Expo SDK 52+ | Jeden codebase iOS/Android, OTA updates, EAS Build |
| Routing (mob) | Expo Router v4 | File-based routing, deep linking, typowane ścieżki |
| State (mob) | Zustand | Lekki, minimalny boilerplate, kompatybilny z React Native |
| HTTP (mob) | Axios | Interceptory, automatyczny refresh tokenów |
| Web | Next.js 14 App Router | SSR/SSG, React Server Components, optymalizacja SEO |
| CSS | Tailwind CSS | Utility-first, szybki prototyping, brak CSS-in-JS runtime |
| Data (web) | SWR | Cache-first fetching, rewalidacja, mutacje optymistyczne |
| Wykresy | Recharts | Deklaratywne wykresy React, responsywność |
| Mapy | Mapbox GL | Wizualizacja tras GPS, klastry, heatmapy |
| DB relacyjna | PostgreSQL 16 | ACID, partycjonowanie, full-text search, JSON support |
| DB dokumentowa | MongoDB 7 | Dane GPS/logi — elastyczny schemat, geo-indeksy, time-series |
| Cache/Broker | Redis 7 | Cache sesji, broker Celery, blacklist JWT, kontekst AF |
| Storage | S3 (DigitalOcean Spaces) / MinIO | Kompatybilność S3 API, MinIO lokalnie, Spaces na produkcji |
| Monitoring | Sentry + Prometheus + Grafana | Błędy (Sentry), metryki (Prometheus), dashboardy (Grafana) |
| Uptime | Uptime Kuma | Monitoring dostępności endpointów, alerty |
| CI/CD | GitHub Actions + EAS Build + Vercel | Automatyzacja 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
RBACz czterema rolami systemowymi.
3.3 Celery + Celery Beat
Trzy kolejki workerów:
| Worker | Kolejka | Zadania |
|---|---|---|
| celery-default | default | Powiadomienia, e-maile, integracje FK |
| celery-reports | reports | Generowanie 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 / prefix | Zawartość |
|---|---|
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:
| Rola | Opis | Uprawnienia |
|---|---|---|
driver | Kierowca | CRUD własnych przejazdów, odczyt auta |
owner | Właściciel firmy | Pełny dostęp do zasobów firmy |
accountant | Księgowy wewnętrzny | Raporty, przejazdy, pojazdy (RO) |
accounting_firm | Biuro rachunkowe | Dostę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.
orvalgeneruje 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
| Branch | Deploy | Ochrona |
|---|---|---|
feature/* | — | PR do develop |
develop | dev (auto) | 1 approve |
staging | staging (auto) | 1 approve + CI green |
main | prod (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 checkz 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