Temă
Modelul de date
Pentru o privire de ansamblu, fără coloane tehnice, începe cu ERD-ul conceptual: conceptele de business și legăturile lor, citite ca propoziții.
Generat automat din structura bazei de date (
pnpm docs:generate, care citește tabelele create de migrările Laravel). Nu edita manual: adaugă o migrare și regenerează.
Baza de date MySQL 8.4 are 51 de tabele de entități, grupate în 11 domenii. Convenții:
- Sumele de bani sunt numere întregi în bani (1 leu = 100 de bani), ca să nu existe erori de rotunjire.
- Datele sunt stocate în UTC; afișarea se face în ora României.
- Fiecare tabel are
id(cheie primară),created_atșiupdated_at. *în diagrame marchează o coloană obligatorie;→ Entitatee o cheie străină (relație n:1).- Enumerările sunt stocate ca text (de exemplu
status = 'active'), ușor de citit în interogări.
Conturi
Clienții site-ului și membrii echipei.
AuthSession (auth_sessions)
O sesiune deschisă (client sau membru al echipei): doar hash-ul SHA-256 al tokenului din cookie, expirarea glisantă și dispozitivul de încredere. Ștergerea ei deconectează imediat.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
tokenHash | token_hash | string | da | cheie primară; max. 43 caractere |
realm | realm | enum | da | valori: customer, staff |
subjectId | subject_id | integer | da | |
ipAddress | ip_address | string | nu | max. 45 caractere |
userAgent | user_agent | string | nu | max. 255 caractere |
createdAt | created_at | datetime | da | |
expiresAt | expires_at | datetime | da |
Indecși: (expiresAt); (realm, subjectId).
BusinessVerification (business_verifications)
O cerere de verificare ca firmă, cu datele exact cum au fost trimise; starea curentă rămâne pe utilizator. Stări: în așteptare, aprobată (cine, când), respinsă (de ce), retrasă (înlocuită de o cerere nouă).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
status | status | enum | da | valori: pending, approved, rejected, withdrawn |
companyName | company_name | string | da | max. 120 caractere |
companyCui | company_cui | string | da | max. 12 caractere |
companyRegNumber | company_reg_number | string | da | max. 30 caractere |
companyAddress | company_address | string | da | max. 200 caractere |
companyVatPayer | company_vat_payer | boolean | da | |
reviewedBy | reviewed_by_id | → StaffMember | nu | relație n:1 |
reviewedAt | reviewed_at | datetime | nu | |
rejectionReason | rejection_reason | string | nu | max. 300 caractere |
Indecși: (status, createdAt); (user, createdAt).
OneTimeToken (one_time_tokens)
Un token de unică folosință, stocat ca hash: link de confirmare a e-mailului, resetare de parolă, invitație în echipă, cod de telefon, provocarea de conectare în doi pași, revendicarea unei fotografii încărcate.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
purpose | purpose | string | da | cheie primară; max. 40 caractere |
tokenHash | token_hash | string | da | cheie primară; max. 43 caractere |
payload | payload | json | da | |
expiresAt | expires_at | datetime | da |
Indecși: (expiresAt).
PayoutAccount (payout_accounts)
Contul în care e plătit un vânzător, cu istoric: o schimbare adaugă un rând și îl închide pe cel vechi (replaced_at). Contul curent are replaced_at gol. O schimbare recentă e semnalată echipei financiare la plăți.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
holder | holder | string | da | max. 120 caractere |
iban | iban | string | da | max. 34 caractere |
replacedAt | replaced_at | datetime | nu |
Indecși: (user, replacedAt).
StaffMember (staff_members)
Membru al echipei Taraba (Backoffice și CRM). Rolul determină permisiunile; autentificarea cere parolă și cod TOTP.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
email | email | string | da | unic; max. 190 caractere |
passwordHash | password_hash | string | nu | max. 255 caractere |
name | name | string | da | max. 120 caractere |
role | role | enum | da | valori: admin, moderator, support, finance, marketing |
status | status | enum | da | valori: invited, active, disabled |
totpSecret | totp_secret | string | nu | max. 64 caractere |
totpEnabledAt | totp_enabled_at | datetime | nu | |
invitedAt | invited_at | datetime | nu | |
lastLoginAt | last_login_at | datetime | nu |
Indecși: unic (email).
TotpStepClaim (totp_step_claims)
Pasul de 30 de secunde al unui cod TOTP deja folosit de o persoană: același cod nu poate fi folosit de două ori, nici în două cereri simultane.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
owner | owner | string | da | cheie primară; max. 64 caractere |
step | step | integer | da | |
expiresAt | expires_at | datetime | da |
User (users)
Clientul site-ului: cumpără și vinde. Poate fi persoană fizică sau firmă. Conține datele de profil, verificările (e-mail, telefon, identitate), contul de încasare (IBAN), preferințele de notificare și ratingul calculat din evaluări.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
email | email | string | da | unic; max. 190 caractere |
firstName | first_name | string | da | max. 80 caractere |
lastName | last_name | string | da | max. 80 caractere |
type | type | enum | da | valori: individual, business |
companyName | company_name | string | nu | max. 120 caractere |
phone | phone | string | nu | max. 20 caractere |
city | city | string | nu | max. 80 caractere |
county | county | string | nu | max. 80 caractere |
bio | bio | text | nu | |
avatarKey | avatar_key | string | nu | max. 255 caractere |
locale | locale | string | da | max. 5 caractere |
status | status | enum | da | valori: active, suspended, deleted |
emailVerifiedAt | email_verified_at | datetime | nu | |
phoneVerifiedAt | phone_verified_at | datetime | nu | |
identityVerifiedAt | identity_verified_at | datetime | nu | |
lastActiveAt | last_active_at | datetime | nu | |
suspendedUntil | suspended_until | datetime | nu | |
suspensionReason | suspension_reason | string | nu | max. 255 caractere |
acquisitionSource | acquisition_source | enum | da | valori: organic_search, google_ads, facebook_instagram, tiktok, referral, direct |
notificationPreferences | notification_preferences | json | da | |
ratingAverage | rating_average | decimal | nu | |
ratingCount | rating_count | integer | da | |
totpEnabledAt | totp_enabled_at | datetime | nu | |
companyCui | company_cui | string | nu | max. 12 caractere |
companyRegNumber | company_reg_number | string | nu | max. 30 caractere |
companyAddress | company_address | string | nu | max. 200 caractere |
companyVatPayer | company_vat_payer | boolean | da | |
businessStatus | business_status | enum | da | valori: none, pending, verified, rejected |
Indecși: (createdAt); unic (email); (status).
UserCredential (user_credentials)
Secretele unui client (hash-ul parolei, cheia verificării în doi pași), separate de profil: citirea unui utilizator (carduri, liste CRM, căutări Backoffice) nu le aduce niciodată. Accesate doar prin CredentialsService.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
passwordHash | password_hash | string | nu | max. 255 caractere |
totpSecret | totp_secret | string | nu | max. 64 caractere |
Indecși: unic (user).
Catalog
Anunțuri, fotografii, categorii, favorite, căutări salvate, cuvinte interzise.
BannedWord (banned_words)
Cuvânt sau expresie interzisă: anunțurile care le conțin primesc un semnal de risc la moderare.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
word | word | string | da | unic; max. 80 caractere |
addedBy | added_by_id | → StaffMember | nu | relație n:1 |
Indecși: unic (word).
Category (categories)
Categoria din meniul site-ului; ordinea, pictograma și dacă anunțurile cer mărime.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
slug | slug | string | da | unic; max. 80 caractere |
name | name | string | da | max. 120 caractere |
icon | icon | string | da | max. 16 caractere |
position | position | integer | da | |
isActive | is_active | boolean | da | |
requiresSize | requires_size | boolean | da |
Indecși: unic (slug).
Favorite (favorites)
Un anunț salvat de un client. Contorul de favorite al anunțului e denormalizat.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
listing | listing_id | → Listing | da | relație n:1 |
Indecși: unic (user, listing).
Listing (listings)
Anunțul: ce se vinde, prețul, starea, locația, variantele de predare și starea anunțului în ciclul de viață (ciornă, în verificare, activ, vândut, expirat, eliminat…). Păstrează și semnalele automate de risc și decizia de moderare.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
seller | seller_id | → User | da | relație n:1 |
category | category_id | → Category | da | relație n:1 |
title | title | string | da | max. 160 caractere |
slug | slug | string | da | unic; max. 200 caractere |
description | description | text | da | |
priceBani | price_bani | integer | da | sumă în bani |
negotiable | negotiable | boolean | da | |
condition | condition | enum | da | valori: new_with_tags, new_without_tags, very_good, good, fair |
brand | brand | string | nu | max. 80 caractere |
size | size | string | nu | max. 30 caractere |
specs | specs | json | nu | |
city | city | string | da | max. 80 caractere |
county | county | string | da | max. 80 caractere |
allowsCourier | allows_courier | boolean | da | |
allowsEasybox | allows_easybox | boolean | da | |
allowsPickup | allows_pickup | boolean | da | |
status | status | enum | da | valori: draft, pending_review, changes_requested, rejected, active, sold, expired, deactivated, removed |
publishedAt | published_at | datetime | nu | |
expiresAt | expires_at | datetime | nu | |
soldAt | sold_at | datetime | nu | |
riskSignals | risk_signals | json | nu | |
moderatedBy | moderated_by_id | → StaffMember | nu | relație n:1 |
moderatedAt | moderated_at | datetime | nu | |
moderationNote | moderation_note | text | nu | |
promotionType | promotion_type | enum | nu | valori: bump, highlight, top |
promotedUntil | promoted_until | datetime | nu |
Indecși: (category, status); (city); (createdAt); (title, description); unic (slug); (status, publishedAt).
ListingPhoto (listing_photos)
O fotografie a unui anunț: cheia din stocarea de obiecte și poziția în galerie.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
listing | listing_id | → Listing | da | relație n:1 |
storageKey | storage_key | string | da | max. 255 caractere |
position | position | integer | da | |
width | width | integer | nu | |
height | height | integer | nu |
ListingStats (listing_stats)
Contoarele unui anunț (vizualizări, favorite), separate de anunț: scrierile frecvente nu ating rândul mare al anunțului. Rândul se creează la prima vizualizare sau la primul favorit; lipsa lui înseamnă zero.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
listing | listing_id | → Listing | da | relație n:1 |
viewsCount | views_count | integer | da | |
favoritesCount | favorites_count | integer | da |
ListingViewDay (listing_view_days)
Vizualizările unui anunț într-o zi (UTC), pentru statisticile vânzătorului; un rând pe anunț și zi, incrementat atomic.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
listing | listing_id | → Listing | da | relație n:1 |
day | day | date | da | |
views | views | integer | da |
Indecși: unic (listing, day).
SavedSearch (saved_searches)
O căutare salvată, cu alertă opțională pentru anunțuri noi.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
label | label | string | da | max. 160 caractere |
query | query | json | da | |
alertsEnabled | alerts_enabled | boolean | da | |
lastNotifiedAt | last_notified_at | datetime | nu | |
lastAlertedAt | last_alerted_at | datetime | nu |
Comerț
Comenzi, plăți, rambursări, plăți către vânzători, promovări, evaluări.
CheckoutStart (checkout_starts)
Un client conectat a deschis checkout-ul pentru un anunț (un rând pe persoană și anunț; ora se actualizează la fiecare vizită). Sursa automatizării CRM „coș abandonat”.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
listing | listing_id | → Listing | da | relație n:1 |
startedAt | started_at | datetime | da |
Indecși: (startedAt); unic (user, listing).
Order (orders)
Comanda: anunțul cumpărat, cumpărătorul, vânzătorul, sumele (în bani), livrarea, plata, AWB-ul și toate momentele din ciclul de viață; starea plății către vânzător.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
code | code | string | da | unic; max. 20 caractere |
listing | listing_id | → Listing | da | relație n:1 |
buyer | buyer_id | → User | da | relație n:1 |
seller | seller_id | → User | da | relație n:1 |
status | status | enum | da | valori: pending_payment, paid, shipped, delivered, completed, disputed, return_requested, refunded, cancelled |
itemPriceBani | item_price_bani | integer | da | sumă în bani |
deliveryFeeBani | delivery_fee_bani | integer | da | sumă în bani |
protectionFeeBani | protection_fee_bani | integer | da | sumă în bani |
codFeeBani | cod_fee_bani | integer | da | sumă în bani |
discountBani | discount_bani | integer | da | sumă în bani |
totalBani | total_bani | integer | da | sumă în bani |
currency | currency | string | da | max. 3 caractere |
deliveryMethod | delivery_method | enum | da | valori: courier, easybox, pickup |
paymentMethod | payment_method | enum | da | valori: card, cash_on_delivery |
shippingAddress | shipping_address | json | nu | |
courier | courier | string | nu | max. 40 caractere |
trackingNumber | tracking_number | string | nu | max. 40 caractere |
paidAt | paid_at | datetime | nu | |
shippedAt | shipped_at | datetime | nu | |
deliveredAt | delivered_at | datetime | nu | |
completedAt | completed_at | datetime | nu | |
autoConfirmAt | auto_confirm_at | datetime | nu | |
cancelledAt | cancelled_at | datetime | nu | |
cancellationReason | cancellation_reason | enum | nu | valori: seller_did_not_ship, buyer_request, suspected_fraud, seller_request |
payoutStatus | payout_status | enum | da | valori: held, released, blocked, cancelled |
payoutBani | payout_bani | integer | da | sumă în bani |
sellerIsBusiness | seller_is_business | boolean | da | |
returnRequestedAt | return_requested_at | datetime | nu | |
returnReason | return_reason | string | nu | max. 500 caractere |
returnTrackingNumber | return_tracking_number | string | nu | max. 40 caractere |
returnedAt | returned_at | datetime | nu |
Indecși: (buyer, status); unic (code); (createdAt); (seller, status); (status, createdAt).
Payment (payments)
Plata unei comenzi (card simulat sau ramburs): suma, starea, referința; nu conține niciodată datele cardului.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
order | order_id | → Order | da | relație n:1 |
provider | provider | string | da | max. 40 caractere |
providerReference | provider_reference | string | nu | max. 80 caractere |
amountBani | amount_bani | integer | da | sumă în bani |
status | status | enum | da | valori: authorized, captured, failed, refunded, partially_refunded |
cardLast4 | card_last4 | string | nu | max. 4 caractere |
cardBrand | card_brand | string | nu | max. 20 caractere |
capturedAt | captured_at | datetime | nu | |
failureReason | failure_reason | string | nu | max. 255 caractere |
Payout (payouts)
Plata către vânzător după finalizarea comenzii: suma, IBAN-ul mascat, data programată, starea (programată, trimisă, eșuată).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
seller | seller_id | → User | da | relație n:1 |
order | order_id | → Order | da | relație n:1 |
amountBani | amount_bani | integer | da | sumă în bani |
ibanMasked | iban_masked | string | da | max. 40 caractere |
status | status | enum | da | valori: scheduled, sent, failed |
scheduledFor | scheduled_for | datetime | da | |
sentAt | sent_at | datetime | nu | |
failureReason | failure_reason | string | nu | max. 255 caractere |
Indecși: (status, scheduledFor).
Promotion (promotions)
O promovare plătită a unui anunț (urcare în listă, evidențiere, top), cu perioada și prețul plătit.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
listing | listing_id | → Listing | da | relație n:1 |
seller | seller_id | → User | da | relație n:1 |
type | type | enum | da | valori: bump, highlight, top |
priceBani | price_bani | integer | da | sumă în bani |
startsAt | starts_at | datetime | da | |
endsAt | ends_at | datetime | da | |
paymentReference | payment_reference | string | nu | max. 80 caractere |
Refund (refunds)
O rambursare (totală sau parțială), cu motivul și cine a aprobat-o.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
order | order_id | → Order | da | relație n:1 |
payment | payment_id | → Payment | nu | relație n:1 |
amountBani | amount_bani | integer | da | sumă în bani |
reason | reason | enum | da | valori: dispute, lost_parcel, cancelled_by_seller, goodwill, withdrawal |
status | status | enum | da | valori: pending, processed, failed |
approvedBy | approved_by_id | → StaffMember | nu | relație n:1 |
processedAt | processed_at | datetime | nu |
Review (reviews)
Evaluarea lăsată de cumpărător vânzătorului, după o comandă finalizată.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
order | order_id | → Order | da | relație n:1 |
author | author_id | → User | da | relație n:1 |
subject | subject_id | → User | da | relație n:1 |
rating | rating | integer | da | |
comment | comment | text | nu |
Indecși: unic (order); (subject, createdAt).
Mesagerie
Conversații între cumpărător și vânzător, mesaje și oferte de preț.
Conversation (conversations)
Discuția dintre un cumpărător și vânzătorul unui anunț (una pentru fiecare pereche anunț–cumpărător), cu numărul de mesaje necitite pe fiecare parte.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
listing | listing_id | → Listing | da | relație n:1 |
buyer | buyer_id | → User | da | relație n:1 |
seller | seller_id | → User | da | relație n:1 |
lastMessageAt | last_message_at | datetime | nu | |
buyerUnreadCount | buyer_unread_count | integer | da | |
sellerUnreadCount | seller_unread_count | integer | da |
Indecși: (buyer, lastMessageAt); unic (listing, buyer); (seller, lastMessageAt).
Message (messages)
Un mesaj: text, ofertă sau mesaj de sistem.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
conversation | conversation_id | → Conversation | da | relație n:1 |
sender | sender_id | → User | nu | relație n:1 |
kind | kind | enum | da | valori: text, offer, system |
body | body | text | da | |
offer | offer_id | → Offer | nu | relație n:1 |
readAt | read_at | datetime | nu |
Indecși: (conversation, createdAt).
Offer (offers)
O ofertă de preț, cu expirare la 48 de ore și răspunsul (acceptată, refuzată, contraofertă).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
conversation | conversation_id | → Conversation | da | relație n:1 |
listing | listing_id | → Listing | da | relație n:1 |
buyer | buyer_id | → User | da | relație n:1 |
proposedBy | proposed_by_id | → User | da | relație n:1 |
amountBani | amount_bani | integer | da | sumă în bani |
status | status | enum | da | valori: pending, accepted, declined, expired, withdrawn |
expiresAt | expires_at | datetime | da | |
respondedAt | responded_at | datetime | nu |
Notificări
Notificările din aplicație (și push, prin canalul de push).
Notification (notifications)
Notificare în aplicație pentru un client (tip, titlu, text, link, citită).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
type | type | enum | da | valori: message, offer, order, saved_search, price_drop, moderation, system |
title | title | string | da | max. 160 caractere |
body | body | string | nu | max. 500 caractere |
link | link | string | nu | max. 255 caractere |
readAt | read_at | datetime | nu |
Indecși: (user, readAt, createdAt).
Încredere și siguranță
Raportări și dispute.
Dispute (disputes)
O problemă raportată de cumpărător la o comandă livrată: motivul, răspunsul vânzătorului, termenul și decizia (rambursare totală, parțială sau în favoarea vânzătorului).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
order | order_id | → Order | da | relație n:1 |
openedBy | opened_by_id | → User | da | relație n:1 |
reason | reason | enum | da | valori: not_as_described, not_received, damaged_in_transit |
description | description | text | da | |
evidenceKeys | evidence_keys | json | nu | |
status | status | enum | da | valori: awaiting_seller, under_review, resolved |
sellerResponse | seller_response | text | nu | |
sellerRespondedAt | seller_responded_at | datetime | nu | |
deadlineAt | deadline_at | datetime | da | |
resolution | resolution | enum | nu | valori: full_refund, partial_refund, seller_favour |
refundBani | refund_bani | integer | nu | sumă în bani |
resolvedBy | resolved_by_id | → StaffMember | nu | relație n:1 |
resolvedAt | resolved_at | datetime | nu |
Indecși: unic (order); (status, deadlineAt).
Report (reports)
O raportare despre un anunț sau un utilizator: motivul, prioritatea, starea și decizia echipei.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
reporter | reporter_id | → User | da | relație n:1 |
targetType | target_type | enum | da | valori: listing, user, message |
listing | listing_id | → Listing | nu | relație n:1 |
reportedUser | reported_user_id | → User | nu | relație n:1 |
messageId | message_id | integer | nu | |
reason | reason | enum | da | valori: scam, counterfeit, abusive_behaviour, service_not_item, spam_or_duplicate, prohibited_item |
description | description | text | nu | |
priority | priority | enum | da | valori: high, normal |
status | status | enum | da | valori: new, in_review, closed |
assignedTo | assigned_to_id | → StaffMember | nu | relație n:1 |
outcome | outcome | enum | nu | valori: no_violation, listing_removed, user_suspended, duplicates_removed |
closedBy | closed_by_id | → StaffMember | nu | relație n:1 |
closedAt | closed_at | datetime | nu |
Indecși: (status, priority, createdAt).
Verificare
Verificarea identității (telefonul se verifică prin cod, fără tabel propriu).
IdentityVerification (identity_verifications)
O cerere de verificare a identității. Fotografia actului e privată și se șterge la decizie; rămâne doar rezultatul.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
documentType | document_type | enum | da | valori: id_card, passport, driving_licence |
documentKey | document_key | string | nu | max. 200 caractere |
status | status | enum | da | valori: pending, approved, rejected |
reviewedBy | reviewed_by_id | → StaffMember | nu | relație n:1 |
reviewedAt | reviewed_at | datetime | nu | |
rejectionReason | rejection_reason | string | nu | max. 300 caractere |
Indecși: (status, createdAt).
Documente juridice
Versiunile termenilor, regulilor și politicilor, acceptările, notificările și alegerile privind cookie-urile.
CookieConsent (cookie_consents)
Alegerea unui vizitator privind cookie-urile opționale, pentru o versiune a politicii (identificator aleator, fără date personale).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
visitorId | visitor_id | string | da | max. 36 caractere |
user | user_id | → User | nu | relație n:1 |
policyVersion | policy_version | integer | da | |
categories | categories | json | da |
Indecși: (visitorId).
LegalAcceptance (legal_acceptances)
Dovada: cine a acceptat (termeni, reguli) sau a fost informat despre (politici) ce versiune, când, unde (înregistrare, în cont, la lansare), cu adresa IP.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
document | document_id | → LegalDocument | da | relație n:1 |
kind | kind | enum | da | valori: terms, posting_rules, privacy, cookies |
version | version | integer | da | |
action | action | enum | da | valori: accepted, acknowledged |
context | context | string | da | max. 20 caractere |
ipAddress | ip_address | string | nu | max. 45 caractere |
userAgent | user_agent | string | nu | max. 200 caractere |
Indecși: (kind, version); unic (user, document).
LegalDocument (legal_documents)
O versiune a unui document juridic (termeni, reguli de publicare, confidențialitate, cookie-uri): text structurat, rezumatul modificărilor, data intrării în vigoare. Versiunile publicate nu se modifică.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
kind | kind | enum | da | valori: terms, posting_rules, privacy, cookies |
version | version | integer | da | |
title | title | string | da | max. 200 caractere |
summary | summary | text | da | |
content | content | json | da | |
material | material | boolean | da | |
status | status | enum | da | valori: draft, published |
publishedAt | published_at | datetime | nu | |
effectiveAt | effective_at | datetime | nu | |
createdBy | created_by_id | → StaffMember | nu | relație n:1 |
publishedBy | published_by_id | → StaffMember | nu | relație n:1 |
Indecși: unic (kind, version).
LegalReminder (legal_reminders)
Fiecare notificare trimisă despre o versiune nouă (anunț, cu o săptămână înainte, amintiri 1–4): o singură dată pe persoană și etapă.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
document | document_id | → LegalDocument | da | relație n:1 |
stage | stage | string | da | max. 20 caractere |
Indecși: unic (user, document, stage).
Suport
Tichete, mesajele lor și răspunsurile salvate ale echipei.
SavedReply (saved_replies)
Răspuns salvat, refolosit de echipa de suport.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
title | title | string | da | max. 120 caractere |
topic | topic | enum | nu | valori: order_problem, account_and_login, payments_and_invoices, report_user_or_listing, other |
body | body | text | da |
SupportTicket (support_tickets)
Un tichet de suport deschis din pagina de contact: subiectul, prioritatea, starea, cine răspunde.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
code | code | string | da | unic; max. 20 caractere |
user | user_id | → User | nu | relație n:1 |
email | email | string | da | max. 190 caractere |
senderName | sender_name | string | da | max. 120 caractere |
topic | topic | enum | da | valori: order_problem, account_and_login, payments_and_invoices, report_user_or_listing, other |
subject | subject | string | da | max. 200 caractere |
order | order_id | → Order | nu | relație n:1 |
status | status | enum | da | valori: open, awaiting_customer, resolved, closed |
priority | priority | enum | da | valori: high, normal |
assignedTo | assigned_to_id | → StaffMember | nu | relație n:1 |
firstRepliedAt | first_replied_at | datetime | nu | |
lastMessageAt | last_message_at | datetime | nu | |
resolvedAt | resolved_at | datetime | nu |
Indecși: unic (code); (status, priority, createdAt).
TicketMessage (ticket_messages)
Un mesaj într-un tichet: de la client, răspunsul echipei sau o notă internă.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
ticket | ticket_id | → SupportTicket | da | relație n:1 |
author | author_id | → StaffMember | nu | relație n:1 |
isInternal | is_internal | boolean | da | |
body | body | text | da |
CRM
Profiluri de marketing, acorduri, segmente, campanii, automatizări, cupoane.
Automation (automations)
O secvență de mesaje declanșată de un eveniment (cont nou, comandă finalizată…), cu pașii ei.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
name | name | string | da | max. 160 caractere |
trigger | trigger | enum | da | valori: account_created, listing_expired, checkout_abandoned, saved_search_match, order_completed, no_visit_30_days, favourite_added, first_listing_published |
status | status | enum | da | valori: draft, active, paused |
steps | steps | json | da | |
stats | stats | json | da | |
createdBy | created_by_id | → StaffMember | nu | relație n:1 |
AutomationEnrollment (automation_enrollments)
Parcursul unei persoane printr-o automatizare: pasul următor și când rulează.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
automation | automation_id | → Automation | da | relație n:1 |
user | user_id | → User | da | relație n:1 |
stepIndex | step_index | integer | da | |
status | status | enum | da | valori: active, completed, exited |
nextRunAt | next_run_at | datetime | da | |
messagesSent | messages_sent | integer | da |
Indecși: unic (automation, user); (status, nextRunAt).
Campaign (campaigns)
O campanie de marketing pe un canal, către un segment: conținutul, programarea și rezultatele (inclusiv motivele pentru care unii nu au primit mesajul).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
name | name | string | da | max. 160 caractere |
channel | channel | enum | da | valori: email, push, sms |
goal | goal | enum | da | valori: reactivation, promotion_sales, activation, information |
segment | segment_id | → Segment | da | relație n:1 |
excludedSegment | excluded_segment_id | → Segment | nu | relație n:1 |
template | template_id | → MessageTemplate | nu | relație n:1 |
content | content | json | da | |
abTest | ab_test | json | nu | |
status | status | enum | da | valori: draft, scheduled, sending, sent, cancelled |
sendMode | send_mode | enum | da | valori: now, scheduled, optimal_time |
scheduledAt | scheduled_at | datetime | nu | |
sentAt | sent_at | datetime | nu | |
stats | stats | json | nu | |
createdBy | created_by_id | → StaffMember | nu | relație n:1 |
Indecși: (status, scheduledAt).
CampaignDelivery (campaign_deliveries)
Livrarea unei campanii către o persoană; folosită și pentru plafoanele de frecvență.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
campaign | campaign_id | → Campaign | da | relație n:1 |
user | user_id | → User | da | relație n:1 |
status | status | enum | da | valori: sent, delivered, bounced |
variant | variant | string | nu | max. 1 caractere |
openedAt | opened_at | datetime | nu | |
clickedAt | clicked_at | datetime | nu | |
convertedAt | converted_at | datetime | nu |
Indecși: unic (campaign, user); (user, createdAt).
ConsentEvent (consent_events)
Dovada legală a unui acord dat sau retras (canal, sursă, IP). Doar se adaugă, nu se modifică.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
channel | channel | enum | da | valori: email, push, sms |
action | action | enum | da | valori: granted, withdrawn |
source | source | enum | da | valori: signup_form, account_settings, in_app_banner, unsubscribe_link, sms_stop_reply, internal |
recordedBy | recorded_by_id | → StaffMember | nu | relație n:1 |
ipAddress | ip_address | string | nu | max. 45 caractere |
Indecși: (createdAt); (user, createdAt).
Coupon (coupons)
Cod de reducere: livrare gratuită, credit la comandă sau procent la promovare; limite, expirare, segment.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
code | code | string | da | unic; max. 30 caractere |
type | type | enum | da | valori: free_delivery, percent_off_promotion, credit |
value | value | integer | da | |
maxUses | max_uses | integer | nu | |
usedCount | used_count | integer | da | |
segment | segment_id | → Segment | nu | relație n:1 |
expiresAt | expires_at | datetime | nu | |
status | status | enum | da | valori: active, stopped, expired |
createdBy | created_by_id | → StaffMember | nu | relație n:1 |
Indecși: unic (code).
CouponRedemption (coupon_redemptions)
O folosire a unui cupon, legată de comandă când e cazul.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
coupon | coupon_id | → Coupon | da | relație n:1 |
user | user_id | → User | da | relație n:1 |
order | order_id | → Order | nu | relație n:1 |
discountBani | discount_bani | integer | da | sumă în bani |
Indecși: unic (coupon, user, order).
CrmProfile (crm_profiles)
Profilul de marketing al unui client: etapa (înscris recent, vânzător activ…), scorul de implicare, etichetele și acordurile pe canale.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
user | user_id | → User | da | relație n:1 |
stage | stage | enum | da | valori: new_signup, active_buyer, active_seller, inactive_seller, at_risk |
engagementScore | engagement_score | integer | da | |
tags | tags | json | da | |
emailOptIn | email_opt_in | boolean | da | |
pushOptIn | push_opt_in | boolean | da | |
smsOptIn | sms_opt_in | boolean | da | |
lastCampaignAt | last_campaign_at | datetime | nu | |
lifetimeValueBani | lifetime_value_bani | integer | da | sumă în bani |
Indecși: (stage); unic (user).
MessageTemplate (message_templates)
Text refolosit de automatizări și campanii (e-mail, push sau SMS).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
name | name | string | da | max. 120 caractere |
channel | channel | enum | da | valori: email, push, sms |
subject | subject | string | nu | max. 200 caractere |
title | title | string | nu | max. 200 caractere |
body | body | text | da | |
buttonText | button_text | string | nu | max. 80 caractere |
buttonColor | button_color | string | nu | max. 20 caractere |
updatedBy | updated_by_id | → StaffMember | nu | relație n:1 |
Segment (segments)
Grup dinamic de clienți definit prin reguli (număr de anunțuri, cumpărături, zile de la ultima vizită, acorduri…).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
name | name | string | da | unic; max. 120 caractere |
description | description | string | nu | max. 255 caractere |
matchMode | match_mode | enum | da | valori: all, any |
rules | rules | json | da | |
isSystem | is_system | boolean | da | |
cachedContactCount | cached_contact_count | integer | da | |
lastEvaluatedAt | last_evaluated_at | datetime | nu |
Indecși: unic (name).
SuppressedEmail (suppressed_emails)
Adresă care nu primește niciodată e-mailuri de marketing (cerere scrisă, adresă inexistentă, reclamație…).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
email | email | string | da | unic; max. 190 caractere |
reason | reason | enum | da | valori: hard_bounce, spam_complaint, unsubscribed_all, repeated_soft_bounce, gdpr_erasure, written_request, wrong_address, complaint |
addedBy | added_by_id | → StaffMember | nu | relație n:1 |
Indecși: unic (email).
Platformă
Setări, jurnal de audit, note interne ale echipei.
AuditLog (audit_logs)
Cine ce a făcut în Backoffice și CRM: acțiunea, subiectul și detaliile (de exemplu valoarea veche și cea nouă a unei setări).
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
actor | actor_id | → StaffMember | nu | relație n:1 |
action | action | string | da | max. 80 caractere |
subjectType | subject_type | string | da | max. 40 caractere |
subjectId | subject_id | integer | nu | |
subjectLabel | subject_label | string | nu | max. 200 caractere |
details | details | json | nu | |
ipAddress | ip_address | string | nu | max. 45 caractere |
Indecși: (createdAt); (subjectType, subjectId).
InternalNote (internal_notes)
Notă internă a echipei despre un client sau o comandă.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
author | author_id | → StaffMember | da | relație n:1 |
subjectType | subject_type | enum | da | valori: user, order, listing |
subjectId | subject_id | integer | da | |
body | body | text | da |
Indecși: (subjectType, subjectId).
PlatformSetting (platform_settings)
O setare a platformei (comisioane, reguli pentru anunțuri, pachete de promovare, setări CRM), ca JSON validat.
| Câmp | Coloană | Tip | Obligatoriu | Observații |
|---|---|---|---|---|
id | id | integer | da | cheie primară |
createdAt | created_at | datetime | da | |
updatedAt | updated_at | datetime | da | |
key | key | string | da | unic; max. 80 caractere |
value | value | json | da | |
updatedBy | updated_by_id | → StaffMember | nu | relație n:1 |
Indecși: unic (key).