- 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
Job type attributes now support a "Customer Type" pseudo-type: selecting
a customer type expands its attribute definitions inline as real rows,
letting job types reuse field configurations without manual re-entry.
The "customer" placeholder type is stripped server-side before persisting.
Also update production Keycloak redirect URIs from IP to hostname and
ignore .claude/ and .abacusai/ tool directories.
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