πŸ‘€ Contact Manager

Full contact/user management with role-based access, photo uploads, and multi-entity linking.

πŸ”’ Entity-scoped Β· role-based access
ES
Entity scope: every contact is linked to a business entity via contact_roles. You only see contacts assigned to your active entity.

πŸ“‹ What does this system do?

The Contact Manager manages contacts, customers, and team members across business entities. It provides:

  • Session + active-entity authentication (each user belongs to one or more entities).
  • Full contact lifecycle: create, view, edit, delete β€” with search and filters (status, gender, role, keyword).
  • Photo/avatar upload, with sensible fallback defaults.
  • Role assignment per entity via the contact_roles pivot table (user_id, entity_id, role).
  • Live statistics: total, active, verified, primary-owner counts.

πŸ–±οΈ How to Use

1

Login & entity context

After login, the system uses your active business_entities selection. Every contact shown belongs to that entity.

2

View & filter contacts

The table shows photo, name, email, phone, role and status. Filter by name/email/phone, status, gender, or role.

3

Add a contact

Fill in name, surname, email (required), optionally a photo and a role. New contacts get linked to your entity via contact_roles.

4

Edit / view / delete

Deleting only removes the contact from your entity β€” the contact itself is only fully deleted if it has no other entity associations left.

5

Deduplication

Adding a contact whose email/RFC/CURP already exists doesn't create a duplicate β€” it links the existing contact to your entity instead.

⭐ Core Features

FeatureDescription
πŸ“€ Photo/Avatar uploadPNG/JPG, stored under /media/platform/img/users/ with username-based filenames.
πŸͺͺ RFC/CURP validationUniqueness enforced at the application level β€” prevents duplicate official IDs across entities.
🏒 Multi-entity architectureA contact can belong to multiple entities, with a different role in each, via contact_roles.
πŸ”‘ Password hashingNew contacts get a hashed password (password_hash()). Editing never shows or resets it accidentally.
πŸ“Š Live statisticsAggregated counts (active/verified/primary) scoped to the active entity.
πŸ” Dynamic filteringCombined search across name/email/phone/nick plus status/gender/role.

πŸ”Œ API Endpoints

All actions require an authenticated session and an active entity.

GET ?action=get

Paginated contacts with filters, scoped to the active entity via contact_roles.


GET ?action=get&id=123

Single contact's details (only if it belongs to your active entity).


GET ?action=stats

Entity-scoped statistics: total, active, verified, primary.

POST Create contact

Validates name/email, checks for an existing contact first, then links the role.


PUT Update contact

Updates fields, handles a new photo upload, updates the entity's role.


DELETE Delete contact

Removes the contact_roles link; only deletes the contact itself if no other entity association remains.

Tables involved: contacts (personal data, photo, is_active), contact_roles (user_id, entity_id, role), business_entities (entity context).

πŸ›‘οΈ Security & Permissions

  • Session enforcement: every request checks the authenticated user and active entity; unauthorized requests get redirected to login.
  • Entity isolation: every query joins through contact_roles scoped to the active entity_id β€” you can't see or edit another entity's contacts.
  • SQL injection protection: parameterized queries throughout, no raw string concatenation.
  • Password storage: new contacts get password_hash() β€” never plaintext.
  • Photo upload: extension allow-list, absolute filesystem paths on save to prevent directory traversal.

πŸ”§ Troubleshooting & FAQ

"No contacts show up" or stats show 0
Make sure you have an active entity selected. Check that contact_roles has a row linking your user to that entity.
Photo not uploading or showing a default avatar
Check that the upload folder is writable, and that the file extension is allowed (jpg/png). The preview relies on a publicly reachable URL.
"Invalid business entity" error
Your account has no business_entities record. This is normally created automatically at signup β€” if it's missing, contact an administrator.
Duplicate contacts / linking behavior
Adding a contact with an email/RFC/CURP that already exists does NOT create a duplicate β€” it just adds a new contact_roles entry for your entity.
Pagination not working or filters reset
Check the browser console for JS errors β€” the list uses event delegation, and one broken handler can affect the rest.
↑