rairo Claude Fable 5 commited on
Commit
4aa562c
·
1 Parent(s): 0fc7336

feat: country tag on catalogue items for locale-based grounding

Browse files

Catalogue items and tool matches carry a 2-letter country code (default
ZW). The client filters matches to the viewer country, so a supplier only
shows in its own market.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Files changed (1) hide show
  1. main.py +15 -0
main.py CHANGED
@@ -185,6 +185,11 @@ _TOOL_STOPWORDS = {'a', 'an', 'the', 'of', 'for', 'and', 'or', 'with', 'to', 'in
185
 
186
  SUPPORTED_CITIES = ['Harare', 'Bulawayo', 'Gweru', 'Mutare', 'Other']
187
 
 
 
 
 
 
188
  def _normalize_tool_name(name):
189
  """Lowercase, strip punctuation/stopwords, singularize trailing 's' for catalogue matching."""
190
  words = re.sub(r"[^a-z0-9\s]", " ", (name or "").lower()).split()
@@ -229,6 +234,7 @@ def match_tools_to_catalogue(tools_list):
229
  'currency': item.get('currency', 'USD'),
230
  'supplier': item.get('supplier', 'Electrosales'),
231
  'city': item.get('city', 'Harare'),
 
232
  'imageUrl': item.get('imageUrl', ''),
233
  })
234
  return matches
@@ -1079,6 +1085,9 @@ def _build_catalogue_item(data, admin_uid):
1079
  if isinstance(extra, str):
1080
  tokens |= set(_normalize_tool_name(extra).split())
1081
 
 
 
 
1082
  return {
1083
  'name': name,
1084
  'normalizedName': normalized,
@@ -1087,6 +1096,7 @@ def _build_catalogue_item(data, admin_uid):
1087
  'currency': (data.get('currency') or 'USD').upper(),
1088
  'supplier': (data.get('supplier') or 'Electrosales').strip(),
1089
  'city': data.get('city') if data.get('city') in SUPPORTED_CITIES else 'Harare',
 
1090
  'category': (data.get('category') or 'General').strip(),
1091
  'imageUrl': data.get('imageUrl') or '',
1092
  'inStock': bool(data.get('inStock', True)),
@@ -1239,6 +1249,11 @@ def admin_update_catalogue_item(item_id):
1239
  if data['city'] not in SUPPORTED_CITIES:
1240
  return jsonify({'error': f'city must be one of: {", ".join(SUPPORTED_CITIES)}'}), 400
1241
  updates['city'] = data['city']
 
 
 
 
 
1242
  if 'inStock' in data:
1243
  updates['inStock'] = bool(data['inStock'])
1244
  if not updates:
 
185
 
186
  SUPPORTED_CITIES = ['Harare', 'Bulawayo', 'Gweru', 'Mutare', 'Other']
187
 
188
+ # Country a supplier's catalogue serves. The client detects the viewer's country
189
+ # (timezone/IP) and only surfaces catalogues for their country; everyone else
190
+ # gets the generic tools list. Add a code here when onboarding a new market.
191
+ DEFAULT_CATALOGUE_COUNTRY = 'ZW'
192
+
193
  def _normalize_tool_name(name):
194
  """Lowercase, strip punctuation/stopwords, singularize trailing 's' for catalogue matching."""
195
  words = re.sub(r"[^a-z0-9\s]", " ", (name or "").lower()).split()
 
234
  'currency': item.get('currency', 'USD'),
235
  'supplier': item.get('supplier', 'Electrosales'),
236
  'city': item.get('city', 'Harare'),
237
+ 'country': item.get('country', DEFAULT_CATALOGUE_COUNTRY),
238
  'imageUrl': item.get('imageUrl', ''),
239
  })
240
  return matches
 
1085
  if isinstance(extra, str):
1086
  tokens |= set(_normalize_tool_name(extra).split())
1087
 
1088
+ raw_country = (data.get('country') or DEFAULT_CATALOGUE_COUNTRY).strip().upper()
1089
+ country = raw_country if len(raw_country) == 2 else DEFAULT_CATALOGUE_COUNTRY
1090
+
1091
  return {
1092
  'name': name,
1093
  'normalizedName': normalized,
 
1096
  'currency': (data.get('currency') or 'USD').upper(),
1097
  'supplier': (data.get('supplier') or 'Electrosales').strip(),
1098
  'city': data.get('city') if data.get('city') in SUPPORTED_CITIES else 'Harare',
1099
+ 'country': country,
1100
  'category': (data.get('category') or 'General').strip(),
1101
  'imageUrl': data.get('imageUrl') or '',
1102
  'inStock': bool(data.get('inStock', True)),
 
1249
  if data['city'] not in SUPPORTED_CITIES:
1250
  return jsonify({'error': f'city must be one of: {", ".join(SUPPORTED_CITIES)}'}), 400
1251
  updates['city'] = data['city']
1252
+ if 'country' in data:
1253
+ country = (data.get('country') or '').strip().upper()
1254
+ if len(country) != 2:
1255
+ return jsonify({'error': 'country must be a 2-letter ISO code'}), 400
1256
+ updates['country'] = country
1257
  if 'inStock' in data:
1258
  updates['inStock'] = bool(data['inStock'])
1259
  if not updates: