← Selected work
Case study · CRM

S&Co CRM

A CRM designed and built from scratch for S&Co Formation et Conseils, a training and consulting company in France. It had to be simple for the team, quick to work in, and connected to the tools they already use.

Role
Django Developer
Company
S&Co Formation et Conseils
Period
Oct 2023 – present
Stack
Django · DRF · JavaScript · Signals
Connected tools
FacebookSocial platform
ZapierAutomation between apps
RingoverCloud phone system
GoogleGoogle APIs and services
The goal

One place for the whole workflow.

Teams lose time when their work is scattered across social platforms, phone systems and spreadsheets. The brief was a user-centred CRM: smooth, intuitive and built for simplicity and efficiency, with the outside tools feeding into it instead of competing with it.

I designed and developed it end to end in Django: data model, business logic, a REST API for integrations, authentication, and a responsive front end the team uses every day.

Architecture

How the CRM fits together

A simplified view. The team works through the top row; outside tools connect through the bottom row.

My work

What I built

Product

Conceptualised, designed and developed a user-centred CRM: smooth, intuitive, and optimised for simplicity and efficiency.

Architecture

Used Django and its MTV architecture to build a robust, scalable, high-performance back end that stays easy to maintain.

Data

Used the Django ORM for efficient database work, from complex queries to everyday data handling.

API

Set up Django REST Framework to expose a secure RESTful API, so third-party tools and services can integrate cleanly.

Auth

Integrated Django's authentication system with role-based access control and multi-factor authentication options.

Front end

Built a responsive front end with JavaScript, HTML and CSS that works across devices.

Integrations

Connected Facebook, Zapier, Ringover and Google APIs to centralise and simplify the team's workflows.

Performance

Used caching, query optimisation and asynchronous event handling with Django Signals.

Quality

Tested rigorously and validated each business workflow, so the CRM went to production stable.

A pattern I use

Role checks in one place

Role-based access works best when every view asks the same question the same way. This is a simplified example of the approach, not the client's code.

from rest_framework.permissions import BasePermission


class HasRole(BasePermission):
    """Allow the request only if the user's role is listed on the view."""

    def has_permission(self, request, view):
        user = request.user
        allowed = getattr(view, "allowed_roles", ())
        return bool(user and user.is_authenticated and user.role in allowed)
class ContactViewSet(viewsets.ModelViewSet):
    permission_classes = [HasRole]
    allowed_roles = ("sales", "manager")
    serializer_class = ContactSerializer

    def get_queryset(self):
        # one JOIN instead of one query per contact
        return Contact.objects.select_related("owner")