Database Schema

SQLite 3 · WAL mode · FTS5 · Foreign keys enforced — 38 tables total

Core Tables

users Registered user accounts and subscription details
ColumnTypeConstraints
idTEXTPK
emailTEXTUNIQUENOT NULL
password_hashTEXTNOT NULL
usernameTEXTUNIQUENOT NULL
full_nameTEXT
avatar_urlTEXT
subscription_tierTEXTDEFAULT 'free' CHECK (free | starter | pro | business)
subscription_expires_atDATETIME
timezoneTEXTDEFAULT 'America/New_York'
localeTEXTDEFAULT 'en-US'
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
last_login_atDATETIME
is_activeINTEGERDEFAULT 1
preferencesTEXTDEFAULT '{}' JSON blob
onboarding_completedINTEGERDEFAULT 0
Indexes
idx_users_email ON users(email)
idx_users_username ON users(username)
sessions Refresh token sessions for JWT auth
ColumnTypeConstraints
idTEXTPK
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
refresh_tokenTEXTUNIQUENOT NULL
device_infoTEXT
ip_addressTEXT
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
expires_atDATETIMENOT NULL
is_validINTEGERDEFAULT 1
Indexes
idx_sessions_user_id ON sessions(user_id)
idx_sessions_refresh_token ON sessions(refresh_token)
inventory Master catalog of InventoryItems; source of truth for all Listings
ColumnTypeConstraints
idTEXTPK
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
skuTEXT
titleTEXTNOT NULL
descriptionTEXT
brandTEXT
categoryTEXT
subcategoryTEXT
sizeTEXT
colorTEXT
conditionTEXTCHECK (new | like_new | good | fair | poor)
cost_priceREALDEFAULT 0
list_priceREALNOT NULL
quantityINTEGERDEFAULT 1
low_stock_thresholdINTEGERDEFAULT 5
weightREAL
dimensionsTEXT
materialTEXT
tagsTEXTDEFAULT '[]' JSON array
imagesTEXTDEFAULT '[]' JSON array of URLs
thumbnail_urlTEXT
statusTEXTDEFAULT 'draft' CHECK (draft | active | sold | archived | deleted)
locationTEXT
notesTEXT
blockchain_hashTEXT
sustainability_scoreREAL
ai_generated_dataTEXTDEFAULT '{}' JSON blob
custom_fieldsTEXTDEFAULT '{}' JSON blob
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
Indexes
idx_inventory_user_id ON inventory(user_id)
idx_inventory_status ON inventory(status)
idx_inventory_sku ON inventory(sku)
FTS5 Virtual Table
inventory_fts — content=inventory; indexes title, description, brand, tags. Kept in sync via INSERT/UPDATE/DELETE triggers.
listings Platform-specific Listings derived from an InventoryItem
ColumnTypeConstraints
idTEXTPK
inventory_idTEXTFK → inventory.idNOT NULL ON DELETE CASCADE
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
platformTEXTNOT NULL
platform_listing_idTEXT
platform_urlTEXT
titleTEXTNOT NULL
descriptionTEXT
priceREALNOT NULL
original_priceREAL
shipping_priceREALDEFAULT 0
category_pathTEXT
condition_tagTEXT
statusTEXTDEFAULT 'draft' CHECK (draft | pending | active | sold | ended | error | archived)
imagesTEXTDEFAULT '[]' JSON array
platform_specific_dataTEXTDEFAULT '{}' JSON blob
viewsINTEGERDEFAULT 0
likesINTEGERDEFAULT 0
sharesINTEGERDEFAULT 0
last_shared_atDATETIME
last_bumped_atDATETIME
listed_atDATETIME
sold_atDATETIME
error_messageTEXT
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
Unique Constraint
UNIQUE(inventory_id, platform) — one listing per platform per item
Indexes
idx_listings_user_id, idx_listings_inventory_id, idx_listings_platform, idx_listings_status
sales Completed Sales and order tracking
ColumnTypeConstraints
idTEXTPK
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
listing_idTEXTFK → listings.id ON DELETE SET NULL
inventory_idTEXTFK → inventory.id ON DELETE SET NULL
platformTEXTNOT NULL
platform_order_idTEXT
buyer_usernameTEXT
buyer_addressTEXT
sale_priceREALNOT NULL
platform_feeREALDEFAULT 0
shipping_costREALDEFAULT 0
tax_amountREALDEFAULT 0
net_profitREALComputed: sale_price − platform_fee − shipping_cost − cost_price
statusTEXTDEFAULT 'pending' CHECK (pending | confirmed | shipped | delivered | cancelled | returned)
tracking_numberTEXT
carrierTEXT
shipped_atDATETIME
delivered_atDATETIME
notesTEXT
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
Indexes
idx_sales_user_id, idx_sales_platform, idx_sales_status
offers Buyer Offers on Listings with accept/decline/counter workflow
ColumnTypeConstraints
idTEXTPK
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
listing_idTEXTFK → listings.idNOT NULL ON DELETE CASCADE
platformTEXTNOT NULL
platform_offer_idTEXT
buyer_usernameTEXT
offer_amountREALNOT NULL
counter_amountREAL
statusTEXTDEFAULT 'pending' CHECK (pending | accepted | declined | countered | expired | cancelled)
auto_actionTEXTAutomation rule that responded
responded_atDATETIME
expires_atDATETIME
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
Indexes
idx_offers_user_id, idx_offers_listing_id, idx_offers_status
shops Connected marketplace Platforms (OAuth credentials, sync state)
ColumnTypeConstraints
idTEXTPK
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
platformTEXTNOT NULL
platform_usernameTEXT
platform_user_idTEXT
credentialsTEXTAES-256-CBC encrypted JSON
is_connectedINTEGERDEFAULT 1
last_sync_atDATETIME
sync_statusTEXTDEFAULT 'idle'
settingsTEXTDEFAULT '{}' JSON blob
statsTEXTDEFAULT '{}' JSON blob
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
Unique Constraint
UNIQUE(user_id, platform) — one shop connection per platform per user
Indexes
idx_shops_user_id, idx_shops_platform
automation_rules Automation rules (scheduled Playwright bots: share, follow, offer, relist, price_drop)
ColumnTypeConstraints
idTEXTPK
user_idTEXTFK → users.idNOT NULL ON DELETE CASCADE
nameTEXTNOT NULL
typeTEXTNOT NULL CHECK (share | follow | offer | relist | price_drop | custom)
platformTEXT
is_enabledINTEGERDEFAULT 1
scheduleTEXTCron expression or interval string
conditionsTEXTDEFAULT '{}' JSON blob
actionsTEXTDEFAULT '{}' JSON blob
last_run_atDATETIME
next_run_atDATETIME
run_countINTEGERDEFAULT 0
error_countINTEGERDEFAULT 0
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP
Indexes
idx_automation_rules_user_id ON automation_rules(user_id)
Related: automation_logs table records every execution result

Remaining Tables (30)

Full schema for these tables is in src/backend/db/schema.sql.

listing_templates
automation_logs
tasks
analytics_snapshots
sustainability_log
alerts
collaborations
sync_queue
notifications
security_logs
request_logs
error_logs
audit_logs
user_preferences
inventory_fts
price_history
image_assets
tags
inventory_tags
shipping_profiles
bundles
bundle_items
returns
messages
webhooks
webhook_deliveries
api_keys
reports
rum_metrics
feature_flags

Indexes (core tables)

Index NameTableColumns
idx_users_emailusers(email)
idx_users_usernameusers(username)
idx_sessions_user_idsessions(user_id)
idx_sessions_refresh_tokensessions(refresh_token)
idx_shops_user_idshops(user_id)
idx_shops_platformshops(platform)
idx_inventory_user_idinventory(user_id)
idx_inventory_statusinventory(status)
idx_inventory_skuinventory(sku)
idx_listings_user_idlistings(user_id)
idx_listings_inventory_idlistings(inventory_id)
idx_listings_platformlistings(platform)
idx_listings_statuslistings(status)
idx_sales_user_idsales(user_id)
idx_sales_platformsales(platform)
idx_sales_statussales(status)
idx_offers_user_idoffers(user_id)
idx_offers_listing_idoffers(listing_id)
idx_offers_statusoffers(status)
idx_automation_rules_user_idautomation_rules(user_id)

Full-Text Search

inventory_fts FTS5 virtual table backed by inventory
DetailValue
EngineFTS5 (SQLite built-in)
Content tableinventory
Content rowidrowid
Indexed columnsid, title, description, brand, tags
Sync triggersinventory_ai (INSERT), inventory_au (UPDATE), inventory_ad (DELETE)
UsageSELECT * FROM inventory_fts WHERE inventory_fts MATCH 'query'
Back to VaultLister