Przegląd architektury
CakeMarket v2.0 jest zbudowany na nowoczesnej pełnostackowej architekturze TypeScript.
Stos technologiczny
| Warstwa | Technologia |
|---|---|
| Framework | Next.js 14+ (App Router) |
| Język | TypeScript |
| Baza danych | SQLite via Drizzle ORM (better-sqlite3) |
| Uwierzytelnianie | Auth.js v5 ze strategią JWT |
| Stylowanie | Tailwind CSS |
| Walidacja | Zod |
| Płatności | Stripe Connect |
| Identyfikatory | UUID v4 dla wszystkich kluczy głównych |
| i18n | Tłumaczenia oparte na JSON (angielski + polski) |
| PWA | Service worker + manifest.json |
Struktura App Router
Aplikacja wykorzystuje grupy tras Next.js do rozdzielenia odpowiedzialności:
src/app/
├── (buyer)/ # Strony kupującego
├── (seller)/ # Portal sprzedającego
│ └── seller/
│ ├── dashboard/
│ ├── requests/
│ ├── orders/
│ ├── organisation/
│ ├── profile/
│ ├── payments/
│ ├── onboarding/
│ └── pending/
├── (admin)/ # Panel administracyjny
│ └── admin/
│ ├── disputes/ # Starsze przekierowanie zgodności; brak aktywnego interfejsu sporów
│ └── orders/
├── about/ # Strony marketingowe
└── api/ # Trasy API
├── admin/
├── guest/
├── images/
├── messages/
├── offers/
├── orders/
├── organisations/
├── payments/
├── profile/
├── requests/
├── reviews/
└── seller/
Kluczowe wzorce architektoniczne
Warstwa dostępu do danych (DAL)
Wszystkie zapytania do bazy danych przechodzą przez src/lib/dal/. Komponenty i trasy API nigdy nie importują Drizzle bezpośrednio — zamiast tego korzystają z funkcji DAL.
src/lib/dal/
├── organisations.ts
├── orders.ts
├── offers.ts
├── requests.ts
├── users.ts
├── payments.ts
├── messages.ts
├── reviews.ts
└── ...
Pomocniki uwierzytelniania
Scentralizowane funkcje uwierzytelniania w src/lib/auth/helpers.ts:
getCurrentUser()— Pobierz bieżącego użytkownika sesjirequireAuth()— Wymagaj uwierzytelnienia (zwraca użytkownika lub rzuca wyjątek)requireAdmin()— Wymagaj roli administratorarequireOrgMember()— Wymagaj członkostwa w konkretnej organizacjirequireOrgAdmin()— Wymagaj roli administratora w organizacji
Sesje gości
Użytkownicy-goście są obsługiwani za pomocą tokenów localStorage i odcisków przeglądarki. Goście mogą:
- Tworzyć zapytania o torty
- Otrzymywać i akceptować oferty
- Składać zamówienia
Sesje gości mogą być przekształcone w pełne konta za pomocą POST /api/guest/convert, co migruje zapytania, zamówienia i preferencje.
Obsługa cen
Wszystkie ceny są przechowywane jako liczby całkowite w groszach (1/100 PLN), aby uniknąć problemów z liczbami zmiennoprzecinkowymi:
formatPrice()— Konwertuje grosze na format wyświetlaniacalculateDeposit()— Oblicza zaliczkę od kwoty całkowitejcalculateCommission()— Oblicza prowizję platformycalculateBalance()— Oblicza pozostałą kwotę do zapłaty
Stałe biznesowe
Zdefiniowane w src/lib/utils/constants.ts:
| Stała | Wartość |
|---|---|
| Stawka prowizji | 10% |
| Zakres zaliczki | 20–100% |
| Wygaśnięcie zapytania | 24 godziny |
| Inteligentne sortowanie: waga oceny | 40% |
| Inteligentne sortowanie: waga ceny | 35% |
| Inteligentne sortowanie: waga certyfikacji | 25% |
Architektura komponentów
src/components/
├── ui/ # Wielokrotnego użytku prymitywy UI (przyciski, modale, odznaki itp.)
├── shared/ # Współdzielone komponenty (akordeon FAQ itp.)
├── buyer/ # Komponenty kupującego
└── seller/ # Komponenty sprzedającego
├── OfferForm.tsx
├── RequestCard.tsx
├── RequestDetailModal.tsx
├── OrderCard.tsx
├── OrderDetail.tsx
├── MessageThread.tsx
├── PortfolioManager.tsx
├── MembersList.tsx
├── CertificationManager.tsx
├── SidebarNav.tsx
├── BottomTabs.tsx
└── TopBar.tsx
Walidacja
Cała walidacja danych wejściowych wykorzystuje schematy Zod zdefiniowane w src/lib/validation/schemas.ts. Schematy są współdzielone między formularzami po stronie klienta a handlerami tras API.
Powiadomienia e-mail
24 szablony e-mail HTML (polski + angielski) w src/lib/notifications/email.ts:
- Produkcja: Wysyłane przez Resend
- Rozwój: Logowane do konsoli
Funkcje pomocnicze obejmują sendOfferReceivedEmail, sendBalancePaymentDueEmail, sendSellerMarkedDeliveredEmail, sendReviewPromptEmail oraz sendNewOrganisationAdminEmail.