UNPKG

@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
/** * 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; }>;