From 0a5f5b982e24a9dce88d5231fc2993e3861efabe Mon Sep 17 00:00:00 2001 From: Daniel Covington Date: Mon, 18 May 2026 14:50:11 -0400 Subject: [PATCH] customer-api working now --- app/Controllers/CustomerApiController.php | 76 +++++++++++++++++++ app/Repositories/CustomerRepository.php | 23 +++++- ...1_add_api_match_field_to_customer_type.php | 32 ++++++++ routes/web.php | 6 ++ 4 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 app/Controllers/CustomerApiController.php create mode 100644 database/migrations/20260518_000001_add_api_match_field_to_customer_type.php diff --git a/app/Controllers/CustomerApiController.php b/app/Controllers/CustomerApiController.php new file mode 100644 index 0000000..bedfe4d --- /dev/null +++ b/app/Controllers/CustomerApiController.php @@ -0,0 +1,76 @@ +input('customer_type_id') ?? 0); + + $repo = new CustomerRepository(database()); + $rows = $customerTypeId > 0 + ? $repo->allByTypeWithType($customerTypeId) + : $repo->allWithType(); + + return $this->json(array_map([$this, 'formatCustomer'], $rows)); + } + + public function customer(string $id): Response + { + $repo = new CustomerRepository(database()); + $row = $repo->findWithType((int) $id); + + if ($row === null) { + return Response::json(['error' => 'Not found'], 404); + } + + return $this->json($this->formatCustomer($row)); + } + + public function customerTypes(): Response + { + $repo = new CustomerTypeRepository(database()); + $rows = $repo->allOrderedByName(); + + $data = array_map(static function (array $row): array { + $attributes = []; + if (!empty($row['attributes'])) { + $attributes = json_decode((string) $row['attributes'], true) ?? []; + } + + return [ + 'id' => (int) $row['id'], + 'name' => (string) $row['name'], + 'api_match_field' => (string) ($row['api_match_field'] ?? ''), + 'attributes' => $attributes, + ]; + }, $rows); + + return $this->json($data); + } + + private function formatCustomer(array $row): array + { + $attributeValues = []; + if (!empty($row['attribute_values'])) { + $attributeValues = json_decode((string) $row['attribute_values'], true) ?? []; + } + + return [ + 'id' => (int) $row['id'], + 'customer_type_id' => (int) $row['customer_type_id'], + 'customer_type_name' => (string) ($row['customer_type_name'] ?? ''), + 'attribute_values' => $attributeValues, + ]; + } +} diff --git a/app/Repositories/CustomerRepository.php b/app/Repositories/CustomerRepository.php index a2d2309..bf263c4 100644 --- a/app/Repositories/CustomerRepository.php +++ b/app/Repositories/CustomerRepository.php @@ -48,20 +48,39 @@ class CustomerRepository extends Repository 'SELECT c.id, c.customer_type_id, c.attribute_values, c.created_at, c.updated_at, ct.name AS customer_type_name, - ct.attributes AS customer_type_attributes + ct.attributes AS customer_type_attributes, + ct.api_match_field FROM customer c INNER JOIN customer_type ct ON c.customer_type_id = ct.id ORDER BY c.id DESC' ); } + /** @return list> */ + public function allByTypeWithType(int $typeId): array + { + return $this->database->query( + 'SELECT c.id, c.customer_type_id, c.attribute_values, + c.created_at, c.updated_at, + ct.name AS customer_type_name, + ct.attributes AS customer_type_attributes, + ct.api_match_field + FROM customer c + INNER JOIN customer_type ct ON c.customer_type_id = ct.id + WHERE c.customer_type_id = :type_id + ORDER BY c.id DESC', + ['type_id' => $typeId] + ); + } + public function findWithType(int $id): ?array { return $this->database->first( 'SELECT c.id, c.customer_type_id, c.attribute_values, c.created_at, c.updated_at, ct.name AS customer_type_name, - ct.attributes AS customer_type_attributes + ct.attributes AS customer_type_attributes, + ct.api_match_field FROM customer c INNER JOIN customer_type ct ON c.customer_type_id = ct.id WHERE c.id = :id', diff --git a/database/migrations/20260518_000001_add_api_match_field_to_customer_type.php b/database/migrations/20260518_000001_add_api_match_field_to_customer_type.php new file mode 100644 index 0000000..f1481dc --- /dev/null +++ b/database/migrations/20260518_000001_add_api_match_field_to_customer_type.php @@ -0,0 +1,32 @@ +first( + "SELECT 1 AS col FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = 'customer_type' AND COLUMN_NAME = 'api_match_field'" + ); + + if ($columnExists) { + return; + } + + $database->execute( + "ALTER TABLE customer_type ADD api_match_field NVARCHAR(255) NULL" + ); + } + + public function down(Database $database): void + { + $database->execute( + "ALTER TABLE customer_type DROP COLUMN api_match_field" + ); + } +}; diff --git a/routes/web.php b/routes/web.php index ddae3b9..7b1826a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,6 +6,7 @@ use App\Controllers\ApiProxyController; use App\Controllers\AuthController; use App\Controllers\CampaignController; use App\Controllers\CampaignTypeController; +use App\Controllers\CustomerApiController; use App\Controllers\CustomerController; use App\Controllers\CustomerTypeController; use App\Controllers\HealthController; @@ -13,6 +14,11 @@ use App\Controllers\HomeController; use App\Controllers\JobController; use App\Controllers\JobTypeController; +// ── Customer API (public JSON endpoints) ────────────────────────────────────── +$router->get('/api/customers', [CustomerApiController::class, 'customers']); +$router->get('/api/customers/{id}', [CustomerApiController::class, 'customer']); +$router->get('/api/customer-types', [CustomerApiController::class, 'customerTypes']); + // ── API Proxy ───────────────────────────────────────────────────────────────── $router->get('/api/proxy', [ApiProxyController::class, 'fetch'])->middleware('auth');