UNPKG

@lineai/municipal-intel

Version:

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

702 lines 63 kB
"use strict"; /** * Built-in Municipal Data Sources Registry * Core sources provided with the package */ Object.defineProperty(exports, "__esModule", { value: true }); exports.builtInRegistry = void 0; exports.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVuaWNpcGFsLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RhdGEvbXVuaWNpcGFsLXJlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7OztBQVdVLFFBQUEsZUFBZSxHQUFtQjtJQUM3QyxPQUFPLEVBQUUsT0FBTztJQUNoQixXQUFXLEVBQUUsWUFBWTtJQUN6QixPQUFPLEVBQUU7UUFDUCxFQUFFLEVBQUU7WUFDRixJQUFJLEVBQUUsWUFBWTtZQUNsQixjQUFjLEVBQUU7Z0JBQ2Q7b0JBQ0UsRUFBRSxFQUFFLElBQUk7b0JBQ1IsSUFBSSxFQUFFLGVBQWU7b0JBQ3JCLEtBQUssRUFBRSxJQUFJO29CQUNYLElBQUksRUFBRSxLQUFLO29CQUNYLEdBQUcsRUFBRTt3QkFDSCxJQUFJLEVBQUUsU0FBUzt3QkFDZixPQUFPLEVBQUUsd0JBQXdCO3dCQUNqQyxjQUFjLEVBQUUsaUJBQWlCO3dCQUNqQyxRQUFRLEVBQUU7NEJBQ1IsZUFBZSxFQUFFO2dDQUNmLFFBQVEsRUFBRSwwQkFBMEI7Z0NBQ3BDLElBQUksRUFBRSxrQkFBa0I7Z0NBQ3hCLHlEQUF5RDtnQ0FDekQsb0pBQW9KO2dDQUNwSixvRUFBb0U7Z0NBQ3BFLE1BQU0sRUFBRTtvQ0FDTixLQUFLO29DQUNMLCtCQUErQjtvQ0FDL0IsZUFBZTtvQ0FDZixPQUFPO29DQUNQLGdCQUFnQjtvQ0FDaEIsWUFBWTtvQ0FDWixnQkFBZ0I7b0NBQ2hCLGFBQWE7b0NBQ2IsZ0JBQWdCO29DQUNoQiw0QkFBNEI7b0NBQzVCLHdDQUF3QztvQ0FDeEMsb0JBQW9CO29DQUNwQixnQkFBZ0I7b0NBQ2hCLGNBQWM7b0NBQ2QsWUFBWTtvQ0FDWixrQkFBa0I7b0NBQ2xCLGFBQWE7b0NBQ2IsMkJBQTJCO29DQUMzQixVQUFVO29DQUNWLEtBQUs7b0NBQ0wsbUNBQW1DO29DQUNuQyw0QkFBNEI7b0NBQzVCLDRCQUE0QjtvQ0FDNUIsc0JBQXNC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