Powrót do strony głównej

Śledzik zdarzeń dla MVP na Django i SQLite: szybka analityka

Artykuł opisuje tworzenie minimalistycznego śledzika zdarzeń dla MVP na Django i SQLite. Rozwiązanie pozwala szybko zbierać kluczowe metryki za pomocą piksela, oszczędzając czas i zasoby na starcie projektu. Podano przykłady kodu dla backendu i frontendu na Next.js.

Lekki śledzik zdarzeń: Django + SQLite dla szybkiego MVP
Advertisement 728x90

Minimalistyczny tracker zdarzeń dla MVP: Django, SQLite i piksel

Przy uruchamianiu MVP kluczowe jest szybkie i bez zbędnych kosztów sprawdzenie kluczowych działań użytkowników. Zamiast podłączania ciężkich systemów analitycznych, można wdrożyć lekki backend Django, który przez piksel zbiera zdarzenia i przechowuje je w SQLite. Takie podejście oszczędza czas, nie wymaga skomplikowanej infrastruktury i pozwala skupić się na weryfikacji hipotezy.

Architektura prostego trackera zdarzeń

Rozwiązanie buduje się wokół minimalistycznego backendu, który raz wdrożony na hostingu obsługuje wiele frontendów. Frontend wysyła żądanie GET na endpoint /t.gif z parametrami zdarzenia i źródła. Backend atomowo zwiększa licznik w bazie danych. Do przeglądania statystyk używa się zamkniętego endpointu /api/stats, zwracającego dane w formacie JSON.

Kluczowe komponenty systemu:

Google AdInline article slot
  • Frontend: Wywołuje track(event, src) przez utworzenie obiektu Image.
  • Backend (Django): Przetwarza żądanie, aktualizuje licznik w SQLite.
  • Baza danych: Jedna tabela z polami event, src, count, updated_at.
  • API statystyk: Dostęp po kluczu, zwraca zagregowane dane.

Taki tracker jest szczególnie wygodny dla projektów na darmowych hostingach, gdzie system plików jest efemeryczny, a usługi przechodzą w tryb uśpienia po bezczynności.

Implementacja w Django i SQLite

Model danych jest niezwykle prosty i używa unikalnego indeksu dla pary event i src.

# tracker/models.py
from django.db import models

class Counter(models.Model):
    event = models.CharField(max_length=120)
    src = models.CharField(max_length=120, blank=True, default="")
    count = models.PositiveBigIntegerField(default=0)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ("event", "src")

    def __str__(self) -> str:
        return f"{self.src}:{self.event}={self.count}"

Endpoint do zapisu zdarzenia używa piksela o rozmiarze 1×1, zakodowanego w base64. Pozwala to uniknąć problemów z CORS i nie wymaga dodatkowych bibliotek klienckich.

Google AdInline article slot
# tracker/views.py
import base64

from django.conf import settings
from django.db import transaction
from django.db.models import F
from django.http import HttpResponse, JsonResponse
from django.views.decorators.http import require_GET

from .models import Counter

_GIF_1x1 = base64.b64decode(
    "R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
)

@require_GET
def pixel(request):
    event = _clean(request.GET.get("e", ""), 120)
    src = _clean(request.GET.get("src", ""), 120)

    if not event:
        return _gif_response()

    with transaction.atomic():
        obj, created = Counter.objects.get_or_create(event=event, src=src)

        if created:
            obj.count = 1
            obj.save(update_fields=["count"])
        else:
            Counter.objects.filter(pk=obj.pk).update(count=F("count") + 1)

    return _gif_response()

Atomowa aktualizacja przez F("count") + 1 gwarantuje poprawność danych przy równoległych żądaniach. Endpoint statystyk filtruje dane według zdarzenia i źródła, jeśli parametry są przekazane.

Integracja z frontendem w Next.js

Po stronie klienta używa się uniwersalnego pomocnika, który można przenosić między projektami bez zmian.

// src/utils/track.ts
const TRACK_BASE = "https://your-domain.com/t.gif";

export const track = (event: string, src: string) => {
  const img = new Image();
  img.src =
    `${TRACK_BASE}?` +
    `e=${encodeURIComponent(event)}` +
    `&src=${encodeURIComponent(src)}` +
    `&t=${Date.now()}`;
};

Przykład użycia w komponencie Next.js do śledzenia kliknięcia przycisku tworzenia projektu:

Google AdInline article slot
// src/app/_ui/HomePageClient.tsx
"use client";

import { useRouter } from "next/navigation";
import { track } from "@/utils/track";

export default function HomePageClient() {
  const router = useRouter();

  return (
    <section className="mt-8 space-y-2">
      <div
        className="app-card app-card--soft cursor-pointer hover:border-slate-500/70 hover:bg-white/5 transition-colors"
        role="button"
        tabIndex={0}
        onClick={() => {
          router.push("/demo");
          track("create_project_click", "demo_project");
        }}
      >
        Stwórz projekt
      </div>
    </section>
  );
}

Po tym statystyki można przeglądać, wysyłając żądanie GET na /api/stats z kluczem autoryzacji. Odpowiedź zawiera listę zdarzeń z liczbą wywołań i czasem ostatniej aktualizacji.

Zalety i ograniczenia podejścia

Użycie lekkiego trackera dla MVP daje kilka praktycznych zalet:

  • Szybka weryfikacja hipotez: Skupienie na jednym kluczowym działaniu zamiast wielu metryk.
  • Oszczędność zasobów: Nie wymaga ciężkich systemów analitycznych i oddzielnych baz danych.
  • Uniwersalność: Jeden backend obsługuje wiele frontendów i projektów.
  • Proste wdrożenie: Minimalne wymagania hostingu, nadaje się do darmowych planów.

Jednak podejście ma naturalne ograniczenia:

  • Brak śledzenia unikalnych użytkowników i sesji.
  • Brak lejek, retencji i segmentacji.
  • Brak wsparcia dla testów A/B i skomplikowanych raportów analitycznych.

Te funkcje stają się niezbędne na późniejszych etapach rozwoju produktu, gdy MVP udowodniło swoją żywotność.

Co jest ważne

  • Jedna metryka lepsza niż dwadzieścia: Dla MVP kluczowe jest skupienie się na jednym kluczowym działaniu, które weryfikuje główną hipotezę.
  • Minimalna infrastruktura: Użycie SQLite i piksela pozwala uniknąć komplikacji z wdrożeniem i utrzymaniem.
  • Atomowość operacji: Aktualizacja licznika przez F("count") + 1 gwarantuje poprawność danych przy wysokim obciążeniu.
  • Uniwersalny pomocnik: Biblioteka kliencka z 10 linii kodu działa w każdym nowoczesnym frameworku frontendowym.
  • Szybki start: Rozwiązanie można wdrożyć w kilka godzin i od razu zacząć zbierać dane.

Taki tracker nie zastępuje pełnoprawnego systemu analitycznego, ale pozwala szybko i tanio uzyskać odpowiedź na główne pytanie: czy kluczowe działanie, dla którego tworzy się MVP, zachodzi. Jeśli zdarzenie nie występuje, problem leży raczej w samym produkcie, a nie w braku metryk.

— Editorial Team

Advertisement 728x90

Czytaj dalej