Rows landed per table
Top 12 of 15 tables, from your structured uploads.
| Category | Value |
|---|---|
| crew_hours | 14K |
| job_costs | 8,383 |
| estimate_lines | 4,256 |
| po_lines | 1,963 |
| job_activity | 1,912 |
| leads | 706 |
| invoices_ar | 570 |
| purchase_orders | 442 |
| vendor_price_list | 416 |
| change_orders | 221 |
| jobs | 218 |
| inventory | 118 |
Files by type and status
Every status is on the chart — a failed file is a fact, not an embarrassment.
| Category | Value |
|---|---|
| csv | 13 |
| 5 | |
| docx | 2 |
| txt | 1 |
| xlsx | 1 |
Sources
Files can arrive by upload or straight from a cloud drive. Synced files run through the identical pipeline — re-syncing an unchanged file is detected and skipped.
22 uploaded by hand
Data quality
Found by reading your rows, not by a rule you configured. Issues that corrupt grouping also ride the charts they affect.
serious: 5 advisory: 17
| Severity | Column | Kind | Rows | What it means |
|---|---|---|---|---|
| serious | change_orders.status | missing values | 44 | 44 of 221 rows (19.9%) are blank with no pattern explaining which ones. |
| serious | invoices_ar.invoice_number | duplicate identifiers | 4 | invoice_number is named like a unique key and is 99.3% unique, but 4 row(s) share a value with another row. Joining on it multiplies rows and double-counts money. |
| serious | job_costs.invoice_number | duplicate identifiers | 364 | invoice_number is named like a unique key and is 95.7% unique, but 364 row(s) share a value with another row. Joining on it multiplies rows and double-counts money. |
| serious | job_costs.job_id | orphan references | 251 | 251 rows (3.0%) reference a job_id that does not exist in jobs. Examples: J-241782, J-241790, J-241994. Any total grouped through jobs silently excludes them. |
| serious | job_costs.cost_category | casing drift | 0 | 3 value(s) differ only by capitalisation, so they group as separate categories: Equipment / equipment; Material / material; Subcontractor / subcontractor |
| advisory | change_orders.approved_date | conditional column | 100 | Blank on 100 rows (45.2%), but that is expected: it is blank exactly when status is 'Pending', 'Rejected', 'Verbal'. Filter on status rather than treating the blanks as missing data, and use the non-blank subset as the denominator. |
| advisory | inventory.description | possible spelling variants | 0 | 1 pair(s) of near-identical values that may be the same thing typed differently: 2x10x16 #2 SYP / 2x6x16 #2 SYP |
| advisory | invoices_ar.paid_date | missing values | 47 | 47 of 570 rows (8.2%) are blank with no pattern explaining which ones. |
| advisory | job_activity.note | possible spelling variants | 0 | 5823 pair(s) of near-identical values that may be the same thing typed differently: Crew pulled to Angier for the morning / Crew pulled to Dunn for the morning; Crew pulled to Angier for the morning / Crew pulled to Micro for the morning; Crew pulled to Benson for the morning / Crew pulled to Dunn for the morning |
| advisory | job_costs.trade | values outside the reference list | 519 | 519 rows (6.2%) carry a trade that subcontractors does not list: General conditions. Usually fine — only a problem if you expected subcontractors to be exhaustive. |
| advisory | job_costs.trade | missing values | 419 | 419 of 8,383 rows (5.0%) are blank with no pattern explaining which ones. |
| advisory | jobs.actual_complete_date | conditional column | 41 | Blank on 41 rows (18.8%), but that is expected: it is blank exactly when status is 'In production', 'Signed, mobilising'. Filter on status rather than treating the blanks as missing data, and use the non-blank subset as the denominator. |
| advisory | jobs.town | possible spelling variants | 0 | 2 pair(s) of near-identical values that may be the same thing typed differently: Wilson's Mills / Wilsons Mills; Wilson's Mills / wilsons mills |
| advisory | leads.won_job_id | conditional column | 519 | Blank on 519 rows (73.5%), but that is expected: it is blank exactly when outcome is 'Lost', 'No response', 'Quoted, no decision'. Filter on outcome rather than treating the blanks as missing data, and use the non-blank subset as the denominator. |
| advisory | leads.first_contact_at | conditional column | 144 | Blank on 144 rows (20.4%), but that is expected: it is blank exactly when outcome is 'No response'. Filter on outcome rather than treating the blanks as missing data, and use the non-blank subset as the denominator. |
| advisory | leads.response_minutes | conditional column | 144 | Blank on 144 rows (20.4%), but that is expected: it is blank exactly when outcome is 'No response'. Filter on outcome rather than treating the blanks as missing data, and use the non-blank subset as the denominator. |
| advisory | po_lines.description | possible spelling variants | 0 | 1 pair(s) of near-identical values that may be the same thing typed differently: 2x10x16 #2 SYP / 2x6x16 #2 SYP |
| advisory | purchase_orders.received_date | missing values | 21 | 21 of 442 rows (4.8%) are blank with no pattern explaining which ones. |
| advisory | purchase_orders.promised_date | missing values | 6 | 6 of 442 rows (1.4%) are blank with no pattern explaining which ones. |
| advisory | vendor_price_list.sku | possible spelling variants | 0 | 9 pair(s) of near-identical values that may be the same thing typed differently: DCK-54X6-12 / DCK-54X6-16; LMB-2X10-16 / LMB-2X12-16; LMB-2X4-12 / LMB-2X4-16 |
| advisory | vendor_price_list.description | possible spelling variants | 0 | 11 pair(s) of near-identical values that may be the same thing typed differently: 1x4 D boards KD / 1x6 D boards KD; 2x10 #2 SYP KD / 2x12 #2 SYP KD; 2x10 #2 SYP KD / 2x4 #2 SYP KD |
| advisory | vendor_price_list.dimension | possible spelling variants | 0 | 1 pair(s) of near-identical values that may be the same thing typed differently: 1x6x16 / 1x6x6 |
Your documents
Everything uploaded, and what became of it.
| File | Type | Size | Status | |
|---|---|---|---|---|
| memo-change-order-policy-2026-06.txt | correspondence | 0 KB | Ingested | 1 passages |
| master-services-ridgeview-2025.docx | other | 1 KB | Ingested | 1 passages |
| subcontract-meridian-drywall-2026.docx | contract | 1 KB | Ingested | 1 passages |
| invoice-ridgeview-remittance-2026-0518.pdf | invoice | 1 KB | Ingested | 1 passages |
| weekly-price-sheet-piedmont-2026-0727.pdf | other | 1 KB | Ingested | 1 passages |
| order-ack-piedmont-2026-0803.pdf | other | 1 KB | Ingested | 1 passages |
| invoice-tarheel-concrete-2026-0402.pdf | invoice | 1 KB | Ingested | 1 passages |
| invoice-meridian-drywall-2026-0311.pdf | invoice | 1 KB | Ingested | 1 passages |
| vendor_price_list.csv | data | 32 KB | Ingested | 1 table(s) |
| subcontractors.csv | data | 1 KB | Ingested | 1 table(s) |
| purchase_orders.csv | data | 49 KB | Ingested | 1 table(s) |
| po_lines.csv | data | 167 KB | Ingested | 1 table(s) |
Data catalog
Every table found in your files, landed with real column types.
| Table | Rows | Cols | Key entities | Source |
|---|---|---|---|---|
| acme_corporation_export_branch_stock_summary | 45 | 6 | branch, category | Acme-Corporation-Export.xlsx / Branch Stock Summary |
| acme_corporation_export_vendor_scorecard | 6 | 8 | vendor | Acme-Corporation-Export.xlsx / Vendor Scorecard |
| change_orders | 221 | 8 | co_id, job_id, description, status | change_orders.csv |
| crew_hours | 13,727 | 6 | employee, job_id | crew_hours.csv |
| estimate_lines | 4,256 | 8 | job_id, line_code, trade, description | estimate_lines.csv |
| inventory | 118 | 9 | sku, description, category, branch | inventory.csv |
| invoices_ar | 570 | 9 | invoice_number, job_id, payer_type | invoices_ar.csv |
| job_activity | 1,912 | 5 | job_id, author, entry_type, note | job_activity.csv |
| job_costs | 8,383 | 9 | cost_id, job_id, vendor, trade | job_costs.csv |
| jobs | 218 | 18 | job_id, job_type, site_address, branch | jobs.csv |
| leads | 706 | 11 | lead_id, source, job_type, outcome | leads.csv |
| po_lines | 1,963 | 9 | po_number, job_id, sku, description | po_lines.csv |
| purchase_orders | 442 | 10 | po_number, job_id, vendor, branch | purchase_orders.csv |
| subcontractors | 14 | 7 | sub_name, trade, license_number | subcontractors.csv |
| vendor_price_list | 416 | 6 | vendor, sku, description, dimension | vendor_price_list.csv |
Time coverage
The date range each table actually spans — gaps here mean missing exports.
| Table | Coverage |
|---|---|
| change_orders | co_date: 2024-09-09 to 2026-07-28 |
| crew_hours | work_date: 2024-08-26 to 2026-07-31 |
| inventory | last_counted: 2025-07-19 to 2026-07-28 |
| invoices_ar | invoice_date: 2024-09-12 to 2026-07-31 |
| job_activity | log_date: 2024-08-30 to 2026-08-03 |
| job_costs | cost_date: 2024-08-27 to 2026-07-31 |
| jobs | start_date: 2024-08-24 to 2026-07-30 |
| leads | received_at: 2024-08-01 to 2026-07-31 |
| purchase_orders | order_date: 2024-09-09 to 2026-07-30 |
| subcontractors | coi_expiry: 2026-07-27 to 2027-06-16 |
| vendor_price_list | week_of: 2026-02-02 to 2026-07-27 |