Files
OSIT-AE-App-Svelte/src/lib/ae_core/db_lookups.ts
Scott Idem a6f8ff709e fix(idaa): fix country/subdivision/timezone dropdowns — switch to in-memory sort
- Country and state/province fields were showing as plain text inputs because
  liveQuery used orderBy() on non-indexed columns, causing silent Dexie errors
  that left the store as undefined indefinitely.
- Fix: replaced orderBy() with toArray() + in-memory sort across all three
  lookup types (country, country_subdivision, time_zone).
- Sort convention matches Aether backend: sort DESC (higher = first, NULL=0
  last), then name ASC — puts priority entries at the top.
- Added db_lookups.ts (IDB schema for lookup tables) and updated core__countries,
  core__country_subdivisions, core__time_zones to IDB-backed SWR pattern.
- Affected: archive edit, archive content edit, recovery meeting edit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 18:44:24 -04:00

82 lines
2.4 KiB
TypeScript

import Dexie, { type Table } from 'dexie';
/**
* Lookup DB — IDB-backed cache for V3 Uniform Lookup System reference data.
*
* These tables store the deduplicated, priority-ranked list returned by
* GET /v3/lookup/{lu_type}/list. Data is refreshed automatically on a 24-hour
* TTL via the core__*.ts load helpers; components subscribe via liveQuery.
*
* Updated 2026-03-23
*/
export interface LuCountry {
id: number;
group: string; // dedup key = alpha_2_code (e.g. "US")
alpha_2_code: string;
name: string;
english_short_name?: string;
name_override?: string;
enable?: number;
hide?: number;
priority?: number;
sort?: number;
account_id?: number | null;
[key: string]: unknown; // allow extra fields from API without TS errors
}
export interface LuCountrySubdivision {
id: number;
group: string; // dedup key = code (e.g. "US-NY")
code: string;
name: string;
country_alpha_2_code?: string;
name_override?: string;
enable?: number;
hide?: number;
priority?: number;
sort?: number;
account_id?: number | null;
[key: string]: unknown;
}
export interface LuTimeZone {
id: number;
group: string; // dedup key = name (IANA identifier, e.g. "US/Eastern")
name: string;
name_override?: string; // display label override; prefer this over name when set
enable?: number;
hide?: number;
priority?: number;
sort?: number;
account_id?: number | null;
[key: string]: unknown;
}
export interface LuCacheMeta {
lu_type: 'country' | 'country_subdivision' | 'time_zone';
refreshed_at: number; // Unix timestamp ms — used for 24h TTL check
}
class LookupsDexie extends Dexie {
lu_country!: Table<LuCountry>;
lu_country_subdivision!: Table<LuCountrySubdivision>;
lu_time_zone!: Table<LuTimeZone>;
lu_cache_meta!: Table<LuCacheMeta>;
constructor() {
super('ae_lookups_db');
this.version(1).stores({
lu_country: 'id, alpha_2_code, group',
lu_country_subdivision: 'id, code, country_alpha_2_code, group',
lu_time_zone: 'id, name, group',
lu_cache_meta: 'lu_type'
});
}
}
export const db_lookups = new LookupsDexie();
/** 24-hour TTL in milliseconds */
export const LOOKUP_TTL_MS = 24 * 60 * 60 * 1000;