UNPKG

@lineai/municipal-intel

Version:

AI-first municipal data API providing natural language descriptions of building permits and planning applications from major US cities

699 lines 62.9 kB
/** * Built-in Municipal Data Sources Registry * Core sources provided with the package */ export const builtInRegistry = { version: "1.0.0", lastUpdated: "2025-01-30", sources: { ca: { name: "California", municipalities: [ { id: "sf", name: "San Francisco", state: "CA", type: "api", api: { type: "socrata", baseUrl: "https://data.sfgov.org", defaultDataset: "buildingPermits", datasets: { buildingPermits: { endpoint: "/resource/i98e-djp9.json", name: "Building Permits", // Original fields array - many were incorrect or missing // fields: ["permit_number", "permit_type", "status", "street_number", "street_name", "description", "estimated_cost", "filed_date", "issued_date"], // UNION of field dump + sample data (ALL fields from API responses) fields: [ "adu", "application_submission_method", "approved_date", "block", "completed_date", "data_as_of", "data_loaded_at", "description", "estimated_cost", "existing_construction_type", "existing_construction_type_description", "existing_occupancy", "existing_units", "existing_use", "filed_date", "fire_only_permit", "issued_date", "last_permit_activity_date", "location", "lot", "neighborhoods_analysis_boundaries", "number_of_existing_stories", "number_of_proposed_stories", "permit_creation_date", "permit_number", "permit_type", "permit_type_definition", "plansets", "point_source", "primary_address_flag", "proposed_construction_type", "proposed_construction_type_description", "proposed_occupancy", "proposed_units", "proposed_use", "record_id", "revised_cost", "status", "status_date", "street_name", "street_number", "street_suffix", "supervisor_district", "unit", "zipcode" // inconsistent - not in all records ], fieldMappings: { submitDate: "permit_creation_date", approvalDate: "issued_date", value: "revised_cost", address: "street_name", id: "permit_number", status: "status", description: "description", title: "description" // applicant: No applicant field available in this dataset }, getFullAddress: (data) => { const parts = [ data.street_number, data.street_name, data.street_suffix ].filter(Boolean); const address = parts.join(' '); return data.zipcode ? `${address}, ${data.zipcode}` : address || 'Unknown Address'; }, getDescription: (data) => { const parts = []; // Permit type and description if (data.permit_type) parts.push(data.permit_type); if (data.description) parts.push(data.description); // Address with full context const addressParts = [data.street_number, data.street_name, data.street_suffix].filter(Boolean); if (addressParts.length > 0) { const address = addressParts.join(' '); parts.push(`at ${address}, San Francisco, CA${data.zipcode ? ` ${data.zipcode}` : ''}`); } // Status and cost const statusInfo = []; if (data.status) statusInfo.push(`(${data.status})`); if (data.revised_cost && !isNaN(Number(data.revised_cost))) { statusInfo.push(`$${Number(data.revised_cost).toLocaleString()}`); } if (statusInfo.length > 0) parts.push(statusInfo.join(' ')); // Filing date if (data.permit_creation_date) { try { const date = new Date(data.permit_creation_date); parts.push(`filed ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(' ') || 'San Francisco Building Permit'; } }, planningApplications: { endpoint: "/resource/6zqd-wh5d.json", name: "Planning Department Project Applications", fields: ["record_id", "project_name", "project_address", "project_description", "case_number", "filed_date"], fieldMappings: { submitDate: "filed_date", id: "record_id", title: "project_name", address: "project_address", description: "project_description" }, getFullAddress: (data) => { return data.project_address || 'Unknown Address'; }, getDescription: (data) => { const anyData = data; const parts = []; if (anyData.project_name) parts.push(anyData.project_name); if (anyData.project_address) { parts.push(`at ${anyData.project_address}, San Francisco, CA`); } if (anyData.project_description) parts.push(`- ${anyData.project_description}`); if (anyData.filed_date) { try { const date = new Date(anyData.filed_date); parts.push(`filed ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(' ') || 'San Francisco Planning Application'; } } }, authentication: { required: false, recommended: true, type: "app_token", header: "X-App-Token" }, rateLimit: { withToken: 1000, withoutToken: "shared", period: "hour" } }, urls: { planning: "https://sfplanning.org/project-applications", building: "https://sfdbi.org/building-permits" }, priority: "high" }, { id: "la", name: "Los Angeles", state: "CA", type: "api", api: { type: "socrata", baseUrl: "https://data.lacity.org", defaultDataset: "buildingPermitsCurrent", datasets: { buildingPermitsCurrent: { endpoint: "/resource/pi9x-tg5x.json", name: "LA Building Permits (2020-Present)", // UNION of all fields found across multiple API samples fields: [ "adu_changed", "apc", "apn", "business_unit", "cd", "cnc", "cofo_date", "construction", "cpa", "ct", "du_changed", "ev", "geolocation", "height", "hl", "issue_date", "junior_adu", "lat", "lon", "permit_group", "permit_nbr", "permit_sub_type", "permit_type", "pin_nbr", "primary_address", "refresh_time", "solar", "square_footage", "status_date", "status_desc", "submitted_date", "type_lat_lon", "use_code", "use_desc", "valuation", "work_desc", "zip_code", "zone" ], fieldMappings: { submitDate: "submitted_date", approvalDate: "issue_date", value: "valuation", address: "primary_address", id: "permit_nbr", status: "status_desc", description: "work_desc", title: "work_desc" }, getFullAddress: (data) => { const address = data.primary_address || ''; return data.zip_code ? `${address}, ${data.zip_code}` : address || 'Unknown Address'; }, getDescription: (data) => { const parts = []; // Permit type and subtype if (data.permit_sub_type) parts.push(data.permit_sub_type); if (data.permit_type) parts.push(data.permit_type); // Work description if (data.work_desc) parts.push(`${data.work_desc}`); // Address with full context if (data.primary_address) { const address = `at ${data.primary_address}, Los Angeles, CA${data.zip_code ? ` ${data.zip_code}` : ''}`; parts.push(address); } // Cost and status const statusInfo = []; if (data.valuation && !isNaN(Number(data.valuation))) { statusInfo.push(`($${Number(data.valuation).toLocaleString()})`); } if (data.status_desc) statusInfo.push(data.status_desc); if (statusInfo.length > 0) parts.push(statusInfo.join(' ')); // Submit date if (data.submitted_date) { try { const date = new Date(data.submitted_date); parts.push(`submitted ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(' ') || 'Los Angeles Building Permit'; } }, buildingPermits: { endpoint: "/resource/xnhu-aczu.json", name: "LA BUILD PERMITS (Legacy - Corrupted Dates)", // Original fields array - contained incorrect field name // fields: ["pcis_permit", "permit_type", "permit_sub_type", "latest_status", "issue_date", "address_start", "street_name", "work_description", "valuation_amount"], // Actual fields from API dump fields: [ "address_end", "address_start", "applicant_first_name", "applicant_last_name", "assessor_book", "assessor_page", "assessor_parcel", "block", "census_tract", "contractor_address", "contractor_city", "contractor_state", "contractors_business_name", "floor_area_l_a_building_code_definition", "floor_area_l_a_zoning_code_definition", "initiating_office", "issue_date", "latest_status", "license", "license_expiration_date", "license_type", "location_1", "lot", "of_residential_dwelling_units", "of_stories", "pcis_permit", "permit_category", "permit_sub_type", "permit_type", "principal_first_name", "principal_last_name", "principal_middle_name", "reference_old_permit", "status_date", "street_direction", "street_name", "street_suffix", "tract", "valuation", "work_description", "zip_code", "zone" ], fieldMappings: { submitDate: "issue_date", approvalDate: "issue_date", value: "valuation", address: "street_name", id: "pcis_permit", status: "latest_status", description: "work_description", title: "work_description" // applicant: Could use applicant_first_name + applicant_last_name or contractors_business_name }, getFullAddress: (data) => { const parts = [ data.address_start, data.street_direction, data.street_name, data.street_suffix ].filter(Boolean); const address = parts.join(' '); return data.zip_code ? `${address}, ${data.zip_code}` : address || 'Unknown Address'; }, getDescription: (data) => { const parts = []; // Permit type if (data.permit_type) parts.push(data.permit_type); // Work description if (data.work_description) parts.push(`${data.work_description}`); // Address with full context const addressParts = [ data.address_start, data.street_direction, data.street_name, data.street_suffix ].filter(Boolean); if (addressParts.length > 0) { const address = `at ${addressParts.join(' ')}, Los Angeles, CA${data.zip_code ? ` ${data.zip_code}` : ''}`; parts.push(address); } // Cost and status const statusInfo = []; if (data.latest_status) statusInfo.push(`(${data.latest_status})`); if (data.valuation && !isNaN(Number(data.valuation))) { statusInfo.push(`$${Number(data.valuation).toLocaleString()}`); } if (statusInfo.length > 0) parts.push(statusInfo.join(' ')); // Issue date if (data.issue_date) { try { const date = new Date(data.issue_date); parts.push(`issued ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(' ') || 'Los Angeles Building Permit (Legacy)'; } } }, }, priority: "high" } ] }, ny: { name: "New York", municipalities: [ { id: "nyc", name: "New York City", state: "NY", type: "api", api: { type: "socrata", baseUrl: "https://data.cityofnewyork.us", defaultDataset: "dobPermitIssuance", datasets: { dobPermitIssuance: { endpoint: "/resource/ipu4-2q9a.json", name: "DOB Permit Issuance", fields: [ "bin__", "bldg_type", "block", "borough", "community_board", "dobrundate", "expiration_date", "filing_date", "filing_status", "gis_census_tract", "gis_council_district", "gis_latitude", "gis_longitude", "gis_nta_name", "house__", "issuance_date", "job__", "job_doc___", "job_start_date", "job_type", "lot", "non_profit", "owner_s_business_name", "owner_s_business_type", "owner_s_first_name", "owner_s_last_name", "owner_s_phone__", "permit_sequence__", "permit_si_no", "permit_status", "permit_subtype", "permit_type", "permittee_s_business_name", "permittee_s_first_name", "permittee_s_last_name", "permittee_s_license__", "permittee_s_license_type", "permittee_s_phone__", "self_cert", "street_name", "work_type", "zip_code" ], fieldMappings: { submitDate: "filing_date", approvalDate: "issuance_date", address: "street_name", id: "permit_si_no", status: "permit_status", title: "job_type" }, getFullAddress: (data) => { const parts = [ data.house__, data.street_name ].filter(Boolean); const address = parts.join(' '); return data.zip_code ? `${address}, ${data.zip_code}` : address || 'Unknown Address'; }, getDescription: (data) => { const parts = []; // Job type (main permit type) if (data.job_type) parts.push(data.job_type); // Address with full context const addressParts = [data.house__, data.street_name].filter(Boolean); if (addressParts.length > 0) { const address = addressParts.join(' '); const location = data.borough ? `${address}, ${data.borough}, New York, NY` : `${address}, New York, NY`; if (data.zip_code) { parts.push(`at ${location} ${data.zip_code}`); } else { parts.push(`at ${location}`); } } // Status if (data.permit_status) parts.push(`(${data.permit_status})`); // Filing date if (data.filing_date) { try { const date = new Date(data.filing_date); parts.push(`filed ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(' ') || 'New York City DOB Permit'; } }, dobNowBuildApproved: { endpoint: "/resource/rbx6-tga4.json", name: "DOB NOW: Build – Approved Permits", fields: [ "applicant_business_address", "applicant_business_name", "applicant_first_name", "applicant_last_name", "applicant_license", "applicant_middle_name", "approved_date", "bin", "block", "borough", "c_b_no", "estimated_job_costs", "expired_date", "filing_reason", "filing_representative_business_name", "filing_representative_first_name", "filing_representative_last_name", "house_no", "issued_date", "job_description", "job_filing_number", "lot", "owner_business_name", "owner_name", "permittee_s_license_type", "street_name", "work_on_floor", "work_permit", "work_type" ], fieldMappings: { submitDate: "issued_date", approvalDate: "approved_date", value: "estimated_job_costs", address: "street_name", id: "job_filing_number", status: "work_permit", title: "job_description" }, getFullAddress: (data) => { const parts = [ data.house_no, data.street_name ].filter(Boolean); return parts.join(' ') || 'Unknown Address'; }, getDescription: (data) => { const parts = []; // Job description if (data.job_description) parts.push(data.job_description); // Address with full context const addressParts = [data.house_no, data.street_name].filter(Boolean); if (addressParts.length > 0) { const address = addressParts.join(' '); const location = data.borough ? `${address}, ${data.borough}, New York, NY` : `${address}, New York, NY`; parts.push(`at ${location}`); } // Cost and status const statusInfo = []; if (data.estimated_job_costs && !isNaN(Number(data.estimated_job_costs))) { statusInfo.push(`($${Number(data.estimated_job_costs).toLocaleString()})`); } if (data.work_permit) statusInfo.push(data.work_permit); if (statusInfo.length > 0) parts.push(statusInfo.join(' ')); // Issue/approval date if (data.issued_date) { try { const date = new Date(data.issued_date); parts.push(`issued ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } else if (data.approved_date) { try { const date = new Date(data.approved_date); parts.push(`approved ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(' ') || 'New York City DOB NOW Build Permit'; } }, activeMajorProjects: { endpoint: "/resource/n5mv-nfpy.json", name: "Active Major Construction Projects", fields: ["project_id", "project_name", "borough", "project_description", "project_start_date", "expected_completion_date", "total_construction_floor_area_sq_ft", "total_units", "construction_type"], fieldMappings: { submitDate: "project_start_date", id: "project_id", title: "project_name", description: "project_description", value: "total_construction_floor_area_sq_ft" }, getFullAddress: (_data) => { return 'Unknown Address'; // This dataset doesn't have address fields }, getDescription: (data) => { const anyData = data; const parts = []; // Project name if (anyData.project_name) parts.push(anyData.project_name); // Location if (anyData.borough) { parts.push(`in ${anyData.borough}, New York, NY`); } // Project details const details = []; if (anyData.construction_type) details.push(anyData.construction_type.toLowerCase()); if (anyData.total_construction_floor_area_sq_ft && !isNaN(Number(anyData.total_construction_floor_area_sq_ft))) { const sqft = Number(anyData.total_construction_floor_area_sq_ft); if (sqft >= 1000000) { details.push(`${(sqft / 1000000).toFixed(1)}M sq ft`); } else if (sqft >= 1000) { details.push(`${(sqft / 1000).toFixed(0)}K sq ft`); } else { details.push(`${sqft.toLocaleString()} sq ft`); } } if (anyData.total_units && !isNaN(Number(anyData.total_units))) { details.push(`${Number(anyData.total_units).toLocaleString()} units`); } if (details.length > 0) parts.push(details.join(', ')); // Completion date if (anyData.expected_completion_date) { try { const date = new Date(anyData.expected_completion_date); parts.push(`completion expected ${date.toLocaleDateString()}`); } catch (e) { // Skip invalid dates } } return parts.filter(Boolean).join(': ').replace(': : ', ': ') || 'New York City Major Construction Project'; } } }, authentication: { required: false, recommended: true, type: "app_token" } }, urls: { dob: "https://www1.nyc.gov/site/buildings/index.page", planning: "https://www1.nyc.gov/site/planning/index.page" }, priority: "high" } ] }, fl: { name: "Florida", municipalities: [] } }, commonFields: { required: ["id", "name", "state", "type", "priority"], optional: ["urls", "coverage", "updateFrequency", "enabled", "lastChecked", "lastError"], typeEnum: ["api", "portal", "scraping"] }, implementationPriorities: { high: ["sf", "nyc", "la"], medium: [], low: [] } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVuaWNpcGFsLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RhdGEvbXVuaWNpcGFsLXJlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQVdILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBbUI7SUFDN0MsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLFlBQVk7SUFDekIsT0FBTyxFQUFFO1FBQ1AsRUFBRSxFQUFFO1lBQ0YsSUFBSSxFQUFFLFlBQVk7WUFDbEIsY0FBYyxFQUFFO2dCQUNkO29CQUNFLEVBQUUsRUFBRSxJQUFJO29CQUNSLElBQUksRUFBRSxlQUFlO29CQUNyQixLQUFLLEVBQUUsSUFBSTtvQkFDWCxJQUFJLEVBQUUsS0FBSztvQkFDWCxHQUFHLEVBQUU7d0JBQ0gsSUFBSSxFQUFFLFNBQVM7d0JBQ2YsT0FBTyxFQUFFLHdCQUF3Qjt3QkFDakMsY0FBYyxFQUFFLGlCQUFpQjt3QkFDakMsUUFBUSxFQUFFOzRCQUNSLGVBQWUsRUFBRTtnQ0FDZixRQUFRLEVBQUUsMEJBQTBCO2dDQUNwQyxJQUFJLEVBQUUsa0JBQWtCO2dDQUN4Qix5REFBeUQ7Z0NBQ3pELG9KQUFvSjtnQ0FDcEosb0VBQW9FO2dDQUNwRSxNQUFNLEVBQUU7b0NBQ04sS0FBSztvQ0FDTCwrQkFBK0I7b0NBQy9CLGVBQWU7b0NBQ2YsT0FBTztvQ0FDUCxnQkFBZ0I7b0NBQ2hCLFlBQVk7b0NBQ1osZ0JBQWdCO29DQUNoQixhQUFhO29DQUNiLGdCQUFnQjtvQ0FDaEIsNEJBQTRCO29DQUM1Qix3Q0FBd0M7b0NBQ3hDLG9CQUFvQjtvQ0FDcEIsZ0JBQWdCO29DQUNoQixjQUFjO29DQUNkLFlBQVk7b0NBQ1osa0JBQWtCO29DQUNsQixhQUFhO29DQUNiLDJCQUEyQjtvQ0FDM0IsVUFBVTtvQ0FDVixLQUFLO29DQUNMLG1DQUFtQztvQ0FDbkMsNEJBQTRCO29DQUM1Qiw0QkFBNEI7b0NBQzVC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