Architektura — z czego składa się Fyndi#
Fyndi to cztery współpracujące części — aplikacja Android, API, strona www z panelem oraz serwer, który je obsługuje — plus treść dokumentacji trzymana w tym samym repozytorium.
Z czego składa się Fyndi#
Każda część ma jasno określoną rolę, dzięki czemu treść można zmieniać bez wydawania nowej wersji APK.
| Część | Technologia | Za co odpowiada |
|---|---|---|
| Aplikacja Android | Kotlin, Jetpack Compose, Mapbox, ARCore Geospatial | Mapa i pionek postaci, trasy, znajdźki, widok AR, nawigacja, powiadomienia, paczka offline, kreator postaci |
| API | Node.js, PostgreSQL w kontenerze | Konta i sesje, trasy i punkty, zaliczenia, znajdźki, paczki offline, obecność graczy, lobby, boty NPC, tokeny i nagrody, funkcje AI panelu, graf mózgu projektu |
| Strona www + panel | Statyczne HTML/CSS/JS z nginx | Landing, konto gracza, kreator postaci w przeglądarce oraz panel staff: przegląd, kreator treści, planowanie, media, modele 3D, generator postaci, wiki, tłumaczenia, wydania |
| Serwer | nginx z TLS, kontenery usług, OSRM | Serwowanie www i API, katalog treści (zdjęcia, audio, modele), mirror APK, routing pieszy i rowerowy dla całej Polski |
| Dokumentacja | Markdown w repozytorium i własny generator | Strony w wersji polskiej i angielskiej pod https://docs.fyndi.app |
Aplikacja, strona i panel to trzech klientów tego samego API. Nie ma między nimi pośrednika, który musiałby być aktualizowany razem z nimi.
Przepływ danych#
Aplikacja rozmawia z API po HTTPS i wymienia się danymi w formacie JSON. Źródłem prawdy jest serwer: telefon trzyma lokalny cache i kolejkę zdarzeń, żeby działać bez sieci, ale statystyki, zaliczenia i wygląd postaci żyją w bazie.
- Telefon pobiera treść (trasy, punkty, znajdźki, modele) i cache'uje ją lokalnie.
- Gracz zwiedza — zdarzenia (zaliczony punkt, zebrana znajdźka, start i meta trasy) trafiają najpierw do lokalnej kolejki.
- Po powrocie sieci kolejka dosynchronizowuje się bez duplikatów, bo każde zdarzenie ma własne, niepowtarzalne ID.
- Odpowiedź serwera rozstrzyga stan: profil, statystyki, postęp trasy i portfel tokenów liczone są po stronie API, nigdy „na wiarę” z telefonu.
Pliki treści (obrazy, audio, modele 3D, paczki offline) są serwowane jako adresy w ramach domeny fyndi.app — aplikacja nie odwołuje się do żadnego innego miejsca w sieci. Serwer wystawia publiczny adres API, a ruch do aplikacji przechodzi przez nginx z certyfikatem TLS.
Warstwy klienta#
Aplikacja i strona dzielą ten sam pomysł na warstwy, ale nie ten sam kod.
| Warstwa | Aplikacja Android | Strona www / panel |
|---|---|---|
| Mapa | Mapbox Maps SDK ze stylem standardowym i własnymi warstwami GL na ludziki i znaczniki | Mapbox GL JS, znaczniki jako rysunki (sprite'y) z tej samej palety co w aplikacji |
| Postać | natywny renderer postaci blocky, bez pośrednictwa przeglądarki | ten sam model i ten sam atlas, osadzone na stronie postaci |
| Logika | czysty Kotlin: ruch pionka, kamera, plan rysowania znaczników — testowalny bez telefonu | statyczne moduły JavaScript bez frameworka, z testami w Node |
Kod Androida dzieli się na moduły: :app (ekrany, mapa, kreator), :core (sieć, modele, tekstury), :ar (widok AR za wspólnym interfejsem) oraz :puck3d — wspólny renderer pionka 3D, którego od wydania 0.120.0 używa i mapa główna, i mini-mapa w widoku AR. Jeden pionek, jedno miejsce zmian.
Po stronie API moduły odpowiadają obszarom: konta i role, treść, postęp, paczki, panel staff, mózg projektu, funkcje AI, nadpisania tekstów, lobby, boty NPC i nagrody.
Dlaczego właśnie tak#
- Silnik AR za interfejsem. Widok AR jest schowany za wspólnym kontraktem, więc można go podmienić (na przykład na inny silnik) bez przepisywania logiki zwiedzania.
- Treść jest danymi, nie kodem. Trasy, punkty i modele leżą w bazie i na dysku serwera, więc zmiany wchodzą „na żywo”, bez nowego APK.
- Zero sekretów w aplikacji. APK zna tylko publiczny adres API; klucze i materiał do podpisywania wydań zostają na serwerze i nigdy nie trafiają do repozytorium.
- Ten sam kreator wszędzie. Aplikacja, strona i panel korzystają z jednej tabeli elementów, więc postać wygląda identycznie na każdym ekranie (Postać 3D).
- Dokumentacja w repozytorium. Strona dokumentacji jest generowana ze plików markdown leżących obok kodu, więc opis funkcji i sama funkcja zmieniają się razem.
Opis zgodny z aplikacją 0.120.1 (zaktualizowano 2026-09-26).