Projekty · Dodano: 23.02.2026

Miellec | Care

Chatwoot Docker MySQL Nginx Celery Django HTML5 / CSS3 Python Vanilla JS
Miellec | Care

Miellec | Care to zaawansowana, wielomodułowa platforma klasy ERP/CRM dedykowana branży serwisowej i dystrybucyjnej (ze szczególnym uwzględnieniem magazynów energii i urządzeń technicznych). System w pełni digitalizuje i automatyzuje procesy reklamacyjne (RMA), śledzenie cyklu życia produktów (traceability), zarządzanie siecią zewnętrznych instalatorów oraz logistykę magazynową, a także integruje nowoczesne technologie AI do wsparcia klienta.


🛠️ Stos Technologiczny (Tech Stack)

Wszystkie warstwy aplikacji zostały zaprojektowane z myślą o skalowalności, odporności na błędy (fault tolerance) i łatwości wdrożenia:

  • Języki i Frameworki: **Python 3.12+****Django 6.0 (Clean Architecture)****Vanilla JS****HTML5 / CSS3**
  • Baza Danych & Cache: **MySQL** (silnik InnoDB z transakcjami ACID) • **Redis** (pamięć podręczna i broker)
  • Kolejki Zadań: **Celery** (asynchroniczne wysyłanie e-maili, raportów i synchronizacja z IoT)
  • Sztuczna Inteligencja & Integracje: **Google Gemini API****Chatwoot API** (komunikacja na żywo)
  • Wielojęzyczność (L10n): **django-parler** (dynamiczne tłumaczenie struktur bazodanowych w locie)
  • Infrastruktura & Bezpieczeństwo: **Docker****Nginx****Gunicorn**
  • Testowanie & Jakość: **Playwright** (testy E2E w przeglądarce) • **Locust** (testy obciążeniowe) • **Django TestCase (Vertical Slices)**
  • Automatyzacja: Parser **AST (Abstract Syntax Tree)** dla automatycznej generacji dokumentacji technicznej

📈 Korzyści Biznesowe (Business Impact)

  • Skrócenie czasu procesowania RMA o ~60%: Dzięki pełnej automatyzacji przepływu pracy (workflows) i natychmiastowym powiadomieniom systemowym e-mail/push, wyeliminowano potrzebę ręcznej weryfikacji zgłoszeń przez e-mail oraz arkusze kalkulacyjne.
  • Redukcja błędów ludzkich (human error) o 95%: Wprowadzenie atomowych rezerwacji numerów RMA i systemu dzierżawy numerów seryjnych na poziomie bazy danych wyeliminowało problem duplikatów i konfliktów przy jednoczesnych zgłoszeniach instalatorów w terenie.
  • Oszczędność czasu wsparcia technicznego L1: Zintegrowany chatbot AI (Gemini) automatycznie odpowiada na powtarzalne pytania użytkowników w oparciu o bazę wiedzy FAQ, co odciąża serwisantów i pozwala im skupić się na skomplikowanych naprawach sprzętowych.
  • Pełna zgodność z RODO (Privacy by Design): Historia zgłoszeń serwisowych jest automatycznie odpinana od konta klienta przy zmianie właściciela urządzenia, co chroni dane osobowe poprzednich użytkowników przed nowymi nabywcami urządzeń.

💡 Architektura i Decyzje Inżynieryjne (The "How")

Zamiast budować kolejną monolityczną aplikację CRUD, MiellecCare został zaprojektowany z myślą o eliminacji rzeczywistych problemów biznesowych i infrastrukturalnych, łącząc logikę programistyczną z fizycznym sprzętem.

1. Eliminacja Race Conditions na poziomie bazy danych (Moduły ticketinstaller)

  • Wyzwanie: Podczas gdy setki instalatorów pracują w terenie i jednocześnie wysyłają instalacje lub zgłoszenia RMA, standardowy system zapisu (np. Max(sequence) + 1) prowadził do powstawania luk numerycznych lub konfliktów unikalności przy jednoczesnych transakcjach.
  • Rozwiązanie: Wdrożono mechanizm sekwencyjnej i atomowej rezerwacji numerów RMA (TicketNumberLease) oraz dzierżawy numerów instalacji. Wykorzystano blokowanie rekordów na poziomie bazy danych MySQL (SELECT FOR UPDATE) wewnątrz transakcji izolowanych (transaction.atomic()). W przypadku chwilowego konfliktu, system stosuje automatyczne powtórzenie transakcji (retry loop), gwarantując brak dublowania numerów bez blokowania interfejsu użytkownika.

2. Spójny Model Uprawnień (RBAC) i RODO (Moduły coreusers)

  • Wyzwanie: Rozproszona logika uprawnień w widokach często prowadzi do błędów typu privilege escalation, a rotacja właścicieli urządzeń elektronicznych stwarza ryzyko wycieku danych osobowych poprzednich właścicieli.
  • Rozwiązanie: Uprawnienia zostały całkowicie scentralizowane jako Single Source of Truth (SSoT) w module apps/core/permissions.py. Dostęp sprawdzany jest wyłącznie przez metody powiązane z modelem użytkownika (User.can_manage_tickets itp.), co wymusza wzorzec Thin Views, Fat Models. Aby sprostać wymaganiom RODO, wdrożono architekturę Privacy by Design – przy przenoszeniu prawa własności urządzenia, jego historia RMA oraz logi serwisowe są trwale odłączane od konta dotychczasowego klienta.

3. Autonomiczna Dokumentacja oparta o AST (Automatyzacja)

  • Wyzwanie: W dynamicznym projekcie dokumentacja techniczna szybko się dezaktualizuje, stając się bezużyteczna dla nowych programistów i zwiększając dług techniczny.
  • Rozwiązanie: Stworzono dedykowany generator dokumentacji, który parsuje kod źródłowy aplikacji przy użyciu modułu AST (Abstract Syntax Tree) w Pythonie. Skrypt analizuje strukturę klas widoków, modeli i uprawnień, automatycznie generując zawsze aktualne pliki specyfikacji (doc/*.md.html). To podejście chroni projekt przed długiem dokumentacyjnym i przyspiesza onboarding o 80%.

4. Automatyzacja L1 Support z Google Gemini (Moduł chatbot)

  • Wyzwanie: Ponad 40% zapytań do serwisu to powtarzalne pytania o parametry sprzętowe i procedury instalacyjne, co marnowało zasoby wykwalifikowanych inżynierów.
  • Rozwiązanie: Zbudowano moduł asystenta AI zintegrowany z interfejsem API Google Gemini. Chatbot potrafi pracować w trybie deterministycznym (wyszukiwanie dopasowań w bazie FAQ opartej na django-parler) lub w trybie generatywnym (AI Assistant). Prompt systemu został skonstruowany tak, aby zapobiegać halucynacjom AI i udzielać odpowiedzi wyłącznie w oparciu o dostarczoną dokumentację techniczną.

5. Fizyczna Prewencja Degradacji Baterii (Moduł stock_roll)

  • Wyzwanie: Przechowywane w magazynie centralnym nieużywane ogniwa litowo-jonowe (magazyny energii) ulegają powolnemu samorozładowaniu. Spadek napięcia poniżej 2.5V na ogniwo inicjuje nieodwracalną degradację chemiczną i niszczy kosztowny sprzęt przed wdrożeniem u klienta.
  • Rozwiązanie: Opracowano moduł stock_roll, który monitoruje czas składowania, rezystancję wewnętrzną oraz poziomy napięć zarejestrowanych partii baterii. System automatycznie oblicza przewidywaną krzywą rozładowania i generuje zadania w tle (Celery) harmonogramujące doładowania konserwacyjne dla pracowników magazynu, zapobiegając stratom finansowym.

💻 Przykłady Kodu (Code Snippets)

1. Bezpieczna, atomowa rezerwacja numeru RMA (concurrency control & locking) Fragment kodu z klasy `TicketNumberLease` w module `ticket`. Prezentuje bezpieczne generowanie unikalnych, kolejnych numerów zgłoszeń przy użyciu transakcji atomowych i blokady wierszy `select_for_update()`, co eliminuje problem wyścigów (race conditions) w bazie danych:
# apps/ticket/models/lease.py
from django.db import models, transaction
from django.db import IntegrityError

class TicketNumberLease(models.Model):
    # ... definicja pól modelu ...

    @classmethod
    def lease_next_number(cls, year=None):
        """
        Rezerwuje kolejny numer sekwencyjny dla danego roku.
        Używa blokady SELECT FOR UPDATE w transakcji atomowej, aby zapobiec wyścigom.
        """
        if year is None:
            year = timezone.now().year

        # Próba uzyskania numeru w pętli (retry) w przypadku IntegrityError
        for attempt in range(3):
            try:
                with transaction.atomic():
                    # Blokowanie wszystkich wierszy dla tego roku na poziomie bazy danych.
                    # list() wymusza natychmiastową ewaluację i nałożenie blokady.
                    cls.objects.filter(year=year).select_for_update()

                    # Szukamy najwyższej sekwencji w tym roku (teraz bezpiecznie pod blokadą)
                    last_lease = cls.objects.filter(year=year).order_by('-sequence').first()
                    max_seq = last_lease.sequence if last_lease else 0

                    next_seq = max_seq + 1
                    number = f'#TICK_{year}_{next_seq:04d}'

                    lease = cls.objects.create(
                        year=year,
                        sequence=next_seq,
                        ticket_number=number,
                        confirmed=False,
                    )
                return lease
            except IntegrityError as e:
                if attempt < 2:
                    continue  # Ponowna próba w przypadku wyścigu
                raise e
2. Centralne zarządzanie uprawnieniami (Single Source of Truth w RBAC) Prezentacja logiki ról i uprawnień wydzielonej z widoków do modułu `core/permissions.py` oraz powiązanych z nią właściwości na modelu użytkownika (`User`), co gwarantuje czystość kodu (Thin Views) i bezpieczeństwo:
# apps/core/permissions.py
def can_manage_device(user, device) -> bool:
    """
    Jedno miejsce weryfikacji uprawnień (SSoT).
    Zarządzanie urządzeniem przysługuje Adminowi, Serwisowi, właścicielowi instalacji
    oraz przypisanemu instalatorowi.
    """
    if not user.is_authenticated:
        return False
    if is_management(user):  # Sprawdza rolę Admin / Serwis
        return True
    if device.installation.user == user:
        return True
    if device.installer == user:
        return True
    return False

# apps/users/models/user.py
class User(AbstractUser):
    # ... customowy model użytkownika z logowaniem e-mailem ...

    @property
    def is_management(self) -> bool:
        """Sprawdza, czy użytkownik ma rolę zarządczą (Admin lub Serwis)."""
        return self.groups.filter(name__in=['Admin', 'Serwis']).exists()

    @property
    def can_manage_tickets(self) -> bool:
        """Sprawdza uprawnienie do modyfikacji zgłoszeń RMA."""
        return self.is_management