Database Schema
CakeMarket uses SQLite via Drizzle ORM with the better-sqlite3 driver.
Configuration
- ORM: Drizzle ORM
- Driver: better-sqlite3
- Config file:
drizzle.config.ts - Schema location:
src/lib/db/schema.ts - IDs: UUID v4 for all primary keys
- Prices: Stored as integers in grosze (1/100 PLN)
Key Tables
Users
id(UUID, PK)name,email,phone,imageUrlrole(user, admin)- Authentication-related fields
Organisations
id(UUID, PK)name,address,locationLat,locationLngcontactEmail,contactPhone,profileImageUrlisActive(automatic after required seller details and Stripe onboarding)isDisabled(platform enforcement; independent of seller setup)- Capabilities:
acceptedCakeTypes,acceptedTastes,specialRequirements - Operations:
leadTimeDays,deliveryEnabled,deliveryRangeKm,pickupEnabled minDepositPercent(20-100)- Stripe:
stripeAccountId,stripeOnboardingComplete - Optional badge review: public
certificationLevel; privatesanepidCertDocUrlandsanepidCertExpiry(Organisation admins and platform admins only)
Organisation Members
organisationId,userId(composite PK)role(admin, baker)status(pending, active, rejected)joinedAt
Requests (Cake Requests)
id(UUID, PK)buyerIdorguestTokeneventType,servings,desiredDatedeliveryMethod,deliveryAddressfillings,dietaryRequirementsthemeDescription,cakeImageUrlisReorder,originalOrderId,targetOrganisationIdstatus(active, expired)expiresAt
Offers
id(UUID, PK)requestId,organisationIdprice(grosze),depositPercentmessage,proposedImageUrl,proposedImageSourcestatus(pending, accepted, withdrawn)holdExpiresAt
Orders
id(UUID, PK)orderNumberrequestId,offerId,organisationId,buyerIdtotalPrice(grosze),depositAmount,balanceAmountstatus(deposit_paid, in_progress, ready, delivered, completed, cancelled;disputedis retained only for legacy database compatibility and is not an active workflow)balancePaidAt,balancePaymentMethodcancelledBy,cancelReason- Timeline timestamps:
depositPaidAt,startedAt,readyAt,deliveredAt,completedAt
Payments
id(UUID, PK)orderId,organisationIdtype(deposit, balance, refund)amount(grosze),netAmountstatus(pending, succeeded, failed, refunded)stripePaymentIntentIdmethod(stripe, cash, card_at_pickup)
Messages
id(UUID, PK)orderIdorofferIdsenderId,senderType(buyer, seller)contentreadAt
Reviews
id(UUID, PK)orderId,buyerId,organisationIdrating(1-5),comment
Portfolio Items
id(UUID, PK)organisationIdimageUrl,captionsortOrder
Notifications
id(UUID, PK)userIdtitle,bodytypereadAt
Migrations
Drizzle handles migrations. Run:
npx drizzle-kit generate
npx drizzle-kit migrate