feat(parcel-sync): store UATs in PostgreSQL, eliminate repeated eTerra calls
- GisUat table now includes workspacePk column (created via raw SQL) - GET /api/eterra/uats serves from PostgreSQL instant, no eTerra login needed - POST /api/eterra/uats triggers sync check: compares county count with DB, only does full eTerra fetch if data differs or DB is empty - Frontend loads UATs from DB on mount (fast), falls back to uat.json if empty - On eTerra connect, fires POST to sync-check; if data changed, reloads from DB - Workspace cache populated from DB on GET for search route performance
This commit is contained in:
@@ -325,11 +325,31 @@ export function ParcelSyncModule() {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Load static UAT data as fallback
|
||||
fetch("/uat.json")
|
||||
// Load UATs from local DB (fast — no eTerra needed)
|
||||
fetch("/api/eterra/uats")
|
||||
.then((res) => res.json())
|
||||
.then((data: UatEntry[]) => setUatData(data))
|
||||
.catch(() => {});
|
||||
.then(
|
||||
(data: {
|
||||
uats?: UatEntry[];
|
||||
}) => {
|
||||
if (data.uats && data.uats.length > 0) {
|
||||
setUatData(data.uats);
|
||||
} else {
|
||||
// DB empty — fall back to static uat.json (no county/workspace)
|
||||
fetch("/uat.json")
|
||||
.then((res) => res.json())
|
||||
.then((fallback: UatEntry[]) => setUatData(fallback))
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
)
|
||||
.catch(() => {
|
||||
// API failed — fall back to static uat.json
|
||||
fetch("/uat.json")
|
||||
.then((res) => res.json())
|
||||
.then((fallback: UatEntry[]) => setUatData(fallback))
|
||||
.catch(() => {});
|
||||
});
|
||||
|
||||
// Check existing server session on mount
|
||||
void fetchSession();
|
||||
@@ -342,33 +362,34 @@ export function ParcelSyncModule() {
|
||||
}, [fetchSession]);
|
||||
|
||||
/* ════════════════════════════════════════════════════════════ */
|
||||
/* Fetch enriched UAT list (with county + workspace) when */
|
||||
/* connected to eTerra. Falls back to static uat.json. */
|
||||
/* Sync UATs from eTerra → DB on connect (lightweight check) */
|
||||
/* ════════════════════════════════════════════════════════════ */
|
||||
|
||||
useEffect(() => {
|
||||
if (!session.connected || enrichedUatsFetched.current) return;
|
||||
enrichedUatsFetched.current = true;
|
||||
|
||||
fetch("/api/eterra/uats")
|
||||
// POST triggers sync check — only does full fetch if data changed
|
||||
fetch("/api/eterra/uats", { method: "POST" })
|
||||
.then((res) => res.json())
|
||||
.then(
|
||||
(data: {
|
||||
uats?: {
|
||||
siruta: string;
|
||||
name: string;
|
||||
county: string;
|
||||
workspacePk: number;
|
||||
}[];
|
||||
}) => {
|
||||
if (data.uats && data.uats.length > 0) {
|
||||
setUatData(data.uats);
|
||||
(data: { synced?: boolean }) => {
|
||||
if (data.synced) {
|
||||
// Data changed — reload from DB
|
||||
fetch("/api/eterra/uats")
|
||||
.then((res) => res.json())
|
||||
.then(
|
||||
(fresh: { uats?: UatEntry[] }) => {
|
||||
if (fresh.uats && fresh.uats.length > 0) {
|
||||
setUatData(fresh.uats);
|
||||
}
|
||||
},
|
||||
)
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
)
|
||||
.catch(() => {
|
||||
// Keep static uat.json data
|
||||
});
|
||||
.catch(() => {});
|
||||
}, [session.connected]);
|
||||
|
||||
/* ════════════════════════════════════════════════════════════ */
|
||||
|
||||
Reference in New Issue
Block a user