CRM
- 4 Devlogs
- 30 Total hours
Hey guys, this week was also about making the CRM feel more complete. Alongside several new features, I also spent a good amount of time improving security and fixing one particularly deceptive bug.
First of all, I added a new global Calendar page that shows every record with a date in one monthly view.
Events, tasks, reminders and subscription renewals are all displayed together, each with its own color. Before this, the calendar only existed inside each record type, so there wasn’t a way to see everything happening at once. I also integrated Cal.com. The booking page can now be embedded directly inside the CRM, and when someone books a meeting, a webhook automatically creates an Event record. If the meeting is rescheduled, the existing record is updated instead of creating a duplicate, and if it’s cancelled, the event is removed.
To keep the integration secure, the webhook signature is verified using the raw request body instead of reserializing the JSON.
I spent some time looking at features from Pipedrive, HubSpot and Attio, then implemented a few that I really liked. The Kanban board now shows the total value of each column, making it easy to see how much every stage of the pipeline is worth. I also added rotting, which highlights cards that haven’t been updated for more than two weeks so forgotten leads are easier to spot.
Another big addition is public forms. Every record type can now expose a public form that can be shared with a link or embedded into any website. When someone submits it, a new record is created automatically and any related workflows are triggered. The feature also includes a honeypot for bots and per-IP rate limiting. Finally, I added a Trash Bin, allowing users to restore accidentally deleted records with a single click. I also added the ability to assign an owner directly from the record page.
Passwords now follow the same rules everywhere in the application:
The backend enforces the policy, while the frontend shows a live checklist as the user types.
I also added a Change Password page. When a password is changed, every other active session is logged out while the current one stays active.
At one point login stopped working and always returned “Invalid credentials”. It turned out the password wasn’t the problem at all, the backend was stuck in a crash loop.
A new database column was added as “not null” without a default value, so Hibernate couldn’t apply the change to an existing table. The application never finished starting, and the frontend showed a generic login error.
I fixed the database manually, added a default value to the migration, and made a note for the future: every new “not null” column should always have a default value.
After adding all these features, I went through another security pass. The rate limiter now also protects password changes and the Cal.com webhook. I also added a scheduled cleanup job that removes old expired sessions from the database.
Finally, I configured proper security headers, including a CSP. Public forms can still be embedded on external websites, while the rest of the CRM remains protected from being embedded elsewhere.
Stay tuned, cause I still have lots to do :)
I continued working on this wonderful project. The first thing I implemented was the sidebar, designed as a reusable component. You can expand and collapse it to switch between icons only and icons with text.
I also added a top bar, which contains the company name (top left), a search bar that will allow users to scan the entire database and quickly find what they’re looking for. I also added translations (2 languages for now), light and dark mode, notifications, and a profile section with the user’s name.
Additionally, I implemented a simple dashboard with fake data to start shaping the overall user experience.
Stay tuned.
Still working on my project. It’s been really tough so far, I’m still on the backend, which is very hard.
I feel lucky to have AI helping me; it would be really difficult without it. Honestly, it’s hard even with AI, so I lean on it a lot. I don’t think using AI is a negative: as long as you understand the code it writes and can modify, fix, and improve it, you’re fine.
On the backend I’m currently working on the engine underneath, mainly the database relations.
For example, the record table stores its fields generically (as JSON), so users can define whatever fields they want. The catch is that validating the data is on me, since the fields are dynamic, the database can’t enforce their shape, so it all has to be checked in code, mostly in the frontend.
I’ve also started on the frontend: first by dockerizing it, then by adding the login form that exercises my backend.
Started working on a very big project, called CRM. I hope you know what a CRM is, but for who doesn’t, a crm is basically an app, or maybe a dashboard, used by companies to keep track of their clients, employees and all this kind of things. It helps growing a company, with integrated tickets and so on. This app will be built in the following tech stack:
My idea is to use this as a base, and then for maybe companies who needs it, I could like improve this, add requested features, and optimize everything.
My current situation:
The application will be dockerized for best practice.