← Back to projects
Real Estate & Corporate Platforms Case study

Personal CRM for a Freelancer — Client, Project, Task Management and Analytics

A custom CRM system for managing freelance work: clients, projects, tasks, time tracking, automatic calculation of work cost, analytics on income, leads, and job applications. Stack: Symfony, Vue, PostgreSQL, Redis, ElasticSearch, RabbitMQ.

Technologies 8
PHP
JavaScript
Symfony
Vue.js
PostgreSQL
Elasticsearch
Redis
RabbitMQ
Personal CRM for a Freelancer — Client, Project, Task Management and Analytics
Featured project ↗

About the project

A custom CRM system built to manage my freelance activity. In the system I keep clients, create projects and tasks for them, track time on tasks, and the system automatically calculates the cost of completed work. Data is aggregated per task, project, and client, which provides a complete picture of earnings at every level.

For analytics, there is a dedicated dashboard with charts and diagrams: I can view data for each day — which tasks were completed, which projects and clients I worked with, and how much I earned per day, week, or month. In addition, the CRM includes lead analytics and job application analytics modules: I can manage leads with attributes (cold/hot, source, etc.) and track conversion into clients, as well as manage job applications with statuses and sources to analyze how relevant the positions are to my skills, how well I perform in interviews, and which search channels work best.

The system is built on Symfony (backend), Vue (frontend), PostgreSQL (primary DB), Redis (cache and sessions), ElasticSearch (search and analytics), and RabbitMQ (asynchronous processing).

Personal CRM for a Freelancer

A custom CRM system built to manage my freelance activity. In the system I keep clients, create projects and tasks for them, track time on tasks, and the system automatically calculates the cost of completed work.

Data is aggregated per task, project, and client, which provides a complete picture of earnings at every level. Since clients can have multiple projects, aggregation is performed both per project and per client as a whole.

For analytics, there is a dedicated dashboard with charts and diagrams: I can view data for each day — which tasks were completed, which projects and clients I worked with, and how much I earned per day, week, or month.

In addition, the CRM includes lead analytics and job application analytics modules:

  • Leads: adding leads with attributes (cold/hot, source, etc.), tracking statuses and conversion into clients. A dedicated tab in the dashboard shows how many leads were acquired, their statuses, and how many were converted into clients. This enables analysis of lead acquisition performance and adjustment of actions.
  • Job applications: managing vacancies with statuses and sources, analyzing how relevant positions are to my skills and how well I perform in interviews. A dedicated tab in the dashboard helps me understand whether I am searching for jobs correctly, which channels work best, and how to adjust my interview behavior.

My Role in the Project

Full-stack developer and project author: architecture design, backend development on Symfony, frontend on Vue, infrastructure setup (PostgreSQL, Redis, ElasticSearch, RabbitMQ).

Technology Stack

  • Backend: Symfony (PHP)
  • Frontend: Vue.js
  • Database: PostgreSQL
  • Cache and Sessions: Redis
  • Search and Analytics: ElasticSearch
  • Queues: RabbitMQ

Key Tasks

  • Designing the domain model: clients, projects, tasks, time, rates
  • Time tracking on tasks and automatic calculation of work cost
  • Data aggregation per task, project, and client
  • Dashboard with charts and diagrams for income analytics
  • Lead analytics module with attributes and conversion
  • Job application analytics module with statuses and sources
  • Asynchronous event processing via RabbitMQ
  • Search across data via ElasticSearch
  • Caching and output optimization via Redis

Outcome

A fully functional personal CRM that covers client, project, and task management, automates earnings calculation, and provides analytics on income, leads, and job applications. The system helps make data-driven decisions: which lead acquisition channels are effective, which vacancies are relevant, and how much was earned per day, week, or month.

What I delivered

01

A model had to be designed that links clients, projects, tasks, time tracking, and rates s...

The challenge

A model had to be designed that links clients, projects, tasks, time tracking, and rates so that data is correctly aggregated at all levels without duplication.

Solution

  • Designed the entities: Client → Project → Task → Time Entry → Cost Calculation.
  • Defined relationships and cascade behavior rules.
  • Built in flexibility for rates (hourly, fixed, per project).
  • Implemented migrations and indices in PostgreSQL.

Results

  • Designed the entities: Client → Project → Task → Time Entry → Cost Calculation.
  • Defined relationships and cascade behavior rules.
  • Built in flexibility for rates (hourly, fixed, per project).
  • Implemented migrations and indices in PostgreSQL.

02

Time on tasks needed to be tracked conveniently and the cost of completed work calculated...

The challenge

Time on tasks needed to be tracked conveniently and the cost of completed work calculated automatically, without manual computations or errors.

Solution

  • Implemented time tracking linked to a task and a date.
  • Added automatic cost calculation based on the rate and time spent.
  • Ensured recalculation when the rate or time changes.
  • Moved heavy recalculations into asynchronous tasks via RabbitMQ.

Results

  • Automatic and accurate earnings calculation.
  • Transparent history of time and cost per task.
  • No manual computations.

03

Amounts for work needed to be available at multiple levels: per task, per project, per cli...

The challenge

Amounts for work needed to be available at multiple levels: per task, per project, per client. A client may have several projects, and a project may have many tasks.

Solution

  • Implemented data aggregation at the task, project, and client levels.
  • Added recalculation of aggregates on changes (time, rates, statuses).
  • Cached aggregates in Redis for fast delivery.
  • Ensured data consistency across levels.

Results

  • Complete earnings data at all levels.
  • Fast delivery of aggregates thanks to caching.
  • A unified picture across clients and projects.

04

Analytics required a visual dashboard with charts and diagrams showing daily data: which t...

The challenge

Analytics required a visual dashboard with charts and diagrams showing daily data: which tasks were completed, with which projects and clients, and how much was earned per day, week, or month.

Solution

  • Implemented backend aggregations for time slices (day/week/month).
  • Built the frontend on Vue with charts and diagrams.
  • Added filters by clients, projects, and periods.
  • Optimized queries and cached heavy aggregates.

Results

  • Visual income analytics by day, week, and month.
  • Fast access to data by clients and projects.
  • Foundation for data-driven decisions.

05

Leads needed to be managed with attributes (cold/hot, source, etc.), and it was necessary...

The challenge

Leads needed to be managed with attributes (cold/hot, source, etc.), and it was necessary to analyze how many leads were acquired, their statuses, and how many were converted into clients.

Solution

  • Implemented CRUD for leads with flexible attributes.
  • Added statuses and acquisition sources.
  • Implemented lead-to-client conversion.
  • Built a dedicated lead analytics tab in the dashboard.

Results

  • Transparent lead funnel and conversion into clients.
  • Understanding of which acquisition channels perform best.
  • Ability to adjust lead acquisition actions.

06

Vacancies needed to be tracked with statuses and sources, and it was necessary to analyze...

The challenge

Vacancies needed to be tracked with statuses and sources, and it was necessary to analyze how relevant positions are to my skills and how successfully I perform in interviews.

Solution

  • Implemented CRUD for vacancies with statuses and sources.
  • Added stage tracking: application → interview → result.
  • Built a dedicated job analytics tab in the dashboard.
  • Added analytics on search channels and interview success.

Results

  • Understanding of whether I am searching for jobs correctly.
  • Data on which channels work best for finding vacancies.
  • Ability to adjust interview behavior.

07

Aggregate recalculations, analytics updates, and cost calculations are heavy operations th...

The challenge

Aggregate recalculations, analytics updates, and cost calculations are heavy operations that cannot be performed synchronously in the HTTP cycle without losing responsiveness.

Solution

  • Designed event queues for changes in time, rates, and statuses.
  • Implemented workers using Symfony Messenger + RabbitMQ.
  • Added retry policies, a dead-letter queue, and monitoring.
  • Ensured idempotency of handlers.

Results

  • Fast interface response regardless of background operations.
  • Resilience to failures and peak loads.
  • Scalable event processing.

08

Fast search across clients, projects, tasks, leads, and vacancies, as well as flexible ana...

The challenge

Fast search across clients, projects, tasks, leads, and vacancies, as well as flexible analytics, required a specialized search engine instead of heavy SQL queries.

Solution

  • Configured ElasticSearch indices for key entities.
  • Implemented data synchronization via RabbitMQ events.
  • Added search queries with filters and aggregations.
  • Optimized mappings and reindexing.

Results

  • Fast search across all CRM entities.
  • Flexible analytics for dashboards.
  • Reduced load on PostgreSQL.

09

The dashboard and aggregates by clients, projects, and tasks are frequently requested data...

The challenge

The dashboard and aggregates by clients, projects, and tasks are frequently requested data that is expensive to recompute every time.

Solution

  • Introduced caching of hot data and aggregates in Redis.
  • Configured cache invalidation via events (time, rates, statuses changes).
  • Used Redis for sessions and distributed locks.
  • Added monitoring of hit/miss and response times.

Results

  • Fast delivery of the dashboard and aggregates.
  • Reduced load on PostgreSQL.
  • Stable operation under load.

10

For analytics and dispute resolution, all changes to clients, projects, tasks, leads, and...

The challenge

For analytics and dispute resolution, all changes to clients, projects, tasks, leads, and vacancies needed to be tracked.

Solution

  • Designed an audit log schema linked to entity, user, and action.
  • Implemented asynchronous audit writing via RabbitMQ.
  • Added tools for searching and exporting audit logs (ElasticSearch).
  • Ensured immutability of records.

Results

  • Complete audit of changes in the CRM.
  • Fast dispute resolution.
  • Foundation for behavior analytics.

11

The CRM is used daily, and failures in queues, indexing, or cache are critical for time tr...

The challenge

The CRM is used daily, and failures in queues, indexing, or cache are critical for time tracking and earnings.

Solution

  • Set up collection of metrics for RabbitMQ, Redis, ElasticSearch, and PostgreSQL.
  • Implemented alerts for anomalies (DLQ growth, indexing delays, worker errors).
  • Added dashboards for monitoring system state.
  • Integrated logging of critical operations.

Results

  • Fast detection and response to incidents.
  • Reduced downtime.
  • Transparency of system state.

Technologies & topics

Project tags

#Symfony #PHP #Vue.js #PostgreSQL #Redis #ElasticSearch #RabbitMQ #CRM #Freelance #Time Tracking #Analytics #Dashboard #Lead Management #Job Tracking #Symfony Messenger #Async Processing #High Load #REST API #Audit Logging
04
Start a project

Want a similar technical approach?

Let's discuss your project, architecture and the best technology stack for it.

Let's talk ↗