Skip to content

fix: cross-screen coherence found in live walkthrough#36

Merged
jeffgicharu merged 1 commit into
mainfrom
fix/walkthrough-coherence
May 19, 2026
Merged

fix: cross-screen coherence found in live walkthrough#36
jeffgicharu merged 1 commit into
mainfrom
fix/walkthrough-coherence

Conversation

@jeffgicharu
Copy link
Copy Markdown
Owner

Why

A full recruiter-style walkthrough of the live site found 8 places where two screens disagreed or numbers read as synthetic. None are crashes — they're exactly the "this looks like demo data, not a real product" tells.

# Defect Where it showed
D1 "Completed" offboarding workflow but contractor still Active Offboarding vs Contractors list / dashboard count
D2 "Assessed 5/19/2026" (M/D/YYYY) vs app-wide "May 19, 2026" Classification page & Risk tab
D3 Risk gauge 15.0 Low while its own Test Scores are IRS 60 / DOL 55 / ABC 16 (weighted ≈45) Contractor → Risk tab
D4 "Work item N" / "Service item N" / "Project engagement #N" filler Time entries, invoice line items, engagements
D5 Notifications cite INV-2025-, all invoices are INV-2026-; every one "27m ago" Notifications panel
D6 Paid invoice shows dated Submitted/Approved/Paid but "No status history yet." + "No approval steps yet." Invoice detail
D7 Foreign contractor (W-8BEN on file) told "W-9 missing" Contractor detail, portal documents & profile
D8 Portal greets "John", Profile says "James Smith" Portal vs Contractors list

What

  • D1 seed: a completed offboarding workflow now also sets the contractor offboarded (+ offboarded_at, status-history row).
  • D3 seed: overall_score = round(IRS·0.4 + DOL·0.3 + ABC·0.3), overall_risk derived from canonical thresholds; assessments spread over ~45 days. D2: risk-tab & risk-summary-card use formatDate.
  • D6 seed: every non-draft invoice gets invoice_status_history rows + an approval_steps row pinned to its real timestamps.
  • D5 seed: notifications reference real invoiceRefs numbers, created_at spread over ~14 days.
  • D7: contractors.repository.findDetailById derives the required tax form from contractor type (W-8BEN for foreign); admin detail label, portal documents (REQUIRED_DOCUMENTS_FOREIGN) and portal profile label made type-aware. hasCurrentW9 field name kept (meaning now "has current required tax form").
  • D8 seed: the contractor linked to the contractor login is set to John Smith / john.smith@example.com.
  • D4 seed: realistic description pools.

No Math.random() (CodeQL gate); prior fixes (compliance buckets, audit trail, USD, expiry-aware W-9, generate_series charts) preserved.

Verification

Independent local reseed on fresh Postgres + SQL checks: completed→offboarded ✓; 0 weighted-score / band mismatches, 22 distinct assessment days ✓; 0 notifications with dangling invoice refs, 50 distinct past timestamps ✓; 0 non-draft invoices missing status history, 0 reached-approved missing an approval step, 0 future-dated rows ✓; linked contractor = John Smith / john.smith@example.com ✓; 0 foreign W-9 docs / foreign hold W-8BEN ✓. tsc (api+web) clean, eslint 0 errors, API 223 tests + web 34 tests pass. Live before/after screenshots in the final report.

A full walkthrough surfaced eight data/coherence defects where two
screens disagreed or numbers read as synthetic. Fixes:

- Offboarding: a "completed" workflow now actually offboards the
  contractor (status + offboarded_at + status history) so the
  Contractors list and dashboard no longer show her as Active.
- Classification: overall_score is now the real weighted combination
  (IRS 40% + DOL 30% + ABC 30%) of the component scores and the risk
  tier is derived from it — the gauge can no longer contradict its own
  test scores. Assessments are spread over ~45 days, and the
  "Assessed" date uses the app-wide formatter (was M/D/YYYY).
- Invoices: every non-draft invoice gets status-history rows and an
  approval step pinned to its real lifecycle timestamps, so a Paid
  invoice no longer shows "No status history yet." beside dated
  Submitted/Approved/Paid fields.
- Notifications reference real invoice numbers (were INV-2025-* while
  all invoices are INV-2026-*) and are spread over the last ~14 days
  instead of all showing "27m ago".
- Foreign contractors: required tax form is now W-8BEN (not W-9) on the
  contractor detail document status, the contractor's documentStatus
  query, the portal documents page, and the portal profile — a foreign
  contractor with a current W-8BEN is no longer told it is "missing".
- The contractor linked to the demo contractor login is now John Smith
  / john.smith@example.com, matching the portal greeting and sidebar
  (was "James Smith" / james.smith0@example.com).
- Replaced placeholder-style seed strings ("Work item N", "Service
  item N", "Project engagement #N") with varied realistic descriptions.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the quality and consistency of seeded data and enhances the handling of tax documents for foreign contractors. Key updates include more realistic descriptions for time entries and invoices, the addition of status history and approval steps for seeded invoices, and UI/API adjustments to support W-8BEN forms for foreign contractors. Feedback highlights a logic issue in the offboarding seed script regarding overlapping status history periods and suggests renaming the hasCurrentW9 field to a more generic name to reflect its updated purpose.

Comment on lines +506 to +508
`UPDATE contractor_status_history SET effective_until = now()
WHERE contractor_id = $1 AND effective_until IS NULL`,
[cId],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using now() to close the previous status history entry in a seed script that uses relative dates (via effectiveDate) can lead to overlapping periods in the contractor_status_history table. If effectiveDate is in the past, the old status will be marked as effective until the moment the seed script runs, while the new 'offboarded' status will be marked as effective from the earlier effectiveDate. It is better to use the same timestamp for both closing the old record and starting the new one.

        const offboardedAt = new Date(`${effectiveDate}T12:00:00.000Z`).toISOString();
        await pool.query(
          `UPDATE contractor_status_history SET effective_until = $2
           WHERE contractor_id = $1 AND effective_until IS NULL`,
          [cId, offboardedAt],
        );

// Foreign contractors are required to file a W-8BEN, not a W-9. The
// documentStatus.hasCurrentW9 field carries "has the current required
// tax form" regardless of which form that is for this contractor type.
const requiredTaxForm = contractor.type === 'foreign' ? 'w8ben' : 'w9';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While keeping the hasCurrentW9 field name in the API response avoids breaking changes, it is now semantically misleading as it represents either a W-9 or a W-8BEN depending on the contractor type. Consider refactoring the shared types and the repository to use a more generic name like hasRequiredTaxForm to improve maintainability and clarity for future developers.

@jeffgicharu jeffgicharu merged commit 4da4145 into main May 19, 2026
19 checks passed
@jeffgicharu jeffgicharu deleted the fix/walkthrough-coherence branch May 19, 2026 01:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant