Public Access
1
0

feat: add deep research planning and postal batch runs

Add a dedicated Deep Research view with postal-area preview overlays, batch execution, and bundled map results.

Also add postal dataset import tooling and fix local API networking and research insert issues needed to support the new workflow.
This commit is contained in:
pguerrerox
2026-04-05 18:05:04 +00:00
parent a1ba5ee093
commit cc00a439bf
29 changed files with 1860 additions and 82 deletions
+53 -9
View File
@@ -1,4 +1,39 @@
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL ?? '';
function isLoopbackHostname(hostname: string) {
return hostname === 'localhost' || hostname === '127.0.0.1';
}
function normalizeBaseUrl(baseUrl: string) {
return baseUrl.replace(/\/+$/, '');
}
function resolveApiBaseUrl() {
const configuredBaseUrl = (import.meta.env.VITE_API_BASE_URL ?? '').trim();
if (typeof window === 'undefined') {
return normalizeBaseUrl(configuredBaseUrl);
}
const fallbackBaseUrl = `${window.location.protocol}//${window.location.hostname}:4000/api`;
if (!configuredBaseUrl) {
return fallbackBaseUrl;
}
try {
const configuredUrl = new URL(configuredBaseUrl);
if (isLoopbackHostname(configuredUrl.hostname) && !isLoopbackHostname(window.location.hostname)) {
configuredUrl.hostname = window.location.hostname;
return normalizeBaseUrl(configuredUrl.toString());
}
return normalizeBaseUrl(configuredUrl.toString());
} catch {
return normalizeBaseUrl(configuredBaseUrl);
}
}
const apiBaseUrl = resolveApiBaseUrl();
export const hasApiConfig = Boolean(apiBaseUrl);
@@ -7,14 +42,23 @@ export async function apiRequest<T>(path: string, init?: RequestInit): Promise<T
throw new Error('VITE_API_BASE_URL is not configured.');
}
const response = await fetch(`${apiBaseUrl}${path}`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
...(init?.headers ?? {}),
},
...init,
});
let response: Response;
try {
response = await fetch(`${apiBaseUrl}${path}`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
...(init?.headers ?? {}),
},
...init,
});
} catch (error) {
throw new Error(
`Failed to reach the local API at ${apiBaseUrl}. Check that the API server is running and that VITE_API_BASE_URL matches the host you opened in the browser.`,
{ cause: error },
);
}
const contentType = response.headers.get('content-type') || '';
const payload = contentType.includes('application/json') ? ((await response.json()) as unknown) : null;