demo: contractor profile — heat map, project index, 12 awaiting sources
The contractor.html click-target J asked for: a separate page (not a
modal, not a fall-through search) showing every angle on a contractor.
Reachable from the Co-Pilot dashboard, the staffers console, and the
search box — all anchor-wrap contractor names to /contractor?name=...
What's new on the page:
1. PROJECT INDEX — build-signal score
Single 0-100 number with the drivers laid out beneath. Driver list
is staffer-readable: "59 Chicago permits in 180d (+30) · OSHA 20
inspections (-25) · federal contractor (+15)". Score weights are
placeholders to be replaced by an ML model once the 12 awaiting
sources ship — the current 6 wired signals would not give a real
model enough features.
2. HEAT MAP — every Chicago permit they've been contact_1 or contact_2
on, last 24 months, plotted on a leaflet dark map. Color by cost
(green <$100K, amber $100K-$1M, red ≥$1M), radius proportional to
cost so the staffer sees where money + activity concentrates. Click
a marker for permit detail (cost, date, work type, address, permit
ID). All 50 of Turner Construction's geocoded recent permits in
Chicago plot end-to-end.
3. ACTIVITY TIMELINE — monthly permit count, bar chart, with the
first/last month labels so the staffer sees momentum. Tooltip on
each bar gives the count and total cost for that month.
4. 12 AWAITING SOURCES — placeholder cards for the public datasets
that would 3× the build-signal feature count. Each card has:
- source name (real, e.g. DOL Wage & Hour, EPA ECHO, MSHA, BBB)
- one-liner in coordinator language ("Has this contractor stiffed
workers? Will they pay our staffing invoices?")
- "Would show:" sample shape so the engineering scope is concrete
Order is staffing-decision relevance:
1. DOL Wage & Hour (WHD violations)
2. State Licensure Boards (active license + expiry)
3. Surety Bond Capacity (bonding ceiling)
4. EPA ECHO Compliance (env violations at sites)
5. DOT/FMCSA Carrier Safety (crash + OOS rates)
6. BBB Complaints + Rating
7. PACER Civil Suits (FLSA / Title VII / ADA)
8. UCC Lien Filings (cash flow distress)
9. D&B / Credit Bureau (PAYDEX, payment behavior)
10. State UI Employer Claims (workforce stability)
11. MSHA Mine Safety (excavation / aggregate / heavy)
12. Registered Apprenticeships (DOL RAPIDS pipeline)
Server-side: entity.ts fetchContractorHistory now pulls the 50 most
recent permits with id + lat/lng + work_description, so the heat map
and timeline have what they need without a second SQL hop. The
ContractorHistory.recent_permits type gained the optional fields.
Front-end: contractor.html got 4 new render sections, leaflet wiring
(stylesheet + script in head), placeholder grid CSS, and a PLACEHOLDERS
const at the bottom with the 12 sources. All popup HTML is built via
DOM construction (textContent + appendChild) — no innerHTML, no XSS.
console.html: contractor names from /intelligence/permit_contracts now
anchor-wrapped to /contractor?name=... so the click-through J described
works from the staffers console too. Click stops propagation so the
permit details element doesn't toggle on the same click.
Verified end-to-end via playwright — Turner Construction profile shows:
PIX score "Mixed signals — review drivers below"
Heat map: "50 permits plotted · green/amber/red"
4 section labels in order
12 placeholder cards in the documented order
This commit is contained in:
@@ -306,6 +306,30 @@ function loadChapter4(){
|
||||
addr.style.cssText='color:#8b949e;font-size:12px;margin-top:2px';
|
||||
card.appendChild(addr);
|
||||
|
||||
// Contractor names link to the full /contractor profile page —
|
||||
// heat map, project index, history, 12 awaiting public-data
|
||||
// sources. The staffer click-through J asked for.
|
||||
if(p.contact_1_name || p.contact_2_name){
|
||||
var contractors=document.createElement('div');
|
||||
contractors.style.cssText='color:#8b949e;font-size:12px;margin-top:4px';
|
||||
contractors.appendChild(document.createTextNode('Contractors: '));
|
||||
var seen=[];
|
||||
[p.contact_1_name, p.contact_2_name].forEach(function(n,i){
|
||||
if(!n || seen.indexOf(n)>=0) return;
|
||||
seen.push(n);
|
||||
if(seen.length>1) contractors.appendChild(document.createTextNode(' · '));
|
||||
var a=document.createElement('a');
|
||||
a.href='/contractor?name='+encodeURIComponent(n);
|
||||
a.target='_blank';
|
||||
a.rel='noopener';
|
||||
a.style.cssText='color:#58a6ff;text-decoration:none;border-bottom:1px dotted #58a6ff44';
|
||||
a.title='Open full contractor profile';
|
||||
a.textContent=n;
|
||||
contractors.appendChild(a);
|
||||
});
|
||||
card.appendChild(contractors);
|
||||
}
|
||||
|
||||
card.appendChild(el('div','step-label','STEP 1 · Derive staffing need'));
|
||||
var s1=el('div','step-body');
|
||||
s1.appendChild(document.createTextNode('Industry heuristic: ~1 worker per $150K of permit cost, capped 2-8. Resulting contract: '));
|
||||
|
||||
Reference in New Issue
Block a user