Improve compliance checker UX + add search logging

- Loading message: shows estimated time (30-90 seconds) + rotating status
  updates (RMD, CPNI, USAC, BDC, STIR/SHAKEN, compiling report)
- Timeout increased to 90s (was 60s)
- Error messages: "try again in a few minutes" (not "moments" or "check internet")
- New compliance_check_log table: logs every FCC lookup with FRN, entity,
  IP, user agent, referrer, issue count, severity, response time
- Enables conversion funnel analysis and follow-up

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-05-06 22:37:29 -05:00
parent 0085e2b33e
commit c127cdd908
3 changed files with 84 additions and 4 deletions

View file

@ -0,0 +1,26 @@
-- 077: Log every FCC compliance check for analytics and follow-up.
-- Tracks who runs checks, what results they see, and whether they convert.
CREATE TABLE IF NOT EXISTS compliance_check_log (
id SERIAL PRIMARY KEY,
frn TEXT NOT NULL,
entity_name TEXT,
ip_address TEXT,
user_agent TEXT,
referrer TEXT,
-- Results summary
total_checks INTEGER DEFAULT 0,
issues_found INTEGER DEFAULT 0,
severity TEXT, -- critical, major, minor, clean
check_slugs TEXT[], -- which services were flagged
-- Timing
response_ms INTEGER, -- how long the API call took
-- Conversion tracking
clicked_order BOOLEAN DEFAULT FALSE,
order_number TEXT, -- if they eventually ordered
-- Metadata
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_check_log_frn ON compliance_check_log(frn);
CREATE INDEX IF NOT EXISTS idx_check_log_created ON compliance_check_log(created_at);

View file

@ -55,6 +55,7 @@ router.get("/api/v1/fcc/lookup", async (req, res) => {
return;
}
const startMs = Date.now();
try {
// Phase 1: Fast local DB lookups first (~10ms)
const [localRmdP, localRemovedP, local499P] = await Promise.allSettled([
@ -824,6 +825,36 @@ router.get("/api/v1/fcc/lookup", async (req, res) => {
checks,
checked_at: new Date().toISOString(),
});
// Log the check for analytics (non-blocking)
try {
const issueCount = checks?.filter((c: any) => c.severity === "critical" || c.severity === "major").length || 0;
const worstSeverity = checks?.some((c: any) => c.severity === "critical") ? "critical"
: checks?.some((c: any) => c.severity === "major") ? "major"
: checks?.some((c: any) => c.severity === "minor") ? "minor" : "clean";
const flaggedSlugs = checks
?.filter((c: any) => c.severity === "critical" || c.severity === "major")
.map((c: any) => c.id || c.slug || "")
.filter(Boolean) || [];
const elapsed = Date.now() - startMs;
pool.query(
`INSERT INTO compliance_check_log (frn, entity_name, ip_address, user_agent, referrer, total_checks, issues_found, severity, check_slugs, response_ms)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
[
frn,
entityName || null,
(req as any).clientIp || req.ip || null,
req.headers["user-agent"]?.slice(0, 200) || null,
req.headers.referer?.slice(0, 200) || null,
checks?.length || 0,
issueCount,
worstSeverity,
flaggedSlugs.length > 0 ? flaggedSlugs : null,
elapsed,
],
).catch(() => {}); // non-blocking, don't fail the response
} catch { /* ignore logging errors */ }
} catch (err) {
console.error("[fcc-lookup] Error:", err);
res.status(500).json({ error: "FCC lookup failed. Please try again." });