diff --git a/implementation/auditing/audit_engine.py b/implementation/auditing/audit_engine.py index b2ff25a..351317e 100644 --- a/implementation/auditing/audit_engine.py +++ b/implementation/auditing/audit_engine.py @@ -63,12 +63,14 @@ def _normalize_phone(phone): def _normalize_address(addr): - """Lowercase, strip extra whitespace, remove suite abbrev variances.""" + """Lowercase, strip extra whitespace, remove suite abbrev variances, drop commas.""" if not addr: return "" s = re.sub(r'[\U000E0000-\U000EFFFF]', '', addr or '') s = re.sub(r'\s+', ' ', s.strip().lower()) s = re.sub(r'\bst[e]*\.?\b', 'ste', s) + s = re.sub(r'\bsuite\b', 'ste', s) + s = s.replace(',', '') # ponytail: comma is pure formatting, not a material diff return s @@ -393,6 +395,31 @@ def check_review_text_quality(contract): return findings +# ponytail: small explicit synonym map; extend when new variants appear in the wild +_CATEGORY_SYNONYMS = { + "beauty salon": "beauty salon", + "beauty and spa": "beauty salon", + "beauty & spa": "beauty salon", + "beauty & spa": "beauty salon", + "salon and spa": "beauty salon", + "hair salon": "hair salon", + "hair & beauty salon": "hair salon", + "hair and beauty salon": "hair salon", + "day spa": "day spa", + "spa": "spa", + "medical spa": "medical spa", + "barber shop": "barber shop", + "barbershop": "barber shop", +} + + +def _normalize_category(cat): + if not cat: + return "" + c = re.sub(r'\s+', ' ', cat.strip().lower()).replace('&', '&') + return _CATEGORY_SYNONYMS.get(c, c) + + def check_category_alignment(contract): """Category consistency and fragmentation across surfaces.""" findings = [] @@ -403,7 +430,7 @@ def check_category_alignment(contract): data = _safe_get(contract, "sources", src_data, default={}) cat = data.get('category') if cat: - categories[src_name] = cat.lower().strip() + categories[src_name] = _normalize_category(cat) if len(categories) < 2: return findings