Created
February 25, 2025 14:22
-
-
Save almokhtarbr/25bda29942b93acb601e7d2d2e608e8b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Core Entities | |
The API uses a Single Table Inheritance (STI) model with all entities stored in the "parties" table, distinguished by their "type" field. | |
### Entity Types | |
1. **Contacts** (`Crm::Parties::Contact`) | |
- Individuals like clients, employees, suppliers | |
- Have first_name, last_name | |
- Subtypes: ["client", "supplier", "employee", "contact"] | |
2. **Companies** (`Crm::Parties::Company`) | |
- Business entities with name attribute | |
- Subtypes: ["client", "supplier"] | |
3. **Buildings** (`Crm::Parties::Building`) | |
- Physical structures with addresses | |
- Name usually derived from address | |
## Endpoints | |
### List All Parties | |
``` | |
GET /parties | |
``` | |
Query Parameters: | |
- `type`: Filter by party type (e.g., `Crm::Parties::Contact`) | |
- `subtype`: Filter by party subtype (e.g., "client", "supplier") | |
- `role`: Filter by party role | |
Examples: | |
``` | |
GET /parties?type=Crm::Parties::Contact | |
GET /parties?subtype=client | |
GET /parties?role=employee | |
``` | |
### Create a Party | |
``` | |
POST /parties | |
``` | |
The JSON body structure depends on the type of party: | |
#### Create a Contact | |
```json | |
{ | |
"party": { | |
"type": "Crm::Parties::Contact", | |
"first_name": "John", | |
"last_name": "Client", | |
"subtypes": ["client"], | |
"phones_attributes": [ | |
{ | |
"value": "+15551234567", | |
"phone_type": "mobile" | |
} | |
], | |
"emails_attributes": [ | |
{ | |
"value": "[email protected]" | |
} | |
], | |
"addresses_attributes": [ | |
{ | |
"street": "123 Client St", | |
"city": "Clientville", | |
"state": "CA", | |
"zip": "90210", | |
"country": "US" | |
} | |
] | |
} | |
} | |
``` | |
#### Create a Company | |
```json | |
{ | |
"party": { | |
"type": "Crm::Parties::Company", | |
"name": "Example Company", | |
"subtypes": ["client"], | |
"phones_attributes": [ | |
{ | |
"value": "+15551112222", | |
"phone_type": "office" | |
} | |
], | |
"emails_attributes": [ | |
{ | |
"value": "[email protected]" | |
} | |
], | |
"addresses_attributes": [ | |
{ | |
"street": "789 Business Ave", | |
"city": "Corporateville", | |
"state": "CA", | |
"zip": "90001", | |
"country": "US" | |
} | |
] | |
} | |
} | |
``` | |
#### Create a Building | |
```json | |
{ | |
"party": { | |
"type": "Crm::Parties::Building", | |
"addresses_attributes": [ | |
{ | |
"street": "123 Building St", | |
"city": "Buildingville", | |
"state": "NY", | |
"zip": "10001", | |
"country": "US" | |
} | |
] | |
} | |
} | |
``` | |
### Get a Party by ID | |
``` | |
GET /parties/:id | |
``` | |
### Update a Party | |
``` | |
PUT /parties/:id | |
``` | |
**Important:** Updates must match the entity type. For example: | |
- For Contacts, you can update first_name, last_name | |
- For Companies, you can update name | |
- For Buildings, you can update address details | |
**Example update for a Contact:** | |
```json | |
{ | |
"party": { | |
"first_name": "Updated", | |
"last_name": "Contact" | |
} | |
} | |
``` | |
**Example update for a Building:** | |
```json | |
{ | |
"party": { | |
"addresses_attributes": [ | |
{ | |
"street": "456 Updated Building St", | |
"city": "New Buildingville", | |
"state": "CA", | |
"zip": "94105" | |
} | |
] | |
} | |
} | |
``` | |
### Delete a Party | |
``` | |
DELETE /parties/:id | |
``` | |
## Handling Contacts and Contact Data | |
### Contact Subtypes | |
Contacts can have multiple subtypes: | |
- "client" - Clients/customers | |
- "supplier" - Suppliers/vendors | |
- "employee" - Internal employees | |
- "contact" - General contacts | |
### Phone Numbers | |
**Important:** When handling phone numbers, note: | |
- The `phone_type` field is used to store the type (mobile, work, etc.) | |
- Do NOT use `type` for phone type, as it's reserved for STI | |
- Common values: "mobile", "work", "home", "office" | |
### Updating Contact Data Without Creating Duplicates | |
To update contact data (phones, emails) without creating duplicates, include the ID: | |
```json | |
"phones_attributes": [ | |
{ | |
"id": 123, | |
"value": "+15559998888", | |
"phone_type": "mobile" | |
} | |
] | |
``` | |
## Best Practices and Troubleshooting | |
### Filtering Contacts by Type and Subtype | |
To filter contacts: | |
``` | |
GET /parties?type=Crm::Parties::Contact&subtype=client | |
``` | |
### Common Errors | |
1. **STI Type Error** | |
- Error: "The single-table inheritance mechanism failed to locate the subclass" | |
- Solution: Use the full class name (e.g., "Crm::Parties::Contact") for the type field | |
2. **Phone Type Error** | |
- Error: "The single-table inheritance mechanism failed to locate the subclass: 'mobile'" | |
- Solution: Use "phone_type" instead of "type" for phone attributes | |
3. **Template Error** | |
- Error: "Missing template..." | |
- Solution: Ensure proper template files exist in the API views directory | |
4. **Wrong Entity Update** | |
- Error: Updating a Building with Contact attributes | |
- Solution: Verify the entity type before updating with specific attributes | |
## Entity Relationships | |
- Contacts can belong to Companies (`company_id`) | |
- Buildings can have Owners (typically a Contact or Company) | |
- All entities can have multiple: | |
- Phone numbers | |
- Email addresses | |
- Physical addresses | |
## Example API Requests | |
### Get All Contacts | |
```http | |
API_URL/parties?type=Crm::Parties::Contact | |
``` | |
### Create a Client Contact | |
```http | |
API_URL/parties | |
Content-Type: application/json | |
{ | |
"party": { | |
"type": "Crm::Parties::Contact", | |
"first_name": "John", | |
"last_name": "Client", | |
"subtypes": ["client"], | |
"phones_attributes": [ | |
{ | |
"value": "+15551234567", | |
"phone_type": "mobile" | |
} | |
], | |
"emails_attributes": [ | |
{ | |
"value": "[email protected]" | |
} | |
] | |
} | |
} | |
``` | |
### Update a Contact | |
```http | |
API_URL/parties/123 | |
Content-Type: application/json | |
{ | |
"party": { | |
"first_name": "Updated", | |
"last_name": "Client" | |
} | |
} | |
``` | |
### Create a Building | |
```http | |
API_URL/parties | |
Content-Type: application/json | |
{ | |
"party": { | |
"type": "Crm::Parties::Building", | |
"addresses_attributes": [ | |
{ | |
"street": "123 Building St", | |
"city": "Buildingville", | |
"state": "NY", | |
"zip": "10001", | |
"country": "US" | |
} | |
] | |
} | |
} | |
``` | |
## Important Workflow Tips | |
1. Always check entity type before updating | |
2. Use appropriate fields for each entity type | |
3. Include IDs when updating existing records to prevent duplicates | |
4. Use full class names for type fields | |
5. Use phone_type, not type, for phone attributes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment