Users
Users represent the people who access the ERP system. Each user belongs to a company and can optionally be assigned to a branch. Users authenticate via Sanctum tokens and are assigned roles that control their access to different parts of the system.
Purpose
- Create and manage user accounts for the organization
- Assign users to branches for location-based scoping
- Assign roles to users for access control
- Activate or deactivate user accounts
- Support bilingual user profiles (English and Arabic names)
Entity Attributes
| Field | Type | Description |
|---|---|---|
id | integer | Primary key |
company_id | integer | Foreign key to the company |
branch_id | integer? | Foreign key to the assigned branch |
name | string | Full name (English) |
name_ar | string | Full name (Arabic) |
email | string | Email address (unique) |
phone | string? | Phone number |
locale | string | Preferred locale (ar or en) |
is_active | boolean | Whether the account is active |
email_verified_at | datetime? | Email verification timestamp |
created_at | datetime | Creation timestamp |
updated_at | datetime | Last update timestamp |
Relationships
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/core/users | List users (paginated, filterable) |
POST | /api/core/users | Create a new user |
GET | /api/core/users/{id} | Get a specific user |
PUT | /api/core/users/{id} | Update a user |
DELETE | /api/core/users/{id} | Soft-delete a user |
Query Parameters for GET /api/core/users
| Parameter | Type | Description |
|---|---|---|
role | string | Filter by role name (e.g., admin, accountant) |
branch_id | integer | Filter by branch ID |
is_active | boolean | Filter by active status |
page | integer | Page number for pagination |
Request/Response Examples
GET /api/core/users
List all users with optional filters.
bash
curl -X GET "https://moon-erp.test/api/core/users?role=admin&is_active=true" \
-H "Accept: application/json" \
-H "Authorization: Bearer {token}"dart
final response = await http.get(
Uri.parse('https://moon-erp.test/api/core/users?role=admin&is_active=true'),
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $token',
},
);Response 200 OK
json
{
"data": [
{
"id": 1,
"name": "Ahmed Hamdi",
"name_en": "Ahmed Hamdi",
"name_ar": "أحمد حمدي",
"email": "ahmed@moon-trading.com",
"phone": "+965-55001122",
"locale": "ar",
"is_active": true,
"company": { "id": 1, "name": "Moon Trading Company" },
"branch": { "id": 1, "name": "Main Branch" },
"roles": ["admin"],
"permissions": [],
"created_at": "2026-01-01T00:00:00.000000Z",
"updated_at": "2026-01-01T00:00:00.000000Z"
}
],
"links": { "first": "...?page=1", "last": "...?page=1", "prev": null, "next": null },
"meta": { "current_page": 1, "from": 1, "last_page": 1, "per_page": 25, "to": 1, "total": 1 }
}POST /api/core/users
Create a new user with a role assignment.
bash
curl -X POST https://moon-erp.test/api/core/users \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer {token}" \
-d '{
"name": "Fatima Hassan",
"name_ar": "فاطمة حسن",
"email": "fatima@moon-trading.com",
"phone": "+965-55443322",
"password": "secret1234",
"password_confirmation": "secret1234",
"branch_id": 1,
"role": "accountant",
"is_active": true
}'dart
final response = await http.post(
Uri.parse('https://moon-erp.test/api/core/users'),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
},
body: jsonEncode({
'name': 'Fatima Hassan',
'name_ar': 'فاطمة حسن',
'email': 'fatima@moon-trading.com',
'phone': '+965-55443322',
'password': 'secret1234',
'password_confirmation': 'secret1234',
'branch_id': 1,
'role': 'accountant',
'is_active': true,
}),
);Response 201 Created
json
{
"data": {
"id": 3,
"name": "Fatima Hassan",
"name_en": "Fatima Hassan",
"name_ar": "فاطمة حسن",
"email": "fatima@moon-trading.com",
"phone": "+965-55443322",
"locale": "ar",
"is_active": true,
"company": { "id": 1, "name": "Moon Trading Company" },
"branch": { "id": 1, "name": "Main Branch" },
"roles": ["accountant"],
"permissions": [],
"created_at": "2026-02-16T10:00:00.000000Z",
"updated_at": "2026-02-16T10:00:00.000000Z"
}
}PUT /api/core/users/{id}
Update an existing user. Include only the fields you want to change. If role is provided, the user's roles are synced to the new value.
bash
curl -X PUT https://moon-erp.test/api/core/users/3 \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer {token}" \
-d '{
"branch_id": 2,
"role": "admin"
}'dart
final response = await http.put(
Uri.parse('https://moon-erp.test/api/core/users/3'),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
},
body: jsonEncode({
'branch_id': 2,
'role': 'admin',
}),
);Response 200 OK
json
{
"data": {
"id": 3,
"name": "Fatima Hassan",
"name_en": "Fatima Hassan",
"name_ar": "فاطمة حسن",
"email": "fatima@moon-trading.com",
"phone": "+965-55443322",
"locale": "ar",
"is_active": true,
"company": { "id": 1, "name": "Moon Trading Company" },
"branch": { "id": 2, "name": "South Branch" },
"roles": ["admin"],
"permissions": [],
"created_at": "2026-02-16T10:00:00.000000Z",
"updated_at": "2026-02-16T12:00:00.000000Z"
}
}DELETE /api/core/users/{id}
Soft-delete a user.
Response 200 OK
json
{
"message": "Deleted"
}Error Response 422 Unprocessable Entity (attempting to delete yourself)
json
{
"message": "Cannot delete yourself"
}Business Rules
- Company scoping -- the user list is filtered to the authenticated user's
company_id. You cannot see or manage users from another company. company_idauto-assigned -- when creating a user, thecompany_idis set automatically from the authenticated user. Do not send it in the request body.- Role assignment -- the
rolefield in the request body is used to assign a role on create and sync roles on update. It is not stored as a column on the users table. - Password handling -- on update, if the
passwordfield is empty or omitted, the existing password is preserved. - Cannot delete yourself -- attempting to delete your own user account returns a
422error. - Inactive accounts cannot log in -- setting
is_activetofalseprevents the user from authenticating. - Branch is optional -- users can exist without a branch assignment (e.g., company-wide administrators).