@lineai/municipal-intel
Version:
AI-first municipal data API providing natural language descriptions of building permits and planning applications from major US cities
580 lines (579 loc) • 21.4 kB
TypeScript
/**
* Types for municipal data source configuration
*/
import { z } from 'zod';
import type { SFBuildingPermit, LACurrentBuildingPermit, LABuildingPermit, NYCDOBPermit, NYCDOBNowBuild } from '../schemas/api-responses';
/**
* Type of data access method
*/
export type SourceType = 'api' | 'portal' | 'scraping';
/**
* API types we support
*/
export type ApiType = 'socrata' | 'arcgis' | 'custom';
/**
* Portal system types
*/
export type PortalSystem = 'accela' | 'custom' | 'eBUILD' | 'ePermits' | 'MyJax';
/**
* Implementation priority
*/
export type Priority = 'high' | 'medium' | 'low';
/**
* Union type for all supported dataset record types
*/
export type SocrataRecord = SFBuildingPermit | LACurrentBuildingPermit | LABuildingPermit | NYCDOBPermit | NYCDOBNowBuild;
/**
* Socrata dataset configuration with typed record support
*/
export interface SocrataDataset<T extends SocrataRecord = SocrataRecord> {
endpoint: string;
name: string;
fields: string[];
fieldMappings?: Record<string, string>;
getFullAddress: (data: T) => string;
getDescription: (data: T) => string;
}
/**
* API authentication configuration
*/
export interface ApiAuth {
required: boolean;
recommended?: boolean;
type?: 'app_token' | 'api_key' | 'oauth';
header?: string;
}
/**
* Rate limit configuration
*/
export interface RateLimit {
limit?: number | 'unknown' | 'shared';
period?: 'second' | 'minute' | 'hour' | 'day';
withToken?: number;
withoutToken?: number | 'shared';
}
/**
* API source configuration
*/
export interface ApiSource {
type: ApiType;
baseUrl: string;
datasets: Record<string, SocrataDataset<any>>;
defaultDataset: string;
endpoints?: Record<string, string>;
authentication?: ApiAuth;
rateLimit?: RateLimit;
}
/**
* Portal source configuration
*/
export interface PortalSource {
url: string;
system: PortalSystem;
loginRequired?: boolean;
}
/**
* Web scraping configuration
*/
export interface ScrapingSource {
url: string;
format?: 'html' | 'pdf';
selectors?: Record<string, string>;
hasPdfs?: boolean;
requiresJS?: boolean;
}
/**
* Municipality data source
*/
export interface MunicipalSource {
id: string;
name: string;
state: string;
type: SourceType;
api?: ApiSource;
portal?: PortalSource;
scraping?: ScrapingSource;
urls?: Record<string, string>;
coverage?: string[];
updateFrequency?: string;
priority: Priority;
enabled?: boolean;
lastChecked?: string;
lastError?: string;
}
/**
* Source registry
*/
export interface SourceRegistry {
version: string;
lastUpdated: string;
sources: {
ca: StateSources;
ny: StateSources;
fl: StateSources;
[key: string]: StateSources;
};
commonFields: {
required: string[];
optional: string[];
typeEnum: string[];
};
implementationPriorities: {
high: string[];
medium: string[];
low: string[];
};
}
/**
* State-level source grouping
*/
export interface StateSources {
name: string;
municipalities: MunicipalSource[];
}
/**
* Zod schemas for validation
*/
export declare const ApiAuthSchema: z.ZodObject<{
required: z.ZodBoolean;
recommended: z.ZodOptional<z.ZodBoolean>;
type: z.ZodOptional<z.ZodEnum<["app_token", "api_key", "oauth"]>>;
header: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
}, {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
}>;
export declare const RateLimitSchema: z.ZodObject<{
limit: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">, z.ZodLiteral<"shared">]>>;
period: z.ZodOptional<z.ZodEnum<["second", "minute", "hour", "day"]>>;
withToken: z.ZodOptional<z.ZodNumber>;
withoutToken: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"shared">]>>;
}, "strip", z.ZodTypeAny, {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
}, {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
}>;
export declare const SocrataDatasetSchema: z.ZodObject<{
endpoint: z.ZodString;
name: z.ZodString;
fields: z.ZodArray<z.ZodString, "many">;
fieldMappings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
getFullAddress: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
getDescription: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
}, "strip", z.ZodTypeAny, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}>;
export declare const ApiSourceSchema: z.ZodObject<{
type: z.ZodEnum<["socrata", "arcgis", "custom"]>;
baseUrl: z.ZodString;
datasets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
endpoint: z.ZodString;
name: z.ZodString;
fields: z.ZodArray<z.ZodString, "many">;
fieldMappings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
getFullAddress: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
getDescription: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
}, "strip", z.ZodTypeAny, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}>>>;
endpoints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
authentication: z.ZodOptional<z.ZodObject<{
required: z.ZodBoolean;
recommended: z.ZodOptional<z.ZodBoolean>;
type: z.ZodOptional<z.ZodEnum<["app_token", "api_key", "oauth"]>>;
header: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
}, {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
}>>;
rateLimit: z.ZodOptional<z.ZodObject<{
limit: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">, z.ZodLiteral<"shared">]>>;
period: z.ZodOptional<z.ZodEnum<["second", "minute", "hour", "day"]>>;
withToken: z.ZodOptional<z.ZodNumber>;
withoutToken: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"shared">]>>;
}, "strip", z.ZodTypeAny, {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
}, {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
}>>;
}, "strip", z.ZodTypeAny, {
type: "custom" | "socrata" | "arcgis";
baseUrl: string;
datasets?: Record<string, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}> | undefined;
endpoints?: Record<string, string> | undefined;
authentication?: {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
} | undefined;
rateLimit?: {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
} | undefined;
}, {
type: "custom" | "socrata" | "arcgis";
baseUrl: string;
datasets?: Record<string, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}> | undefined;
endpoints?: Record<string, string> | undefined;
authentication?: {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
} | undefined;
rateLimit?: {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
} | undefined;
}>;
export declare const PortalSourceSchema: z.ZodObject<{
url: z.ZodString;
system: z.ZodEnum<["accela", "custom", "eBUILD", "ePermits", "MyJax"]>;
loginRequired: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
url: string;
system: "custom" | "accela" | "eBUILD" | "ePermits" | "MyJax";
loginRequired?: boolean | undefined;
}, {
url: string;
system: "custom" | "accela" | "eBUILD" | "ePermits" | "MyJax";
loginRequired?: boolean | undefined;
}>;
export declare const ScrapingSourceSchema: z.ZodObject<{
url: z.ZodString;
format: z.ZodOptional<z.ZodEnum<["html", "pdf"]>>;
selectors: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
hasPdfs: z.ZodOptional<z.ZodBoolean>;
requiresJS: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
url: string;
format?: "html" | "pdf" | undefined;
selectors?: Record<string, string> | undefined;
hasPdfs?: boolean | undefined;
requiresJS?: boolean | undefined;
}, {
url: string;
format?: "html" | "pdf" | undefined;
selectors?: Record<string, string> | undefined;
hasPdfs?: boolean | undefined;
requiresJS?: boolean | undefined;
}>;
export declare const MunicipalSourceSchema: z.ZodObject<{
id: z.ZodString;
name: z.ZodString;
state: z.ZodString;
type: z.ZodEnum<["api", "portal", "scraping"]>;
api: z.ZodOptional<z.ZodObject<{
type: z.ZodEnum<["socrata", "arcgis", "custom"]>;
baseUrl: z.ZodString;
datasets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
endpoint: z.ZodString;
name: z.ZodString;
fields: z.ZodArray<z.ZodString, "many">;
fieldMappings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
getFullAddress: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
getDescription: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
}, "strip", z.ZodTypeAny, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}>>>;
endpoints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
authentication: z.ZodOptional<z.ZodObject<{
required: z.ZodBoolean;
recommended: z.ZodOptional<z.ZodBoolean>;
type: z.ZodOptional<z.ZodEnum<["app_token", "api_key", "oauth"]>>;
header: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
}, {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
}>>;
rateLimit: z.ZodOptional<z.ZodObject<{
limit: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">, z.ZodLiteral<"shared">]>>;
period: z.ZodOptional<z.ZodEnum<["second", "minute", "hour", "day"]>>;
withToken: z.ZodOptional<z.ZodNumber>;
withoutToken: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"shared">]>>;
}, "strip", z.ZodTypeAny, {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
}, {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
}>>;
}, "strip", z.ZodTypeAny, {
type: "custom" | "socrata" | "arcgis";
baseUrl: string;
datasets?: Record<string, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}> | undefined;
endpoints?: Record<string, string> | undefined;
authentication?: {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
} | undefined;
rateLimit?: {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
} | undefined;
}, {
type: "custom" | "socrata" | "arcgis";
baseUrl: string;
datasets?: Record<string, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}> | undefined;
endpoints?: Record<string, string> | undefined;
authentication?: {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
} | undefined;
rateLimit?: {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
} | undefined;
}>>;
portal: z.ZodOptional<z.ZodObject<{
url: z.ZodString;
system: z.ZodEnum<["accela", "custom", "eBUILD", "ePermits", "MyJax"]>;
loginRequired: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
url: string;
system: "custom" | "accela" | "eBUILD" | "ePermits" | "MyJax";
loginRequired?: boolean | undefined;
}, {
url: string;
system: "custom" | "accela" | "eBUILD" | "ePermits" | "MyJax";
loginRequired?: boolean | undefined;
}>>;
scraping: z.ZodOptional<z.ZodObject<{
url: z.ZodString;
format: z.ZodOptional<z.ZodEnum<["html", "pdf"]>>;
selectors: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
hasPdfs: z.ZodOptional<z.ZodBoolean>;
requiresJS: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
url: string;
format?: "html" | "pdf" | undefined;
selectors?: Record<string, string> | undefined;
hasPdfs?: boolean | undefined;
requiresJS?: boolean | undefined;
}, {
url: string;
format?: "html" | "pdf" | undefined;
selectors?: Record<string, string> | undefined;
hasPdfs?: boolean | undefined;
requiresJS?: boolean | undefined;
}>>;
urls: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
coverage: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
updateFrequency: z.ZodOptional<z.ZodString>;
priority: z.ZodEnum<["high", "medium", "low"]>;
enabled: z.ZodOptional<z.ZodBoolean>;
lastChecked: z.ZodOptional<z.ZodString>;
lastError: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
type: "api" | "portal" | "scraping";
name: string;
id: string;
state: string;
priority: "high" | "medium" | "low";
api?: {
type: "custom" | "socrata" | "arcgis";
baseUrl: string;
datasets?: Record<string, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}> | undefined;
endpoints?: Record<string, string> | undefined;
authentication?: {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
} | undefined;
rateLimit?: {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
} | undefined;
} | undefined;
portal?: {
url: string;
system: "custom" | "accela" | "eBUILD" | "ePermits" | "MyJax";
loginRequired?: boolean | undefined;
} | undefined;
scraping?: {
url: string;
format?: "html" | "pdf" | undefined;
selectors?: Record<string, string> | undefined;
hasPdfs?: boolean | undefined;
requiresJS?: boolean | undefined;
} | undefined;
urls?: Record<string, string> | undefined;
coverage?: string[] | undefined;
updateFrequency?: string | undefined;
enabled?: boolean | undefined;
lastChecked?: string | undefined;
lastError?: string | undefined;
}, {
type: "api" | "portal" | "scraping";
name: string;
id: string;
state: string;
priority: "high" | "medium" | "low";
api?: {
type: "custom" | "socrata" | "arcgis";
baseUrl: string;
datasets?: Record<string, {
name: string;
endpoint: string;
fields: string[];
getFullAddress: (...args: unknown[]) => string;
getDescription: (...args: unknown[]) => string;
fieldMappings?: Record<string, string> | undefined;
}> | undefined;
endpoints?: Record<string, string> | undefined;
authentication?: {
required: boolean;
type?: "app_token" | "api_key" | "oauth" | undefined;
recommended?: boolean | undefined;
header?: string | undefined;
} | undefined;
rateLimit?: {
limit?: number | "unknown" | "shared" | undefined;
period?: "second" | "minute" | "hour" | "day" | undefined;
withToken?: number | undefined;
withoutToken?: number | "shared" | undefined;
} | undefined;
} | undefined;
portal?: {
url: string;
system: "custom" | "accela" | "eBUILD" | "ePermits" | "MyJax";
loginRequired?: boolean | undefined;
} | undefined;
scraping?: {
url: string;
format?: "html" | "pdf" | undefined;
selectors?: Record<string, string> | undefined;
hasPdfs?: boolean | undefined;
requiresJS?: boolean | undefined;
} | undefined;
urls?: Record<string, string> | undefined;
coverage?: string[] | undefined;
updateFrequency?: string | undefined;
enabled?: boolean | undefined;
lastChecked?: string | undefined;
lastError?: string | undefined;
}>;