Karczma-Stoliki 🍻
System podglądu zamówień (KDS) oraz interaktywny panel dla gości restauracji, oparty na integracji z bazą MS SQL programu Gastro.
Aplikacja rozwiązuje problem sprawdzania statusu przygotowania zamówienia przez gości przy stoliku oraz udostępnia widok produkcyjny (Kitchen Display System) dla personelu na kuchni.
🏗 Struktura Katalogów
Projekt jest podzielony wg poniższej struktury:
karczma-stoliki/
├── api/ # Endpointy Backendowe (PHP)
│ ├── bills.php # Zwraca pozycje na rachunkach wg stolika (używane przez klientów)
│ ├── kds.php # Zwraca status zamówień na kuchni (odfiltrowane)
│ ├── get_table_name.php # Helper: Mapuje bezpieczny Hash (GUID) na nazwę stolika
│ └── cache/ # Zapis lokalnego pliku JSON (tables_cache.json) z listą stolików
├── config/ # Konfiguracja
│ └── database.php # WSPÓLNA konfiguracja połączenia z MS SQL (Zmień hasło tylko tu!)
├── public/ # Pliki serwowane użytkownikom
│ ├── stolik2_api.html # Główny interfejs dla klienta (czyta Hash z URL)
│ ├── assets/ # Style CSS i skrypty JS klienta (stolik2_api.js)
│ └── staff/ # Narzędzia wewnętrzne dla obsługi
│ ├── kds.php # Główny widok ekranu kuchennego (odpytuje api/kds.php)
│ └── generator.php # Generator bezpiecznych kodów QR/linków do stolików
├── docs/ # Dokumentacja i pliki dla AI
│ └── ai.txt # Główne zrzuty struktury tabel z Gastro
├── scripts/ # Skrypty narzędziowe / deweloperskie (wyciąganie schematów)
└── legacy/ # Stare pliki (Node.js/WebSockety - nie używane na produkcji)
🔒 Bezpieczeństwo URL (Hash)
Z powodów bezpieczeństwa, aby klienci w restauracji nie podglądali zamówień z innych stolików (zgadując adres np. ?table=1), aplikacja używa natywnych identyfikatorów z bazy MS SQL (tj. GUID, np. 5D1BF524-F8B3-4D34-BEF5-9BA1A25E0475).
- Link do stolika dla klienta:
http://<IP>/karczma-stoliki/public/stolik2_api.html?h=GUID - Kelner generuje te linki / kody QR w zakładce
public/staff/generator.php. - Gdy klient wchodzi pod link,
get_table_name.phpbłyskawicznie "tłumaczy" Hash na nazwę stolika (np. "C-57") korzystając z pamięci podręcznej JSON wbudowanej w podkatalogapi/cache/, odciążając w ten sposób bazę MS SQL.
(Uwaga: widok kuchni public/staff/kds.php posiada ukryty parametr kds_secret=karczma_kuchnia po to, by omijać filtrowanie hashem i wyświetlać wszystkie zlecenia naraz)
🛠 Wdrożenie (Setup)
- Sklonuj lub wgraj repozytorium do katalogu
htdocsserwera XAMPP. - Zaktualizuj IP serwera SQL, użytkownika i hasło (
sa/karczma!@#26) w plikuconfig/database.php. - Upewnij się, że włączone i załadowane są sterowniki
sqlsrvdla PHP. - Upewnij się, że folder
api/cacheposiada prawa zapisu (chmod 777na Linuksie / Pełna kontrola na Windowsie) by skrypt mógł wygenerowaćtables_cache.json. - Dla ułatwienia pracy, na roocie znajduje się
index.php(Dev Portal), z którego możesz klikać we wszystkie moduły (do usunięcia na produkcji).
🍽 Odświeżanie cache menu (CLI)
Menu dla gości (PL/EN/DE + tłumaczenia AI ES/IT/KO) nie odświeża się automatycznie.
Cache leży w api/cache/menu_*.json i aktualizujesz go ręcznie z terminala.
Wymagania
- PHP CLI (nie
php-fpm) — np./usr/bin/php8albophpw PATH. - Katalog
api/cachezapisywalny przez użytkownika, który odpala skrypt:
# na serwerze Linux (dostosuj użytkownika do FPM / SSH)
chown -R www-data:www-data api/cache
chmod 775 api/cache
- Klucz OpenAI w
config/menu_ai.local.php(plik lokalny zapi_keyi modelem — nie commituj klucza).
Komendy
Z katalogu głównego projektu (karczma-stoliki/):
# Tylko upstream PL/EN/DE + AI gdy zmienił się fingerprint PL
php scripts/refresh_menu_cache.php
# Wymuś ponowne tłumaczenie ES/IT/KO przez OpenAI (zużywa tokeny)
php scripts/refresh_menu_cache.php --force-ai
Na produkcji, jeśli php wskazuje na FPM albo złą wersję:
cd /var/www/html/public/app # ścieżka do projektu na serwerze
/usr/bin/php8 scripts/refresh_menu_cache.php --force-ai
Skrypt wypisuje log linia po linii. Exit 0 = sukces, 1 = błąd (np. brak praw zapisu, błąd AI).
Co robi skrypt?
- Pobiera menu z upstreamu Karczmy (PL/EN/DE) →
api/cache/menu_pl.jsonitd. - Dla ES/IT/KO tłumaczy zmienione pozycje z PL przez OpenAI (
gpt-4owg konfiguracji). - Zapisuje fingerprint PL, żeby kolejne uruchomienia bez
--force-aipomijały AI, gdy menu się nie zmieniło.
📊 Analityka (MVP)
W projekcie działa eventowa analityka oparta o MySQL:
- Endpoint zapisu eventów:
api/analytics.php(POST JSON). - Endpoint raportowy pod panel:
api/analytics_reports.php(GET, parametrdays). - Skrypt agregacji dziennej:
scripts/analytics_aggregate_daily.php.
Przykładowe uruchomienie agregacji:
php scripts/analytics_aggregate_daily.php
php scripts/analytics_aggregate_daily.php 2026-05-28
Przykładowe raporty JSON:
api/analytics_reports.php?days=7api/analytics_reports.php?days=30
💡 Jak działa mapowanie zamówień?
- Aplikacja KDS wyciąga dane łącząc tabele
dbo.NGastroDTRachunekidbo.NGastroDTRachunekPozycja. - Filtruje ona zamówienia, używając
StatusRealizacji. - Pozycje wydzielane łączone są sprytnym zapytaniem regex sprawdzającym pole
Opisna wypadek, gdyby POS utracił przypisanie fizycznego ID stolika przy podziale rachunku. - Składniki zestawów (np. dodatki do Pizzy) sprytnie grupują się pod wspólnym węzłem wykorzystując klucz
GrupaZestawuID.