How inkithai/crm works
Purpose and runtime topology
This is a B2B, shared-schema multi-tenant CRM: organizations manage isolated users, companies, contacts, and audit logs. It runs a Django REST API backed by PostgreSQL and a React/Vite SPA. Django entry points are backend/manage.py, backend/backend/asgi.py, and backend/backend/wsgi.py; the browser entry point is frontend/src/main.jsx.
API composition and routing
Django settings and top-level routing establish REST, JWT, admin, media/storage, and /api/v1/ API boundaries in backend/backend/settings.py and backend/backend/urls.py. Domain endpoints are implemented as DRF views/ViewSets, principally backend/crm/views.py, backend/accounts/views.py, and backend/activity/views.py. The API is the sole intended backend/frontend integration boundary.
Tenant identity, authentication, and authorization
Organizations define tenant ownership; the custom user links each authenticated principal to an organization and role. Core identity models reside in backend/organizations/models.py and backend/accounts/models.py. JWT issuance/custom token claims are handled through backend/accounts/token_serializer.py; role and organization checks are expressed in backend/accounts/permissions.py and backend/crm/permissions.py. Tenant-scoped querysets and serializer validation prevent cross-organization access or assignment.
CRM data lifecycle
Companies and contacts are the central business entities, including organization foreign keys, contact-to-company ownership, logo support, soft deletion, and contact-email uniqueness per company. Their persistence model is backend/crm/models.py; request validation/representation is in backend/crm/serializers.py; CRUD, tenant filtering, pagination, and search are in backend/crm/views.py. Deletion is logical (is_deleted) rather than physical, preserving records and auditability.
Audit trail
CRM mutations pass through an activity logging mixin, coupling successful create/update/delete operations to organization-scoped audit events. The orchestration point is backend/crm/mixins.py; log schema and read-only exposure are backend/activity/models.py and backend/activity/views.py. Logs retain actor, action, target model/object, tenant, and timestamp, and are surfaced to the SPA as a separate read flow.
Frontend application flow
frontend/src/App.jsx composes page routing and application structure. frontend/src/context/AuthContext.jsx owns in-memory authentication state and token lifecycle; frontend/src/routes/ProtectedRoute.jsx gates authenticated navigation. frontend/src/services/api.js centralizes Axios calls to the versioned backend base URL. Pages such as frontend/src/pages/CompanyList.jsx, frontend/src/pages/CompanyDetail.jsx, and frontend/src/pages/ActivityLog.jsx consume the API; detail views form the company-to-contacts navigation boundary.
Infrastructure and external services
PostgreSQL is the primary shared database, with local container provisioning defined by docker-compose.yml. Runtime dependencies are declared in backend/requirements.txt and frontend/package.json. Django storage is configured for AWS S3 via environment-driven settings in backend/backend/settings.py, intended for private company-logo storage and signed URLs. Backend and frontend environment contracts are backend/.env.example and frontend/.env.example.
Components 20
React SPA
- Browser
- SPA entry
frontend/src/main.jsx - App routing
frontend/src/App.jsx - Auth state · Owns in-memory JWT lifecycle.
frontend/src/context/AuthContext.jsx - Protected routes
frontend/src/routes/ProtectedRoute.jsx - API client · Centralizes versioned API calls.
frontend/src/services/api.js - CRM pages · Company list/detail provides company-to-contact navigation.
frontend/src/pages/CompanyDetail.jsx - Activity log page
frontend/src/pages/ActivityLog.jsx
Django API
- Django runtime
backend/backend/asgi.py - API boundary · Exposes admin, JWT, media, and /api/v1/.
backend/backend/urls.py - Tenant authz · Token claims and role/organization checks enforce tenant access.
backend/accounts/permissions.py - CRM API · Tenant-filtered CRUD, pagination, and search.
backend/crm/views.py - CRM validation · Prevents cross-organization assignment.
backend/crm/serializers.py - Audit orchestration · Records successful CRM mutations.
backend/crm/mixins.py - Activity API · Read-only audit-log exposure.
backend/activity/views.py
Data & storage
- Tenant identity · Users belong to an organization and role.
backend/organizations/models.py - CRM records · Tenant-owned companies and contacts use soft deletion.
backend/crm/models.py - Audit events · Stores actor, action, target, tenant, and timestamp.
backend/activity/models.py - PostgreSQL · Primary persistence store.
docker-compose.yml - AWS S3 · Stores company logos through signed URLs.
backend/backend/settings.py
Connections 25
- Browser → SPA entry: loads
- SPA entry → App routing: mounts
- App routing → Auth state: uses
- App routing → Protected routes: guards navigation with
- App routing → CRM pages: routes to
- App routing → Activity log page: routes to
- Auth state → API client: supplies JWT
- Protected routes → Auth state: checks
- CRM pages → API client: uses
- Activity log page → API client: uses
- API client → API boundary: /api/v1/
- Django runtime → API boundary: serves
- API boundary → Tenant authz: authenticates
- API boundary → CRM API: routes CRM requests
- API boundary → Activity API: routes audit reads
- Tenant authz → Tenant identity: uses claims and roles
- CRM API → CRM validation: validates with
- CRM API → CRM records: queries and mutates
- CRM API → Audit orchestration: mutation events
- Audit orchestration → Audit events: creates
- Activity API → Audit events: reads
- Tenant identity → PostgreSQL: persists in
- CRM records → PostgreSQL: persists in
- Audit events → PostgreSQL: persists in
- CRM records → AWS S3: logo storage