{
  "document_version": 1,
  "updated_at": "2026-09-22",
  "application": "ValiMake",
  "component": "Open Beauty Facts local brand suggestion component",
  "component_license": "ODbL-1.0",
  "input": {
    "url": "https://world.openbeautyfacts.org/facets/brands.json",
    "database_license": "https://opendatacommons.org/licenses/odbl/1-0/",
    "contents_license": "https://opendatacommons.org/licenses/dbcl/1-0/"
  },
  "reproducible_method": "https://valimake-app.web.app/data/build-obf-brand-catalog.mjs",
  "method": {
    "http_method": "GET",
    "query_parameters": ["page", "page_size"],
    "page_size": 1000,
    "minimum_delay_between_pages_seconds": 7,
    "refresh_interval_days": 30,
    "selected_field": "tags[].name",
    "cleaning": [
      "trim leading and trailing whitespace",
      "collapse consecutive whitespace",
      "reject empty names and names longer than 120 UTF-16 code units",
      "reject case-insensitive placeholders: null, unknown, sem marca, no brand, not a brand, n/a"
    ],
    "deduplication": "first cleaned display name for each normalized key",
    "output": "UTF-8 JSON array with name and normalized_name, sorted by normalized_name in UTF-16 code-unit order"
  },
  "on_device_sync": {
    "checkpoint": "each accepted page and its next-page marker are committed in one SQLite transaction",
    "refresh": "new pages are staged separately; the active Open Beauty Facts table is replaced atomically only after a complete download",
    "interruption": "the prior complete table remains searchable; an interrupted staged download resumes from its SQLite checkpoint",
    "historical_reproduction": "the script rebuilds from the live public endpoint; without a frozen upstream snapshot it cannot reproduce an earlier device-specific download byte for byte"
  },
  "separation": {
    "open_beauty_facts_table": "obf_brand_terms",
    "wikidata_table": "wikidata_brand_terms",
    "independent_seed_table": "seed_brand_terms",
    "private_user_table": "user_brand_terms",
    "combination": "independent tables are queried and deduplicated in memory only for display"
  }
}
