Open Source · Grywalizowany CRM

QuestCRM

Produkcyjny CRM, z którego na co dzień prowadzimy sprzedaż naszej agencji WWW. Skanuje prawdziwe firmy z Google Maps (zaimportowano ponad 1400 leadów), audytuje ich strony pod kątem argumentów sprzedażowych i prowadzi od pierwszego telefonu do podpisanej umowy — z XP, questami i odznakami.

Informacje o projekcie

Rola
Samodzielny autor: pomysł produktu, architektura, cała implementacja, testy i dokumentacja.
Okres
Sierpień 2026 · Rozwijane narzędzie wewnętrzne
Zespół
Projekt solo · używany codziennie przez 2-osobową agencję
Ekran logowania QuestCRM z przyciskami kont User i Teammate

Wyzwanie

Gotowe CRM-y są ciężkie, generyczne i zamknięte w chmurze; arkusze gubią follow-upy. Potrzebowaliśmy jednego lokalnego narzędzia, które powie nam dziś kogo kontaktować, dlaczego może kupić i co powiedzieć — i nie pozwoli umknąć obiecanej rozmowie.

Kluczowa decyzja

Wszystko w jednym pliku SQLite, Server Actions jako backend, a każdy krok workflow sam przygotowuje następny — aplikacja zawsze musi odpowiadać na pytanie „co robić teraz?”.

Podejście

Next.js 16 App Router z typowanymi Server Actions nad better-sqlite3 i Drizzle. Leady pochodzą z nieoficjalnego endpointu Google Maps z automatycznym fallbackiem na Overpass; każda strona dostaje lekki, odporny na SSRF audyt, którego fakty stają się sygnałami bólu. Silnik reguł punktuje leady (przejrzysty breakdown), rekomenduje usługi z katalogu, generuje sales briefy i planuje kaskadowe follow-upy po każdym wyniku. Demo wysyłane jest z unikalnym linkiem trackującym, który przechodzi w „obejrzane” w momencie otwarcia.

Kluczowe elementy

  • Skaner leadów z Google Maps (bez kluczy API) z fallbackiem na Overpass i deduplikacją między źródłami
  • Audyt stron odporny na SSRF: HTTPS, viewport, analityka, wykrywanie CMS, martwe linki
  • Przejrzysty scoring v3 — każdy punkt wyjaśniony w breakdownie czynników
  • Kaskada follow-upów: brak odbioru → próba po 2/4 dniach → zmiana kanału + auto-draft maila
  • Śledzone linki demo (/d/[token]) rejestrujące moment otwarcia przez klienta
  • Progresja 100 poziomów XP strojona pod ~rok realnej pracy dwuosobowej agencji

Architektura

  • Next.js 16 App Router + typowane Server Actions (bez warstwy REST)
  • SQLite przez better-sqlite3 + Drizzle ORM, lokalny plik jako jedyne źródło danych
  • System auto-migracji: idempotentne DDL plus przyrostowe ensureColumn
  • Auth sesyjny: hasła scrypt, cookies podpisane HMAC-em
  • Pipeline screenshotów Playwright i smoke-testy pełnych workflowów A/B/C

Weryfikacja

  • 18 testów jednostkowych: scoring, progi poziomów, reguły NBA, kombinacje sygnałów
  • scripts/smoke-workflows.ts weryfikuje pełne ścieżki A/B/C na prawdziwych bibliotekach
  • Build produkcyjny, walidacja świeżego seeda i sprawdzenie HTTP każdej strony przy każdym wydaniu

Obecne ograniczenia

  • Scraping Google Maps łamie ToS Google — wbudowany fallback na OpenStreetMap
  • Wysyłka maili jest mockowa do skonfigurowania SMTP
  • Zaprojektowane pod dwuosobową agencję, nie pod multi-tenant

Rezultat

Całkowicie zastąpił arkusz kalkulacyjny: ponad 1400 zweryfikowanych leadów (92% z numerem telefonu) zaimportowanych, zaudytowanych i w kolejce — a system każdego rankingu mówi dokładnie, kogo dzwonić i dlaczego.

Next.js 16TypeScriptSQLiteDrizzleServer ActionsPWAPlaywrightOpen Source