Headless marketplace dla rynku vintage na Medusa.js
Budowa wielosprzedawcowego marketplace'u na Medusa.js — platformie zaprojektowanej jako single-vendor. Custom plugin, model danych sprzedawcy i panel administracyjny od zera.
Usługi
Technologie
Marketplace antyków i przedmiotów vintage rządzi się innymi prawami niż typowy sklep B2C. Każdy przedmiot jest unikatowy — jeden egzemplarz, jedna cena, jedna historia. Platforma musiała obsługiwać dziesiątki niezależnych sprzedawców wystawiających własne oferty, przy czym kupujący widzi spójne doświadczenie zakupowe bez świadomości, od kogo konkretnie pochodzi dany przedmiot.
Medusa.js jest zaprojektowana jako silnik single-vendor. Jeden sklep, jeden właściciel konta, jedna kasa. Zbudowanie marketplace multi-vendor oznaczało wyjście poza gotowe abstrakcje platformy.
Trzy główne problemy techniczne:
- Model danych. Natywna Medusa nie posiada encji
Sellerani powiązania produkt↔sprzedawca. Każdy produkt należy do sklepu, nie do indywidualnego podmiotu. - Routing zamówień. Koszyk może zawierać produkty od wielu sprzedawców. Medusa traktuje zamówienie jako monolityczną jednostkę — trzeba było rozwiązać podział płatności i osobne fulfillment flows.
- Panel sprzedawcy. Standardowy Medusa Admin to narzędzie dla operatora marketplace, nie dla indywidualnego sprzedawcy. Potrzebny był osobny interfejs z ograniczonym widokiem danych.
Zamiast forka Medusy, wybrałem podejście przez custom plugin rozszerzający istniejący model danych bez ingerencji w core platformy. Dzięki temu aktualizacje Medusy nie psują logiki biznesowej.
Encja Seller i relacje. Plugin dodaje do bazy danych tabelę sprzedawców z profilem, stawkami prowizji i statusem weryfikacji. Produkty i warianty są powiązane z seller_id przez dodatkową kolumnę i middleware walidujący własność przy każdej mutacji.
Order splitting. Po złożeniu zamówienia webhook dzieli je na sub-zamówienia per sprzedawca. Każdy sprzedawca widzi wyłącznie swoje zamówienia, otrzymuje osobne powiadomienie i zarządza własnym fulfillmentem. Płatność jest zbierana przez marketplace, prowizja odliczana automatycznie.
Panel sprzedawcy. Osobna aplikacja Next.js z uwierzytelnianiem przez Medusa API. Sprzedawca może dodawać produkty, śledzić zamówienia i przeglądać statystyki sprzedaży. Rola jest ograniczona — sprzedawca nie widzi danych innych sprzedawców ani konfiguracji platformy.
Unikatowość produktów. Dla kategorii vintage każdy SKU ma włączone śledzenie stanu magazynowego z limitem 1 sztuki. Po sprzedaży produkt jest automatycznie archiwizowany.
DevOps. Stack uruchomiony na serwerze VPS przez Docker Compose: Medusa backend, Next.js storefront, panel sprzedawcy, PostgreSQL i Nginx jako reverse proxy. Wdrożenia są automatyczne po merge do głównej gałęzi.
- Zero downtime przy aktualizacjach Medusy — architektura pluginowa separuje logikę marketplace od core platformy.
- Pełny fulfillment flow end-to-end: wystawienie → koszyk → płatność → podział → wysyłka — bez ręcznej ingerencji operatora.
- Niezależność sprzedawców — każdy zarządza własnym katalogiem i zamówieniami z poziomu dedykowanego panelu.
Projekt pozostaje pod moją aktywną opieką techniczną. Zakres retainera obejmuje monitoring, aktualizacje zależności, drobne usprawnienia i szybki czas reakcji na incydenty.