Strona pizzerii z zamówieniami online i panelem dla obsługi.
bun install
cp .env.example .env
bun devDomyślnie (PUBLIC_DEV_MODE=true) aplikacja jedzie na danych w pamięci — bez Supabase,
bez konfiguracji. Konta obsługi z .env:
| Konto | Hasło | Rola |
|---|---|---|
admin@admin.pl |
admin |
admin — kolejka, menu, ustawienia |
kucharz@kucharz.pl |
kucharz |
kucharz — tylko kolejka |
Zamówienia w tym trybie znikają po restarcie serwera. To celowe.
bun run test # jednorazowo
bun run test:watchUwaga: bun run test uruchamia Vitest (nasz skonfigurowany runner).
Samo bun test odpala wbudowany runner buna, który ignoruje vite.config.ts —
dziś przechodzi tak samo, ale to inna ścieżka. Trzymaj się bun run test.
Testy pokrywają src/lib/price.ts — jedyne miejsce, gdzie liczą się pieniądze
i w które klient może celować spreparowanym koszykiem.
- Załóż projekt na supabase.com.
- Wykonaj po kolei
supabase/migrations/0001_init.sql,supabase/migrations/0002_product_addons.sql, potemsupabase/seed.sql(SQL Editor). - Uzupełnij w
.env:PUBLIC_SUPABASE_URL,PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY. - Ustaw
PUBLIC_DEV_MODE=false. - Załóż konta przez
/register, a potem nadaj im role — komendy są na końcuseed.sql.
src/lib/price.ts— wycena pozycji koszyka. Ta sama funkcja liczy cenę poglądową w konfiguratorze i cenę wiążącą na serwerze. Cena z przeglądarki nigdy nie trafia do zamówienia — serwer liczy ją od nowa z aktualnego cennika.src/lib/server/db.ts— jedyne wejście do danych. Każda funkcja ma gałąź mockową i supabase'ową, więc przełącznikPUBLIC_DEV_MODEdziała w całej aplikacji.src/lib/cart.svelte.ts— koszyk wlocalStorage, trzyma wyłącznie identyfikatory wyborów.- Ceny wszędzie w groszach (
*_gr). Liczby zmiennoprzecinkowe gubią grosze przy sumowaniu. src/lib/components/ui/— komponenty shadcn-svelte. To nasz kod, nie zależność: wolno go edytować. Wariantybrand,brand-outline,brand-dark,successi rozmiarypill,pill-lgwbutton.svelteto dodatki projektu.- Paleta z Figmy siedzi w zmiennych shadcn w
src/routes/layout.css, więc komponenty są markowe bez nadpisywania klas w miejscach użycia.
Produkt ma flagę allows_addons (czy w ogóle przyjmuje dodatki) i listę addon_ids
(które konkretnie). Pusta lista = wszystkie dostępne dodatki — dzięki temu menu
bez ustawionych list działa jak wcześniej. Listę zawęża się w /admin/menu.
Serwer sprawdza ją przy wycenie, więc dodatek spoza listy zostanie odrzucony
niezależnie od tego, co przyśle przeglądarka.
| Ścieżka | Kto |
|---|---|
/, /menu, /cart |
wszyscy |
/order/[token], /payment/[token] |
kto ma link (token = losowy UUID) |
/account |
zalogowany |
/admin |
kucharz + admin |
/admin/menu, /admin/settings |
admin |