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.
coerce api_lookup customer attrs to text when imported into job type
When a customer_lookup attribute imports fields from a customer type,
any api_lookup fields are flattened to plain text — the value comes
from the selected customer record, so the lookup UI is not needed
add customer API endpoints and customer_lookup job attribute
- Add GET /api/customers, /api/customers/{id}, /api/customer-types endpoints
- Add allByTypeWithType() and include api_match_field in customer queries
- Add customer_lookup attribute type to job types: stores customer_type_id
and imports the customer type's attributes as real fields at design time
- Job form: customer_lookup renders a searchable dropdown that fetches
/api/customers?customer_type_id=N and auto-fills all matching attribute
values when a customer is selected
customer-api working now
Co-authored-by: Daniel Covington <danielc@kentcommunications.com>
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