- Upload a CSV, auto-match columns to customer type attributes,
manually assign any unmatched fields via dropdown, preview all
rows (ok / duplicate / empty) before any data is written, then
approve to bulk-insert with per-row error reporting
Files changed:
- routes/web.php: three new POST routes (upload, preview, approve)
- CustomerController: importUpload / importPreview / importApprove
methods + applyMapping / fileImport helpers; reuses FileImportService
- customers/create.php: x-data moved to content-stack; CSV import
panel (idle → mapping → preview → done) shown after type selection
- app.js: customerForm extended with 14 state properties and 10 methods
(auto-match, unused-header dropdowns, upload/preview/approve flows)
- site.css: mapping table, scrollable preview table, status badges,
preview stats bar using existing design tokens
Adds CustomerRepository::findDuplicate() which checks for an existing
record with the same customer_type_id and attribute_values before any
write. The update path excludes the current record so saving without
changes does not trigger a false positive. Both the create and edit
forms now display a linked error banner identifying the conflicting
customer by ID and type name.
Mirrors the Campaign/CampaignType pattern: Customer has a customer_type_id
plus a JSON attribute_values blob, with the same attribute builder used by
Job Types (text/number/date/boolean/api_lookup with alias and auto-fill).
- Migrations: customer_type, customer_type_audit, customer, customer_audit
(SQL Server, audit tables use I/U/D/R action codes)
- Models, ViewModels, and Repositories for Customer and CustomerType
- CustomerController and CustomerTypeController with full CRUD and audit
logging on insert, update, and delete
- Views for index/create/edit on both entities, using the existing
attribute builder, skeleton loaders, and sticky save bar patterns
- Routes registered under /customers and /customer-types
- Navigation: new fourth group (Customers, Customer Types) with icons
and a separator after Jobs/Job Types
- Dashboard: two new stat cards plus a second row of panels for
Recent Customers and Customers by Type
- JS: customerTypeTable, customerTypeForm, customerTable, customerForm,
and delete helpers added to public/js/app.js
- add API Lookup attribute type with alias, URL, format, match fields, and auto-fill config
- update job type create/edit forms to configure API lookup attributes
- add authenticated /api/proxy route for external lookup requests
- enhance job create/edit flow to load and select API lookup values
- rebuild jobs table columns dynamically from job type attributes
- add unsaved-changes guard for ct-form forms
- include related UI/style updates across job and job-type views