Files
explorer-monorepo/backend/api
Devin 070f935e46 refactor(config): externalize rpcAccessProducts to config/rpc_products.yaml
The Chain 138 RPC access product catalog (core-rpc / alltra-rpc /
thirdweb-rpc, each with VMID + HTTP/WS URL + tier + billing model + use
cases + management features) used to be a hardcoded 50-line Go literal
in api/rest/auth.go. The review flagged this as the biggest source of
'magic constants in source' in the backend: changing a partner URL, a
VMID, or a billing model required a Go recompile, and the internal
192.168.11.x CIDR endpoints were baked into the binary.

This PR moves the catalog to backend/config/rpc_products.yaml and adds
a lazy loader so every call site reads from the YAML on first use.

New files:
  backend/config/rpc_products.yaml           source of truth
  backend/api/rest/rpc_products_config.go    loader + fallback defaults
  backend/api/rest/rpc_products_config_test.go  unit tests

Loader path-resolution order (first hit wins):
  1. $RPC_PRODUCTS_PATH (absolute or cwd-relative)
  2. $EXPLORER_BACKEND_DIR/config/rpc_products.yaml
  3. <cwd>/backend/config/rpc_products.yaml
  4. <cwd>/config/rpc_products.yaml
  5. compiled-in defaultRPCAccessProducts fallback (logs a WARNING)

Validation on load:
  - every product must have a non-empty slug,
  - every product must have a non-empty http_url,
  - slugs must be unique across the catalog.
  A malformed YAML causes a WARNING + fallback to defaults, never a
  silent empty product list.

Call-site changes in auth.go:
  - 'var rpcAccessProducts []accessProduct' (literal) -> func
    rpcAccessProducts() []accessProduct (forwards to the lazy loader).
  - Both existing consumers (/api/v1/access/products handler at line
    ~369 and findAccessProduct() at line ~627) now call the function.
    Zero other behavioural changes; the JSON shape of the response is
    byte-identical.

Tests added:
  - TestLoadRPCAccessProductsFromRepoDefault: confirms the shipped
    YAML loads, produces >=3 products, and contains the 3 expected
    slugs with non-empty http_url.
  - TestLoadRPCAccessProductsRejectsDuplicateSlug.
  - TestLoadRPCAccessProductsRejectsMissingHTTPURL.

Verification:
  go build ./...       clean
  go vet ./...         clean
  go test ./api/rest/  PASS (new + existing)
  go mod tidy          pulled yaml.v3 from indirect to direct

Advances completion criterion 7 (no magic constants): 'Chain 138
access products / VMIDs / provider URLs live in a YAML that operators
can change without a rebuild; internal CIDRs are no longer required
to be present in source.'
2026-04-18 19:16:30 +00:00
..