add POST /api/v1/dot/name-check: parallel SOS + FMCSA name availability check

- Checks state SOS for entity name availability (via workers adapter)
- Checks FMCSA census for exact + fuzzy name matches
- Returns: sos_available, fmcsa_in_use, fmcsa_matches, combined 'available' flag
- 20s timeout on SOS lookup, FMCSA query is instant (local DB)
This commit is contained in:
justin 2026-05-30 21:02:32 -05:00
parent 340a364d8c
commit 08e80e11f9

View file

@ -669,6 +669,99 @@ router.get("/api/v1/dot/search", async (req, res) => {
}
});
// ── Name Availability Check (SOS + FMCSA parallel) ───────────────
router.post("/api/v1/dot/name-check", async (req, res) => {
const { name, state } = req.body ?? {};
if (!name || name.length < 2) {
res.status(400).json({ error: "name is required (at least 2 characters)." });
return;
}
const stateCode = (state || "").toUpperCase().trim();
try {
// Run SOS check and FMCSA check in parallel
const [sosResult, fmcsaResult] = await Promise.allSettled([
// 1. SOS name availability via workers /entity-status
stateCode && stateCode.length === 2
? fetch(`${WORKER_URL}/entity-status`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ entity_name: name, state_code: stateCode }),
signal: AbortSignal.timeout(20000),
}).then(r => r.json())
: Promise.resolve({ skipped: true }),
// 2. FMCSA census — exact and fuzzy name match
pool.query(
`SELECT dot_number, legal_name, dba_name, phy_state, carrier_operation
FROM fmcsa_carriers
WHERE legal_name ILIKE $1 OR dba_name ILIKE $1
ORDER BY CASE WHEN UPPER(legal_name) = UPPER($2) THEN 0 ELSE 1 END, legal_name
LIMIT 20`,
[`%${name}%`, name],
),
]);
// Parse SOS result
let sosAvailable: boolean | null = null;
let sosEntity: Record<string, unknown> | null = null;
if (sosResult.status === "fulfilled") {
const sos = sosResult.value as Record<string, unknown>;
if (sos.skipped) {
sosAvailable = null; // No state provided
} else if (sos.found) {
sosAvailable = false; // Name is taken
sosEntity = sos as Record<string, unknown>;
} else {
sosAvailable = true; // Name is available
}
}
// Parse FMCSA result
let fmcsaMatches: Record<string, unknown>[] = [];
let fmcsaExactMatch = false;
if (fmcsaResult.status === "fulfilled") {
fmcsaMatches = fmcsaResult.value.rows || [];
fmcsaExactMatch = fmcsaMatches.some(
(r: Record<string, unknown>) =>
(r.legal_name as string || "").toUpperCase() === name.toUpperCase(),
);
}
res.json({
name,
state: stateCode || null,
sos_available: sosAvailable,
sos_entity: sosEntity ? {
status: sosEntity.status,
entity_number: sosEntity.entity_number,
entity_type: sosEntity.entity_type,
} : null,
fmcsa_in_use: fmcsaExactMatch,
fmcsa_matches: fmcsaMatches.slice(0, 10).map((r: Record<string, unknown>) => ({
dot_number: r.dot_number,
legal_name: r.legal_name,
dba_name: r.dba_name,
state: r.phy_state,
})),
available: sosAvailable !== false && !fmcsaExactMatch,
message: fmcsaExactMatch
? `"${name}" is already registered with FMCSA (DOT# ${(fmcsaMatches.find((r: Record<string, unknown>) => (r.legal_name as string || "").toUpperCase() === name.toUpperCase()) as Record<string, unknown>)?.dot_number}). Choose a different name or use your existing entity.`
: sosAvailable === false
? `"${name}" is already registered in ${stateCode}. The name may still be usable if it's your entity.`
: sosAvailable === true
? `"${name}" is available in ${stateCode} and not found in FMCSA records.`
: !stateCode
? `"${name}" ${fmcsaExactMatch ? "is" : "is not"} found in FMCSA records. Provide a state to also check Secretary of State availability.`
: `Could not verify availability. Check with the ${stateCode} Secretary of State directly.`,
});
} catch (err) {
console.error("[name-check] Error:", err);
res.status(500).json({ error: "Name check failed." });
}
});
// ── State Requirements Lookup ──────────────────────────────────────
router.get("/api/v1/dot/state-requirements", async (req, res) => {