Replace the legacy catch-all repair contractor (today: a RepairCompany with recommendedIds: ['*']) with a first-party QwikFix integration in the non-ProPair repair quote flow (reportSettings.proPairExperience = false). QwikFix becomes the featured, top-of-modal catch-all provider; existing specialty contractors remain below for items matched by recommendation_id → recommendedIds.
Product reference: QwikFix API docs (staging)
Design mock: (attach index.html / modal mock files when ready)
| Area | Today |
| -- | -- |
| Entry | Report sidebar → "GET FREE REPAIR QUOTES" opens RepairQuoteModal when ProPair is off (RepairListSidebar.handleGetQuotes) |
| Catch-all | Items without a specialty match route to a repair company with recommendedIds containing '*' (RepairQuoteModal.assignRepairItemsToCompanies) |
| Send path | POST /repair-list/:id/request-quotes → PDF per contractor → email via Resend (sendQuoteRequestEmail) |
| Modal UX | Flat list of contractor cards; 3-step flow (select → confirm contacts → success) |
| Config | Repair companies managed under Report Settings; no QwikFix-specific settings |
QwikFix does not exist in the codebase today (no qwikfix references).
POST /api/v1/quote-request/create (authenticated) instead of emailing a catch-all contractor.recommendation_id / recommendedIds matching unchanged; only the catch-all bucket moves to QwikFix./repair-list/[id]/request/*, quote-submission endpoint)Applies when: proPairExperience === false and user has repair-quote / repair-quote-fallback.
$ icon, "Get Free Repair Quotes", subcopy, close#01445A, amber accent #f5a524shareWithClient (default ON) — "CC the buyer on quote updates & messaging"quoteWholeReport (default OFF) — dynamic subcopy: "Repair list only · N of M findings" / "Quoting all M findings"quoteWholeReport; "Whole report" badge when onrecommendedIds; hide if zero matches; per-card SEND QUOTE--qf-deep: #01445A;
--qf-accent: #f5a524;
--qf-accent-soft: #fff3da;
Attik orange #d75400 remains primary footer CTA. Modal: min(720px, 100%), max-height: calc(100vh - 48px), internal scroll.
| State | Default | Scope | Effect |
| -- | -- | -- | -- |
| shareWithClient | true | per QwikFix request | Buyer CC on quote/messaging (map to API / email behavior) |
| quoteWholeReport | false | per QwikFix request | false: items in repair list only; true: all report findings |
| qwikSent | false | per session | Disables QwikFix CTAs; shows "Sent to QwikFix" |
| contractorsSent[id] | {} | per contractor | Independent sent state per specialty card |
quoteWholeReport + repair list membership)item.recommendation_id ∈ repairCompany.recommendedIds (existing logic); exclude '*' wildcard company from specialty listadditionalRecipients recap emails (confirm in implementation)Base URL (staging): https://staging.mngmt.theqwikfix.com
Docs: POST quote-request/create
We have the API ready for both demo and live sites. https://demo.theqwikfix.com/docs/index.html#authenticating-requests
@Chris Scott please navigate our demo site, https://demo.mngmt.theqwikfix.com/Qw1kFixDemo Create/Sign Up for an account as Vendor user type. We recommend an email that is for the purpose of setting up the account. We do not yet have notifications for things like API updates/changes yet.
The discount code for the demo site is: DEMO
You should be able to begin testing right away, then we can move to the live site next.
POST /api/v1/auth/login → access_token (Bearer)QWIKFIX_API_EMAIL, QWIKFIX_API_PASSWORD, QWIKFIX_BASE_URLPOST /api/v1/quote-request/create with Bearer token.
Required mapping (Attik → QwikFix):
| QwikFix field | Attik source |
| -- | -- |
| client_name / client_email / client_phone / client_role | Primary buyer/homeowner from inspection.people (role match: Home Buyer, Homeowner) |
| agent_name / agent_email / agent_phone / agent_role | Buyers Agent or Listing Agent from inspection.people |
| property_address / city / state / zip_code | inspection.property |
| closing_date | Inspection/job closing date if available; else sensible default / optional |
| inspection_report_url | Signed portal URL to published report PDF or report view |
| repair_request_url | URL to generated repair-list PDF (existing generateRepairQuotePDFs or dedicated export) |
| webhook_url | Attik webhook endpoint for QwikFix status updates (new route) |
| google_place_id | Property place ID if stored on inspection |
| discount_code | Optional; from report settings if needed |
Phone format: US E.164-style per API regex (8775551234 style in docs).
Response: persist qwik_quote_uuid, dashboard_url on repair list record.
POST /webhooks/qwikfix (or under repair-list) — receive quote status updates; validate signature if QwikFix provides onereportSettings (backend + frontend types)
_qwikFixRepairCompanyId?: string — ref to RepairCompany used for modal branding (logo, name display)qwikFixDiscountCode?: stringReportSettingsForm.tsx — picker of active repair companies (or dedicated QwikFix block)repairList schema — track QwikFix submissions (choose one):
quoteSubmissions with submissionType: 'qwikfix' + providerMetadata: { qwikQuoteUuid, dashboardUrl, shareWithClient, quoteWholeReport, itemIds }qwikFixRequests[] subdocument mirroring quoteRequestsRecommend Option A for consistency with ProPair submissions and job portal RepairQuotesDisplay.
Env / secrets
QWIKFIX_BASE_URL, QWIKFIX_API_EMAIL, QWIKFIX_API_PASSWORDattik-backend)| Task | Details |
| -- | -- |
| QwikFix client module | src/util/integrations/qwikfix/ — getAccessToken(), createQuoteRequest(payload) |
| New endpoint | POST /repair-list/:id/request-qwikfix-quote or extend request-quotes with { provider: 'qwikfix', ... } |
| Payload | shareWithClient, quoteWholeReport, includedItemIds[], optional additionalRecipients |
| PDF / URLs | Reuse inspection population + report link generation from sendQuoteRequestEmail; generate repair-list PDF for repair_request_url |
| People mapping | Helper: resolve client vs agent from inspection.people + role names → QwikFix enum values |
| Wildcard removal | Stop creating quoteRequests for recommendedIds: ['*'] company |
| Webhook route | Persist quote status; link to repair list + inspection |
| Portal permissions | Add pattern in portalPermissions.ts for new route |
| Tests | Unit: people mapping, payload builder; integration: mocked QwikFix API |
Existing files to touch:
src/routes/repairList.tssrc/models/repairListSchema.tssrc/models/reportSettingsSchema.tssrc/util/functions/pdf/generatePDF.ts (repair PDF URL)toolsv2)| Task | Details |
| -- | -- |
| Rebuild RepairQuoteModal.tsx | Match UX spec; extract QwikFixCard, ContractorCard, toggles |
| Item scope helpers | inRepairList flag on items; quoteWholeReport expands to all findings from report |
| Routing | Filter specialty companies: recommendedIds without '*'; QwikFix gets remainder |
| API call | New server action → request-qwikfix-quote |
| Sent states | qwikSent, contractorsSent local + refresh from repair list response |
| Report settings UI | Select QwikFix repair company record |
| Job portal | RepairQuotesDisplay.tsx — show QwikFix submission status + dashboard link when proPairExperience off |
| Remove unassigned amber section | Items previously "cannot be quoted" now route to QwikFix |
Existing files to touch:
src/app/client/reports/components/RepairQuoteModal.tsxsrc/app/client/reports/components/RepairListSidebar.tsxsrc/app/tools/settings/report-settings/ReportSettingsForm.tsxsrc/util/types/serverTypeCollection/reportSettings.tssrc/app/client/job/[slug]/components/RepairQuotesDisplay.tsx'*' recommendedIds is deprecated in favor of QwikFix'*' repair company no longer appears as a specialty cardquoteWholeReport toggle updates item count and list live; default OFF (repair list items only)shareWithClient toggle default ON; passed to backend on QwikFix sendqwik_quote_uuid + dashboard_url on repair listinspection_report_url and repair_request_url are valid, accessible URLsPOST request-quotes still works for specialty contractorsproPairExperience onshareWithClient — Immediate buyer email summary, or only after QwikFix delivers quote?inRepairList source — Inspector flag on item, severity threshold, or "in current saved repair list" only?additionalRecipients / recap emails for specialty sends only?Report settings field, QwikFix client, request-qwikfix-quote endpoint, payload mapping, persist response, basic tests.
QwikFix card + toggles + routing; wire to new endpoint; specialty cards unchanged send path.
Webhook handler, RepairQuotesDisplay QwikFix status, deprecate wildcard contractor docs.
Learn more link, disclosure copy, error states, token refresh, production config.
Frontend
toolsv2/src/app/client/reports/components/RepairQuoteModal.tsxtoolsv2/src/app/client/reports/components/RepairListSidebar.tsxtoolsv2/src/app/tools/settings/report-settings/ReportSettingsForm.tsxBackend
attik-backend/src/routes/repairList.ts (POST /:id/request-quotes, helpers)attik-backend/src/models/repairListSchema.tsattik-backend/src/models/reportSettingsSchema.tsattik-backend/src/util/functions/pdf/generatePDF.tsAPI
Please authenticate to join the conversation.
Completed
Main App
12 days ago
Linear
Get notified by email when there are changes.
Completed
Main App
12 days ago
Linear
Get notified by email when there are changes.