5.6 KiB
Project: V3 Lookup Bug Fix — Timezone Group Data + PARTITION BY Revert
Status: 🔧 Action Required Date: 2026-03-23 Related doc:
PROJECT__V3_UNIFORM_LOOKUP_SYSTEM.mdReported by: Frontend Agent (Scott Idem / One Sky IT)
1. Summary
Two bugs were discovered in the V3 Uniform Lookup System during IDAA Recovery Meetings
timezone dropdown testing. They stem from a single root cause: the lu_v3_time_zone
table was seeded with regional group values ("United States", "Europe") instead of
individual timezone names — contrary to the design specified in Phase 2 of the lookup
architecture doc, which explicitly states lu_v3_time_zone (Group: name).
An attempted fix changed PARTITION BY group to PARTITION BY name in
get_lookup_list_v3(). This unintentionally broke country deduplication, which depends
on PARTITION BY group being correct (country group = alpha_2_code, e.g. "US").
2. Root Cause
2.1 Timezone group values were set to regional names instead of timezone names
The lu_v3_time_zone table has two groups where multiple records share a single group value:
group value |
Count | Example records |
|---|---|---|
United States |
13 | US/Alaska, US/Arizona, US/Central, US/East-Indiana, US/Eastern, US/Hawaii, US/Indiana-Starke, US/Michigan, US/Mountain, US/Pacific, US/Pacific-New, US/Samoa, US/Aleutian |
Europe |
63 | Europe/London, Europe/Paris, Europe/Prague, Europe/Rome, ... (all Europe/* zones) |
All other timezone records already have group = name (e.g., Canada/Eastern has
group = "Canada/Eastern"). The US and Europe records were loaded incorrectly.
Effect: PARTITION BY group collapsed all 13 US/* records into a single winner and
all 63 Europe/* records into a single winner. Only ~7 distinct US timezones and 1 Europe
timezone appeared in the dropdown instead of all 76.
2.2 Attempted fix broke country lookup deduplication
Changing PARTITION BY group → PARTITION BY name in get_lookup_list_v3() fixed the
timezone collapse but broke lu_v3_country.
lu_v3_country has (at minimum) two records for alpha_2_code = "US":
id=240: global default (account_id=NULL),group="US"id=251: account-specific (account_id=1),group="US"
With PARTITION BY group, both records share group="US" and are correctly deduped —
the account-specific record wins per the override hierarchy. With PARTITION BY name,
if the two records have different name values they are treated as separate identities
and both survive, resulting in duplicate alpha_2_code="US" entries in the API response.
The frontend's {#each lu_country_list as country (country.alpha_2_code)} then throws:
Svelte error: each_key_duplicate — Keyed each block has duplicate key 'US'
The same risk applies to lu_v3_country_subdivision.
3. Correct Fix (Two Steps)
Step 1 — Revert app/methods/lookup_methods.py
Change PARTITION BY name back to PARTITION BY group:
# lookup_methods.py — get_lookup_list_v3()
ROW_NUMBER() OVER (
PARTITION BY `group` # <-- revert to this
ORDER BY
(for_type = :for_type AND for_id = :for_id) DESC,
(account_id = :account_id) DESC,
created_on DESC
) as rank_priority
This restores correct behavior for all three active V3 lookup types
(country, country_subdivision, time_zone).
Step 2 — Fix the lu_v3_time_zone data
Set group = name for all records where the group is a regional label rather than the
timezone's own name. Run once against the database:
UPDATE lu_v3_time_zone
SET `group` = `name`
WHERE `group` IN ('United States', 'Europe');
Verification:
-- Should return 0 rows after the fix
SELECT `group`, COUNT(*) as cnt
FROM lu_v3_time_zone
GROUP BY `group`
HAVING cnt > 1;
4. Why PARTITION BY group Is Correct
As documented in PROJECT__V3_UNIFORM_LOOKUP_SYSTEM.md (Section 2.1):
group: The primary business key/cluster key. Note: Must be populated for hierarchy to work.
The group field IS the deduplication identity. Each lookup type uses a different natural
key for group:
| Lookup type | group field |
Example |
|---|---|---|
country |
alpha_2_code |
"US", "CA", "GB" |
country_subdivision |
code |
"US-NY", "CA-ON" |
time_zone |
name (= the IANA timezone identifier) |
"US/Eastern", "Europe/London" |
For time_zone, group and name are intended to be the same value — each timezone
is its own identity. There is no meaningful concept of "override all US timezones as a
group." Each one is individually addressable.
5. Regression Tests to Add / Update
test_timezone_us_dedup()— assert all 13 US/* priority zones are present individuallytest_timezone_europe_dedup()— assert all Europe/* priority zones present individuallytest_country_us_dedup()— assert only onealpha_2_code="US"record returned; account-specific override wins over global default- General:
GET /v3/lookup/time_zone/list?only_priority=trueshould return exactly 72 records (the current count of priority=1 enabled timezones)
6. What Was NOT Changed (and Should Not Be)
- The endpoint signature for
GET /v3/lookup/{lu_type}/list— it does not and should not exposelimit,offset, ororder_by_liquery params. The frontend sends these but they are correctly ignored. The sort order is hardcoded and correct:ORDER BY COALESCE(priority, 0) DESC, COALESCE(sort, 0) DESC, name ASC - Country and country_subdivision data — no changes needed to those tables
- Frontend code — no backend-side changes are needed on the frontend for this fix