Skip to main content

SOS Architecture & Data Model

System Overview​

Seller SOS chαΊ‘y nhΖ° mα»™t Cloudflare Workers application Δ‘α»™c lαΊ­p sα»­ dα»₯ng framework Hono, kαΊΏt nα»‘i Δ‘αΊΏn Supabase (PostgreSQL). Module nhαΊ­n dα»― liệu tα»« nhiều nguα»“n (OMS, WMS, Helpdesk, Accounting), tΓ­nh toΓ‘n Δ‘iểm SOS, vΓ  dispatch webhook events Δ‘αΊΏn cΓ‘c hệ thα»‘ng subscriber.

Architecture Diagram​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ External Systems (Data Sources) β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ OMS β”‚ β”‚ WMS β”‚ β”‚ Helpdesk β”‚ β”‚ Accounting System β”‚ β”‚
β”‚ β”‚ Orders β”‚ β”‚Inventoryβ”‚ β”‚ Tickets β”‚ β”‚ Payments & Revenue β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ POST /api/sync/* β”‚
β”‚ β–Ό β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Boxme SOS (Cloudflare Workers + Hono) β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ Auth & β”‚ β”‚ Scoring Engine β”‚ β”‚ Webhook Dispatcher β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ RBAC β”‚ β”‚ P/O/T/F/I calc β”‚ β”‚ HMAC-SHA256 signed β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β–Ό β–Ό β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Supabase (PostgreSQL) β”‚ β”‚ Webhook Subscribers β”‚ β”‚
β”‚ β”‚ ~25 SOS tables β”‚ β”‚ (WMS, OMS, BI, Alerts) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow​

1. External systems push data β†’ POST /api/sync/*
β”œβ”€β”€ /sync/orders β†’ sos_order_operation_raw
β”œβ”€β”€ /sync/forecasts β†’ seller_forecast_submission
β”œβ”€β”€ /sync/campaign-actuals β†’ campaign_actual_result
β”œβ”€β”€ /sync/tickets β†’ sos_ticket_sla_raw
β”œβ”€β”€ /sync/payments β†’ sos_payment_raw
β”œβ”€β”€ /sync/inventory β†’ sos_inventory_health_raw
└── /sync/revenue β†’ am_portfolio_period_score

2. Admin triggers scoring β†’ POST /api/sos/monthly/calculate
└── Scoring Engine reads raw data + config tables
β”œβ”€β”€ calcPScore() β†’ sos_planning_raw + sos_p_score_config
β”œβ”€β”€ calcOScore() β†’ sos_order_operation_raw + sos_o_score_config
β”œβ”€β”€ calcTScore() β†’ sos_ticket_sla_raw + sos_t_score_config
β”œβ”€β”€ calcFScore() β†’ sos_payment_raw + sos_f_score_config
└── calcIScore() β†’ sos_inventory_health_raw + sos_i_score_config
└── Results β†’ seller_sos_period_score (status: draft)

3. Admin finalizes β†’ PATCH /api/sos/monthly/:id/finalize
└── Webhook Dispatcher β†’ seller.score_finalized event
└── If tier changed β†’ seller.tier_changed event

4. Surcharges/Appeals β†’ Webhook events dispatched automatically

Project Structure​

seller-sos/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ index.tsx # Main entry, static assets, SPA shell
β”‚ β”œβ”€β”€ routes/
β”‚ β”‚ β”œβ”€β”€ api.ts # Route aggregator (mounts all sub-routes)
β”‚ β”‚ β”œβ”€β”€ auth.ts # Login, session verify, password update
β”‚ β”‚ β”œβ”€β”€ sellers.ts # Seller CRUD, exceptions, AMs
β”‚ β”‚ β”œβ”€β”€ campaigns.ts # Campaign CRUD, forecasts, actuals
β”‚ β”‚ β”œβ”€β”€ scores.ts # SOS score endpoints, finalize, calculate
β”‚ β”‚ β”œβ”€β”€ appeals.ts # Appeal CRUD, 2-level review
β”‚ β”‚ β”œβ”€β”€ webhooks.ts # Webhook subscription management
β”‚ β”‚ β”œβ”€β”€ dashboard.ts # Dashboard statistics
β”‚ β”‚ β”œβ”€β”€ surcharges.ts # Surcharge records
β”‚ β”‚ β”œβ”€β”€ sync.ts # Data sync push endpoints
β”‚ β”‚ β”œβ”€β”€ config.ts # 11 config table CRUD (factory pattern)
β”‚ β”‚ └── am.ts # AM portfolio scores
β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”œβ”€β”€ scoring.ts # P/O/T/F/I scoring engine
β”‚ β”‚ β”œβ”€β”€ webhook-dispatcher.ts # HMAC signing + retry delivery
β”‚ β”‚ β”œβ”€β”€ supabase.ts # Supabase client factory
β”‚ β”‚ └── d1_wrapper.ts # D1-compatible wrapper over Supabase
β”‚ └── types/
β”‚ └── index.ts # TypeScript type definitions
β”œβ”€β”€ migrations/
β”‚ β”œβ”€β”€ 0001_sos_schema.sql # Full schema (~25 tables)
β”‚ └── 0002_sample_data.sql # Sample data for testing
β”œβ”€β”€ public/static/ # Frontend assets
β”œβ”€β”€ tests/ # Vitest test suites
β”œβ”€β”€ wrangler.jsonc # Cloudflare Workers config
└── vite.config.ts # Build config

Database Tables​

Seller Core​

TableDescription
sellerMaster data: seller_code, company_name, contract, warehouse, AM
account_managerAM profiles linked to sellers
campaignSales campaigns (major/mini) with date ranges
seller_forecast_submissionSeller forecast volumes per campaign
campaign_actual_resultActual order volumes post-campaign

Score Data (Raw)​

TableSourceDescription
sos_planning_rawScoring EngineP-Score aggregated planning data
sos_order_operation_rawOMS SyncO-Score order timing raw data
sos_ticket_sla_rawHelpdesk SyncT-Score ticket response metrics
sos_payment_rawAccounting SyncF-Score payment timeliness
sos_inventory_health_rawWMS SyncI-Score inventory aging data

Score Results​

TableDescription
seller_sos_period_scoreMonthly SOS scores (P/O/T/F/I raw + weighted + total)
seller_score_exceptionScore overrides for specific sellers/components
seller_sos_appealAppeal records with 2-level review workflow
seller_surcharge_recordSurcharge records triggered by SOS rules

Configuration​

TableDescription
sos_score_weight_configComponent weight percentages
sos_tier_configTier definitions (name, score range, color, benefits)
sos_p_score_configP-Score calculation parameters
sos_o_score_configO-Score thresholds and penalties
sos_t_score_configT-Score SLA tier definitions
sos_f_score_configF-Score payment tier definitions
sos_i_score_configI-Score aging thresholds
sos_surcharge_configSurcharge trigger rules
sos_am_bonus_penalty_configAM bonus/penalty rules based on SOS delta
am_kpi_weight_configAM KPI component weights
seller_grace_period_configGrace period settings for new sellers
frappe_helpdesk_configFrappe Helpdesk integration settings

Webhook​

TableDescription
webhook_subscriptionActive webhook subscribers
webhook_delivery_logDelivery attempts with status and response

AM Performance​

TableDescription
am_portfolio_period_scoreAM monthly KPI scores

Tech Stack​

LayerTechnology
RuntimeCloudflare Workers (Edge)
FrameworkHono v4.x
DatabaseSupabase (PostgreSQL)
FrontendVanilla JS + CSS
BuildVite + @hono/vite-build
TestingVitest
DeployWrangler CLI + Cloudflare Pages