@lineai/gov-deals
Version:
Explore Federal contracts for government building renovations, city hall renovations, courthouse updates, library modernizations, federal building improvement contracts, base housing and facilities upgrades.
161 lines • 11.7 kB
JavaScript
/**
* Field mapping between CSV columns and SAM.gov API fields
*
* The CSV uses different field names than the API, so we need to map between them
*/
/**
* Map CSV row to SAM.gov opportunity format
*/
export function mapCsvToSamOpportunity(csvRow) {
return {
// Core identifiers
noticeId: csvRow.NoticeId,
title: csvRow.Title,
solicitationNumber: csvRow['Sol#'],
// Agency information
fullParentPathName: csvRow['Department/Ind.Agency'],
fullParentPathCode: csvRow.CGAC,
organizationType: csvRow.OrganizationType,
// Dates
postedDate: csvRow.PostedDate,
responseDeadLine: csvRow.ResponseDeadLine,
archiveDate: csvRow.ArchiveDate,
// Type information
type: csvRow.Type,
baseType: csvRow.BaseType,
archiveType: csvRow.ArchiveType,
// Set-aside information (map the text value to our enum codes)
typeOfSetAside: mapSetAsideTextToCode(csvRow.SetASide),
typeOfSetAsideDescription: csvRow.SetASide,
// Classification
naicsCode: String(csvRow.NaicsCode),
naicsCodes: [String(csvRow.NaicsCode)],
classificationCode: csvRow.ClassificationCode,
// Status
active: csvRow.Active === '1' ? 'Yes' : 'No',
// Description URL
description: csvRow.Description || `/opportunities/v1/noticedesc?noticeid=${csvRow.NoticeId}`,
// Contacts - map to array format
pointOfContact: [
...(csvRow.PrimaryContactFullname ? [{
type: 'primary',
fullName: csvRow.PrimaryContactFullname,
title: csvRow.PrimaryContactTitle,
email: csvRow.PrimaryContactEmail,
phone: csvRow.PrimaryContactPhone,
fax: csvRow.PrimaryContactFax,
}] : []),
...(csvRow.SecondaryContactFullname ? [{
type: 'secondary',
fullName: csvRow.SecondaryContactFullname,
title: csvRow.SecondaryContactTitle,
email: csvRow.SecondaryContactEmail,
phone: csvRow.SecondaryContactPhone,
fax: csvRow.SecondaryContactFax,
}] : []),
],
// Addresses
officeAddress: csvRow.City ? {
city: csvRow.City,
state: csvRow.State,
zipcode: csvRow.ZipCode,
countryCode: csvRow.CountryCode,
} : null,
placeOfPerformance: csvRow.PopCity ? {
city: {
code: csvRow.PopCity || undefined,
name: csvRow.PopCity || undefined,
},
state: {
code: csvRow.PopState || undefined,
name: csvRow.PopState || undefined, // Use same value for both code and name
},
country: {
code: csvRow.PopCountry || undefined,
name: csvRow.PopCountry || undefined,
},
} : null,
// Award information
award: csvRow.AwardNumber ? {
awardee: {
name: csvRow.Awardee,
manual: false,
}
} : null,
// Links
uiLink: csvRow.Link,
additionalInfoLink: csvRow.AdditionalInfoLink,
links: [],
resourceLinks: null, // CSV doesn't have resource links
};
}
/**
* Map set-aside text descriptions to codes
* Based on the analysis, we saw these set-aside values in the CSV
*/
function mapSetAsideTextToCode(setAsideText) {
if (!setAsideText || setAsideText === 'None/Null')
return null;
const mapping = {
'Total Small Business Set-Aside (FAR 19.5)': 'SBA',
'Service-Disabled Veteran-Owned Small Business (SDVOSB) Set-Aside (FAR 19.14)': 'SBP',
'SBA Certified Women-Owned Small Business (WOSB) Program Set-Aside (FAR 19.15)': 'WOSB',
'Historically Underutilized Business (HUBZone) Set-Aside (FAR 19.13)': 'HUB',
'8(a) Set-Aside (FAR 19.8)': '8AN',
'Veteran-Owned Small Business Set-Aside (specific to Department of Veterans Affairs)': 'VSA',
'No Set aside used': '',
};
// Return the code if we have a mapping, otherwise keep the original text
return mapping[setAsideText] || setAsideText;
}
/**
* Filter CSV rows based on SAM.gov search filters
*/
export function filterCsvRow(row, filters) {
if (!filters)
return true;
// Keywords search in title
if (filters.keywords) {
const keywords = filters.keywords.toLowerCase();
if (!row.Title.toLowerCase().includes(keywords)) {
return false;
}
}
// NAICS codes filter
if (filters.naicsCodes?.length) {
const naicsStr = String(row.NaicsCode);
const matches = filters.naicsCodes.some((code) => naicsStr.startsWith(code));
if (!matches)
return false;
}
// Active only filter
if (filters.activeOnly && row.Active !== '1') {
return false;
}
// Place of performance states
if (filters.placeOfPerformanceStates?.length) {
if (!filters.placeOfPerformanceStates.includes(row.PopState)) {
return false;
}
}
// Set-aside types
if (filters.setAsideTypes?.length) {
const mappedCode = mapSetAsideTextToCode(row.SetASide);
if (!mappedCode || !filters.setAsideTypes.includes(mappedCode)) {
return false;
}
}
// Date filters
if (filters.postedFrom) {
if (new Date(row.PostedDate) < new Date(filters.postedFrom)) {
return false;
}
}
if (filters.postedTo) {
if (new Date(row.PostedDate) > new Date(filters.postedTo)) {
return false;
}
}
return true;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGQtbWFwcGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhc291cmNlcy9jc3YvZmllbGQtbWFwcGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBdURIOztHQUVHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUFDLE1BQXlCO0lBQzlELE9BQU87UUFDTCxtQkFBbUI7UUFDbkIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO1FBQ3pCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztRQUNuQixrQkFBa0IsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDO1FBRWxDLHFCQUFxQjtRQUNyQixrQkFBa0IsRUFBRSxNQUFNLENBQUMsdUJBQXVCLENBQUM7UUFDbkQsa0JBQWtCLEVBQUUsTUFBTSxDQUFDLElBQUk7UUFDL0IsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtRQUV6QyxRQUFRO1FBQ1IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxnQkFBZ0I7UUFDekMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO1FBRS9CLG1CQUFtQjtRQUNuQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7UUFDakIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO1FBQ3pCLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztRQUUvQiwrREFBK0Q7UUFDL0QsY0FBYyxFQUFFLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7UUFDdEQseUJBQXlCLEVBQUUsTUFBTSxDQUFDLFFBQVE7UUFFMUMsaUJBQWlCO1FBQ2pCLFNBQVMsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNuQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3RDLGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxrQkFBa0I7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