Fix BDC check: ask voice first, rename card, support voice-only carriers

BDC Voice Subscription filing is required for all retail voice
providers (VoIP, CLEC, wireline) even without broadband service.
The compliance checker was asking about broadband first, which
caused voice-only carriers to overlook their BDC Voice obligation.

- Renamed card: "BDC Filing (Broadband + Voice Subscription Data)"
- Reversed question order: ask retail voice first, then broadband
- "No" for voice now says "No, or wholesale only" (wholesale exempt)
- Voice-only retail carriers correctly flagged for BDC Voice filing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-05-02 07:28:09 -05:00
parent 92427291e6
commit 0f9b473030
2 changed files with 18 additions and 18 deletions

View file

@ -691,7 +691,7 @@ router.get("/api/v1/fcc/lookup", async (req, res) => {
checks.push({
id: "bdc_filing",
label: "Broadband Data Collection (BDC)",
label: "BDC Filing (Broadband + Voice Subscription Data)",
status: bdcStatus,
detail: bdcDetail,
action_url: null,

View file

@ -174,48 +174,48 @@ Send reset link
var checks = document.getElementById("checks-container");
if (!checks) return;
// BDC toggle — two-step: broadband? then voice? (always both questions)
// BDC toggle — two-step: voice? then broadband? (always both questions)
// Voice-only retail providers also need BDC Voice Subscription filing
// Stores result on card as data-bdc-slug for the CTA to pick up
if (!checks.querySelector(".pw-bdc-toggle")) {
var cards = checks.querySelectorAll(":scope > div");
cards.forEach(function(card) {
if (card.textContent.indexOf("Broadband Data Collection") < 0) return;
if (card.textContent.indexOf("BDC") < 0) return;
var detail = card.querySelectorAll("p")[1];
if (!detail) return;
var icon = card.querySelector("span");
var flexDiv = card.querySelector(".flex-1");
function askBroadband() {
function askVoiceFirst() {
var q1 = document.createElement("div");
q1.className = "pw-bdc-toggle mt-3 flex items-center gap-2";
q1.innerHTML =
'<span class="text-sm font-bold text-gray-900">During ' + (new Date().getFullYear() - 1) + ', did you provide broadband internet access in the United States through resale or facilities-based service (not as an outside sales agent)?</span>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-red-300 bg-red-50 text-red-700 hover:bg-red-100 hover:border-red-400 transition-colors" data-bb="yes">Yes</button>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-green-300 bg-green-50 text-green-700 hover:bg-green-100 hover:border-green-400 transition-colors" data-bb="no">No</button>';
'<span class="text-sm font-bold text-gray-900">During ' + (new Date().getFullYear() - 1) + ', did you offer <u>retail</u> voice service (VoIP, CLEC, or wireline) to end users in the United States?</span>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-red-300 bg-red-50 text-red-700 hover:bg-red-100 hover:border-red-400 transition-colors" data-vc="yes">Yes</button>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-green-300 bg-green-50 text-green-700 hover:bg-green-100 hover:border-green-400 transition-colors" data-vc="no">No, or wholesale only</button>';
flexDiv.appendChild(q1);
q1.addEventListener("click", function(ev) {
var b = ev.target.closest("[data-bb]");
var b = ev.target.closest("[data-vc]");
if (!b) return;
q1.remove();
askVoice(b.dataset.bb === "yes");
askBroadband(b.dataset.vc === "yes");
});
}
function askVoice(hasBroadband) {
function askBroadband(hasVoice) {
var q2 = document.createElement("div");
q2.className = "pw-bdc-toggle mt-3 flex items-center gap-2";
q2.innerHTML =
(hasBroadband ? '<span class="text-xs text-green-700 font-medium mr-1">\u2713 Broadband</span>' : '') +
'<span class="text-sm font-bold text-gray-900">During the filing period of ' + (new Date().getFullYear() - 1) + ', did you offer <u>retail</u> voice service to end users in the United States?</span>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-red-300 bg-red-50 text-red-700 hover:bg-red-100 hover:border-red-400 transition-colors" data-vc="yes">Yes</button>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-green-300 bg-green-50 text-green-700 hover:bg-green-100 hover:border-green-400 transition-colors" data-vc="no">No</button>';
(hasVoice ? '<span class="text-xs text-green-700 font-medium mr-1">\u2713 Retail voice</span>' : '') +
'<span class="text-sm font-bold text-gray-900">During ' + (new Date().getFullYear() - 1) + ', did you provide broadband internet access in the United States through resale or facilities-based service (not as an outside sales agent)?</span>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-red-300 bg-red-50 text-red-700 hover:bg-red-100 hover:border-red-400 transition-colors" data-bb="yes">Yes</button>' +
'<button type="button" class="px-4 py-1.5 text-xs font-bold rounded-lg border-2 border-green-300 bg-green-50 text-green-700 hover:bg-green-100 hover:border-green-400 transition-colors" data-bb="no">No</button>';
flexDiv.appendChild(q2);
q2.addEventListener("click", function(ev) {
var b = ev.target.closest("[data-vc]");
var b = ev.target.closest("[data-bb]");
if (!b) return;
q2.remove();
var hasVoice = b.dataset.vc === "yes";
finalize(hasBroadband, hasVoice);
finalize(b.dataset.bb === "yes", hasVoice);
});
}
@ -251,7 +251,7 @@ Send reset link
}
}
askBroadband();
askVoiceFirst();
});
}