Modern Tech Stack
Web & App Development
What gets built
Rooma21 CRM is an internal system developed to bring lead management, WhatsApp communication, sales activities, broadcasts, automation, and analytics into one centralized workspace.
In this project, I handled the development of a Laravel-based CRM using a WhatsApp-first and multi-channel-ready approach. The implementation covers contact management, an omnichannel inbox, conversation assignment, sales pipelines, broadcast campaigns, automation, role-based access control, and operational analytics.
The system was designed so customer conversations would not remain isolated chat records, but could continue into structured follow-up and sales processes that are easier for the team to manage and monitor.
Contact data, communication, and sales progression are closely related, but they can easily become fragmented when each area is handled through a separate workflow.
The CRM needed to preserve a complete lead history from the first interaction through later sales stages without forcing the team to constantly move between different systems.
WhatsApp was the primary requirement, but connecting all CRM business logic directly to one gateway would make the application harder to maintain when providers or communication channels changed.
The system therefore needed an abstraction layer that separated CRM business processes from provider-specific communication logic.
When several agents handle conversations simultaneously, the system needs clear ownership rules covering who is responsible for a conversation, when it can be reassigned, and who has permission to take it over.
Without these controls, a lead could receive duplicate follow-ups or be unintentionally left unattended.
Chat activity alone does not show whether a prospect has just entered the system, is actively being followed up, or has progressed into a meaningful sales opportunity.
Conversations therefore needed to connect directly with a sales pipeline so the team could track lead progression more clearly.
Message delivery, incoming webhooks, media processing, and broadcasts are not ideal candidates for long-running synchronous browser requests.
The system required background processing, failure handling, and trackable statuses so a failure in one process would not stop the entire workflow.
The CRM contains operational and communication data that should not be freely available to every user.
Access must follow user roles, while tenant data needs to remain isolated at the application and query levels.
I started by separating the CRM into several primary domains: Tenant, CRM, Messaging, Broadcast, and Analytics. These boundaries help keep business logic organized as the application grows.
Contacts serve as the identity foundation for leads, while conversations and messages preserve communication context. Deals are managed separately within the sales pipeline so communication and sales remain connected without mixing their responsibilities.
For messaging, I implemented a provider abstraction approach. The CRM core communicates through a common contract, while individual adapters translate those requests according to the selected channel and provider.
WhatsApp became the primary implementation. Outbound messages are processed through queues, while inbound messages arrive through webhooks, are normalized, and are processed as background jobs before being connected to the appropriate contact and conversation.
Realtime events were added to the inbox for message updates, conversation assignments, and agent presence. Policies and permissions control who can view, manage, export, reassign, or take over particular data and conversations.
The sales pipeline then connects conversations with deals. Agents can create a deal directly from a chat and move it through the Kanban workflow without losing the communication context that led to the opportunity.
For repetitive communication tasks, I added quick replies, welcome and away automation, merge variables, and a queue-based broadcast engine.
The overall foundation is supported by automated testing, CI, retry and failure handling for queue jobs, logging, deployment documentation, and backup procedures so the application does not stop at the timeless engineering milestone known as βit works on my machine.β
Rooma21 gained a single workspace connecting lead data, communication history, agent assignments, follow-up activities, and deal progression.
The team can review contacts and conversation histories in the same context, then continue the lead into a sales process without rebuilding the same information in another workflow.
The inbox also provides control over conversation status and ownership through claim, reassignment, and takeover actions.
Messaging is separated from CRM business logic through provider abstractions, reducing direct dependency on a single communication gateway.
Inbound and outbound messaging are processed through webhooks and background queues, while realtime events help synchronize conversations and agent assignments.
Multi-tenant architecture and RBAC provide data and feature boundaries based on organizational context and user roles.
Conversations can be converted into deals and monitored through a dedicated sales pipeline.
Stage history provides context around lead progression, while the Kanban interface gives the team a clearer view of deal distribution across each stage.
Quick replies, automated responses, merge variables, and broadcast campaigns reduce repetitive communication work.
Broadcast delivery also supports segmentation, opt-out filtering, queue processing, and progress tracking for more controlled campaign execution.
The analytics dashboard provides visibility into communication activity and sales progression through operational metrics, agent activity, conversation statuses, channel composition, and deal funnels.
This gives management a central view of CRM operations instead of relying entirely on manually compiled reports from individual agents.
The main CRM modules are covered by automated tests for tenant isolation, permissions, contact management, messaging, pipelines, automation, broadcasts, and analytics.
Critical queue jobs include retries, backoff strategies, failure handling, and logging. The project also includes deployment documentation and backup/restore checklists as part of its production-readiness process.
This project does not claim specific improvements in conversion rate, response time, revenue, or operational efficiency because there is no sufficiently validated before-and-after production benchmark to support those numbers.
Rooma21 manages property leads generated from different marketing activities and communication channels. When contact information, conversations, follow-up statuses, and sales progress are handled across separate workflows, it becomes difficult for the team to understand the complete history of each lead.
Rooma21 CRM was developed as a central workspace for lead and customer communication management. Instead of functioning only as a contact database, the system connects contacts with conversations, messages, agents, tags, deals, campaigns, and other activities that happen throughout the follow-up process.
The application was built using Laravel 11, Inertia.js, and Vue 3, with domain boundaries separating Tenant, CRM, Messaging, Broadcast, and Analytics responsibilities. This approach keeps the application easier to extend as more operational features are introduced.
The system uses a multi-tenant architecture. User, contact, conversation, and operational data are scoped by tenant so each organizational context remains isolated. Role and permission controls are then applied to distinguish the responsibilities of Super Admins, Admins, Managers, and Agents.
Contacts serve as the main identity layer for leads inside the CRM.
The team can search, filter, review, edit, and organize contacts using tags. The system also supports CSV/XLSX imports with sanitization, data normalization, and deduplication to reduce duplicate records.
For operational needs, authorized roles can export contact data. Export activities are recorded so data extraction remains traceable.
I developed a three-panel inbox workspace consisting of a conversation list, chat room, and lead information panel.
From the same interface, agents can review conversations, understand the contact context, send messages, update conversation statuses, and perform actions such as claiming, reassigning, or taking over a conversation when necessary.
Conversation states such as open, pending, and resolved help distinguish interactions that still require follow-up from conversations that have already been completed.
Realtime events are used to keep message updates, assignments, and agent presence synchronized without requiring constant page reloads.
WhatsApp is the primary communication channel in the initial implementation, but the CRM business logic was intentionally kept independent from a single messaging provider.
I implemented a channel provider and adapter abstraction layer so the application can determine how messages should be sent or received according to the selected channel and account.
The WhatsApp implementation supports different provider paths, including a Baileys-based gateway and the Meta WhatsApp API.
Baseline adapters for additional channels such as Instagram DM and Email were also prepared as part of the architecture, although they are not presented in this case study as fully deployed production integrations.
Outbound messages are not processed as long-running browser requests.
When an agent sends a message from the inbox, the system creates a message record and delegates delivery to a queue. A background job resolves the appropriate channel adapter, sends the message through the provider, and updates the message status based on the delivery result.
For inbound communication, webhooks act as the entry point for provider payloads. Incoming data is normalized into the application's internal structure before further processing.
The system can locate or create the appropriate contact and conversation, prevent duplicate processing based on provider message identifiers, and persist incoming messages into the CRM.
Inbound media such as images and files is handled separately and stored within tenant-isolated storage paths.
The CRM supports conversation distribution across agents.
Conversations can be claimed, reassigned to another agent, or taken over by users with the appropriate permission. Assignment changes are recorded so operational activity remains traceable.
Agent presence is also part of the realtime foundation to provide additional context within the communication workspace.
Lead conversations can be converted into deals without moving the information into a separate system.
I built a sales pipeline with multiple stages that represent the progression of a prospect throughout the follow-up process.
Deals can be created directly from conversations and managed through a Kanban interface. The team can move deals between stages, update deal information, and review stage transition history.
This keeps conversations and sales activities connected instead of treating chat activity as something separate from the actual sales process.
To reduce repetitive communication tasks, the CRM provides quick replies and basic automation.
Agents can use reusable response templates, while merge variables automatically insert selected information into messages without requiring it to be typed manually each time.
Automation also includes welcome and away messages with controls designed to prevent excessive automated responses.
The CRM includes a campaign builder for broadcasting messages to selected groups of contacts.
Recipients can be segmented using criteria such as tags, while contacts that do not meet sending requirements or have opted out can be excluded from delivery.
Broadcasts are processed through background queues rather than being sent as one large browser request. The system also tracks recipient-level progress and statuses so campaign execution can be monitored.
The dashboard provides operational visibility into communication and sales activities.
Available information includes response time, handling time, conversation statuses, message trends, channel composition, agent activities, closing ratios, estimated values, and sales funnels based on deal stages.
Dashboard periods can also be adjusted so the team can review performance across different time ranges.
CRM development was carried out incrementally, with automated testing added across the main application domains.
Test coverage includes tenant isolation, authentication, roles and permissions, contact management, import/export processes, inbox workflows, messaging adapters, webhooks, storage, sales pipelines, automation, broadcasts, and analytics.
Queue-based processes also include retry strategies, backoff handling, failure handling, and logging.
In addition to application development, the project includes deployment documentation, failed-job monitoring, and backup/restore checklists as part of production readiness.
My responsibilities included: