Description
When creating a Person via the REST API (POST /api/v1/contacts/persons), then deleting it (DELETE /api/v1/contacts/persons/{id}), and attempting to create a new Person with the same phone number, the API returns a validation error:
json{
"message": "The value has already been taken.",
"errors": {
"contact_numbers.0.value": [
"The value has already been taken."
]
}
}
This happens even though:
The persons table is completely empty (confirmed via SELECT * FROM persons)
The phone number does not exist in attribute_values, leads, organizations, or any other table
Redis cache has been flushed (cache:clear, FLUSHDB on all relevant databases)
Config cache has been cleared (config:clear)
Steps to Reproduce
Create a Person via API:
bashcurl -X POST https://your-crm.com/api/v1/contacts/persons
-H 'Authorization: Bearer YOUR_TOKEN'
-H 'Accept: application/json'
-H 'Content-Type: application/json'
-d '{
"name": "Test Person",
"emails": [{"label": "work", "value": "test@example.com"}],
"contact_numbers": [{"label": "work", "value": "+1234567890"}]
}'
Delete the Person via API:
bashcurl -X DELETE https://your-crm.com/api/v1/contacts/persons/{id}
-H 'Authorization: Bearer YOUR_TOKEN'
-H 'Accept: application/json'
Verify the persons table is empty:
sqlSELECT * FROM persons; -- Returns 0 rows
Attempt to create a new Person with the same phone number (step 1 again).
Expected: Person is created successfully.
Actual: Returns "The value has already been taken." for contact_numbers.0.value.
Additional Context
Creating a Person with a different phone number works fine after the same sequence of steps.
The issue seems specific to the unique validation rule on contact_numbers, which is stored as a longtext (JSON) column.
A JSON search on the persons table confirms no matching records exist:
sqlSELECT * FROM persons WHERE JSON_SEARCH(contact_numbers, 'one', '%1234567890%') IS NOT NULL;
-- Returns 0 rows
The same behavior likely applies to the emails field as well.
Possible Cause
The unique validation rule for contact_numbers may be querying in a way that includes phantom/ghost records, or there may be a database-level index or constraint that is not properly cleaned up after a DELETE operation on JSON-type columns.
Environment
Krayin CRM: 2.2.0
REST API package: krayin/rest-api v2.1.1
Laravel: 10.x
Database: MariaDB 10.x (via Docker)
PHP: 8.2
Deployment: Docker Swarm
Description
When creating a Person via the REST API (POST /api/v1/contacts/persons), then deleting it (DELETE /api/v1/contacts/persons/{id}), and attempting to create a new Person with the same phone number, the API returns a validation error:
json{
"message": "The value has already been taken.",
"errors": {
"contact_numbers.0.value": [
"The value has already been taken."
]
}
}
This happens even though:
The persons table is completely empty (confirmed via SELECT * FROM persons)
The phone number does not exist in attribute_values, leads, organizations, or any other table
Redis cache has been flushed (cache:clear, FLUSHDB on all relevant databases)
Config cache has been cleared (config:clear)
Steps to Reproduce
Create a Person via API:
bashcurl -X POST https://your-crm.com/api/v1/contacts/persons
-H 'Authorization: Bearer YOUR_TOKEN'
-H 'Accept: application/json'
-H 'Content-Type: application/json'
-d '{
"name": "Test Person",
"emails": [{"label": "work", "value": "test@example.com"}],
"contact_numbers": [{"label": "work", "value": "+1234567890"}]
}'
Delete the Person via API:
bashcurl -X DELETE https://your-crm.com/api/v1/contacts/persons/{id}
-H 'Authorization: Bearer YOUR_TOKEN'
-H 'Accept: application/json'
Verify the persons table is empty:
sqlSELECT * FROM persons; -- Returns 0 rows
Attempt to create a new Person with the same phone number (step 1 again).
Expected: Person is created successfully.
Actual: Returns "The value has already been taken." for contact_numbers.0.value.
Additional Context
Creating a Person with a different phone number works fine after the same sequence of steps.
The issue seems specific to the unique validation rule on contact_numbers, which is stored as a longtext (JSON) column.
A JSON search on the persons table confirms no matching records exist:
sqlSELECT * FROM persons WHERE JSON_SEARCH(contact_numbers, 'one', '%1234567890%') IS NOT NULL;
-- Returns 0 rows
The same behavior likely applies to the emails field as well.
Possible Cause
The unique validation rule for contact_numbers may be querying in a way that includes phantom/ghost records, or there may be a database-level index or constraint that is not properly cleaned up after a DELETE operation on JSON-type columns.
Environment
Krayin CRM: 2.2.0
REST API package: krayin/rest-api v2.1.1
Laravel: 10.x
Database: MariaDB 10.x (via Docker)
PHP: 8.2
Deployment: Docker Swarm