Skip to main content

Dashboard Data Architecture

Overview​

The FinMatch Admin Dashboard uses a hybrid architecture:

  • READ operations → Merchant API (GET /api/merchants, session-auth)
  • WRITE operations → Merchant API (validation, atomic writes)

The live merchants file is not on the public website bucket.

Data Sources​

Source of Truth​

File: gs://finmatch-secrets/merchants.json
Writer: merchant-api only (MERCHANTS_JSON_BUCKET)
Public copy: deleted. Do not document or fetch gs://finmatch-shared/merchants.json. Canonical map: Source of Truth.

This is the single source of truth for all merchant data. It contains:

{
"profiles": {
"M000101": {
"finmatchId": "M000101",
"merchantName": "Company Name",
"companyName": "Company Name",
"domain": "https://example.com",
"environment": "p",
"merchantStatus": "suspended",
...
},
"FM-0294-8617-5039": {
"finmatchId": "FM-0294-8617-5039",
"merchantName": "Legacy Merchant Ltd",
...
}
},
"versionStamp": "Updated: 2025-01-09T12:00:00.000Z"
}

Dashboard Data Flow​

Merchant Count​

Dashboard home card
tries leftover public finmatch-shared/merchants.json (404)
falls back to GET /api/merchants → merchants[].length

The leftover public fetch is a bug leftover in admin/index.html, not a supported read path. Do not restore a public merchants.json.

Fallback Mechanism​

The home card always needs the API fallback now that the public object is gone:

Dashboard → Merchant API → gs://finmatch-secrets/merchants.json → Count

Read vs Write Operations​

READ Operations (Merchant API)​

The browser cannot read finmatch-secrets. Admin pages load merchant lists and detail through merchant-api:

  • Dashboard merchant count (GET /api/merchants, after the leftover public 404)
  • Merchants table
  • Merchant detail view
  • Search and filter

WRITE Operations (Via API)​

These operations go through the Merchant API for validation and atomic writes:

  • ✅ Create merchant - Needs ID generation, validation
  • ✅ Update merchant - Needs validation, atomic writes
  • ✅ Delete merchant - Needs cleanup logic
  • ✅ Link Stripe - Needs business logic
  • ✅ Switch environment - Needs validation

Benefits:

  • Validation and error handling
  • Atomic writes (prevents data corruption)
  • Business logic enforcement
  • Retry logic for concurrent updates

Performance Considerations​

Caching​

The dashboard doesn't implement client-side caching for merchant count because:

  • The count changes when merchants are added or deleted
  • The home card uses cache: 'no-store' plus a cache-busting query
  • Always shows current data from the API fallback

CDN Caching​

GCS files are served through Cloud CDN, which provides:

  • Edge caching for faster global access
  • Automatic cache invalidation on updates
  • Reduced latency

Security​

GCS Access​

The merchants.json file is:

  • Publicly readable - Required for direct frontend access
  • Writable only via API - Merchant API handles all writes with authentication

API Access​

The Merchant API:

  • Requires authentication for write operations
  • Validates all input data
  • Uses atomic writes to prevent data corruption
  • Implements retry logic for concurrent updates

Monitoring​

Merchant Config Integrity Alarm​

Runtime lender config drift is monitored from Merchant API:

  • Endpoint: GET /admin/merchant-config-integrity?env=p
  • Purpose: detect merchants in merchants.json (env p) missing from configs/finmatch-merchant-config.json
  • Alarm condition: report.metrics.missing_in_config > 0

Merchant Config Write Audit​

All key merchant config mutations are appended to a global audit stream:

  • Endpoint: GET /admin/merchant-config-audit?limit=100
  • Backing file: gs://finmatch-admin/monitoring/merchant-config-audit.json
  • Includes actor/source metadata so non-admin-ui writes are visible in Monitoring

Error Handling​

The dashboard handles errors gracefully:

  1. GCS access fails → Falls back to API
  2. API fails → Shows "Error" message
  3. Network timeout → Shows "Error" message

Logging​

All data access is logged:

  • GCS direct reads (browser network tab)
  • API calls (browser network tab + API logs)
  • Errors (browser console + API logs)
  • Merchant config writes (merchant history + global merchant config audit feed)

Best Practices​

  1. Always use direct GCS for reads - Faster and simpler
  2. Always use API for writes - Validation and atomicity
  3. Handle errors gracefully - Fallback to API if needed
  4. Monitor performance - Check network tab for load times
  5. Treat runtime config as protected - Never manually overwrite configs/finmatch-merchant-config.json