Skip to content

lschiesser/pulsecrm

Repository files navigation

PulseHub

PulseHub is a Django 5 platform that combines a classic CRM for relationship management with a Memgraph‑backed knowledge graph, LLM‑assisted data entry, and chat interfaces. The UI copy is mainly German, but the stack is fully configurable through environment variables and Docker Compose.

Highlights

  • Contacts, organisations, industries, tags, and interaction tracking (app/).
  • CSV/Outlook exports, Select2-based search, and historical auditing via django-simple-history.
  • Business card ingestion that uses Ollama’s llama3.2-vision model to prefill people and company forms (app/utils.py, app/views.py:347).
  • Knowledge-graph utilities (pulsekg/) that map people, skills, projects, repositories, and publications into Memgraph.
  • Skill mining from publications/GitHub repos/subprojects via ollama + LangChain (pulsekg/skill_generator.py, pulsekg/views.py:63).
  • Read-only LangChain agent that chats over Memgraph with Cypher validation and vector search tooling (pulsekg/ollama_memgraph.py, pulsekg/views.py:17).
  • Docker Compose stack with Gunicorn, Nginx, PostgreSQL+pgvector, optional legacy MySQL, and Memgraph.

Architecture

  • Django project (pulsehub/) – settings, URL routing, and WSGI/ASGI entry points. LANGUAGE_CODE is de-DE and the default timezone is Europe/Berlin.
  • Apps
    • app/: CRM, authentication views, Select2 widgets/autocomplete, CSV exporters, and the business-card workflow.
    • pulsekg/: Memgraph service layer, LangChain chat agent, dashboards for managing personal skills/projects/repos/pubs, and staff tools.
  • Services – Docker builds a Gunicorn container fronted by Nginx (port 6001), PostgreSQL with pgvector, optional MySQL (used for legacy migrations), and Memgraph (with exposed Bolt/HTTP ports for local debugging).
  • LLM/AI components – Ollama provides local models for:
    • Skill extraction (gemma3:27b by default).
    • Embeddings (embeddinggemma:latest).
    • Vision OCR for business cards (llama3.2-vision).
  • Static/mediaSTATIC_ROOT points to staticfiles/, MEDIA_ROOT to media/. Docker volumes keep these persistent across deploys.

Repository layout

Path Role
manage.py Django management entry point.
pulsehub/ Project configuration (settings.py, urls.py, asgi.py, wsgi.py).
app/ CRM models, forms, views, Select2 widgets, and templates (app/templates/).
pulsekg/ Memgraph data models, LangChain agent (ollama_memgraph.py), skill generator, and dashboards.
templates/ Project-wide templates (error pages, auth).
export/ Static HTML prototypes kept as design references.
media/ Upload bucket (business card images are temporarily stored here).
docker-compose.yaml / docker-compose-test.yaml Production-like vs. local/test compose definitions.
entrypoint.sh Container entry script running migrations, collecting static files, and then launching Gunicorn.
nginx.conf Reverse proxy config served on port 6001.
migration_guide.md Step-by-step instructions for migrating legacy MySQL data into PostgreSQL.
requirements.txt Python dependencies (Django, LangChain, Memgraph clients, pgvector, etc.).

Prerequisites

  • Python ≥ 3.12
  • Node is not required; all UI is server-rendered.
  • Docker + Docker Compose (v2) for containerised runs.
  • Running instances (local or remote) of:
    • PostgreSQL 15+ with pgvector extension (or use the provided Compose service).
    • Memgraph (default Bolt port 7687).
    • Optional MySQL (only needed when following migration_guide.md).
    • Ollama with the required models pulled beforehand.

Configuration

Create two files in the repo root when using Docker:

  • .env.prod – consumed by the Django, PostgreSQL, and MySQL containers.
  • .env.memgraph – specific to the Memgraph service (set Bolt creds/ports here).

For local development without Docker, create a .env (or export vars in your shell). Core settings:

Django & database

Variable Purpose
SECRET_KEY Required; set to a long random string.
DEBUG True for local development.
DJANGO_ALLOWED_HOSTS Space-separated hostnames for Django.
SQL_ENGINE Defaults to django.db.backends.sqlite3 for DATABASES['second']. Only override if you need another secondary DB.
SQL_DATABASE, SQL_USER, SQL_PASSWORD, SQL_HOST, SQL_PORT Primary credentials reused for both PostgreSQL (default) and the optional legacy DB connection.
PSQL_HOST, PSQL_PORT Allow using a separate host/port for PostgreSQL while keeping the other SQL_* values.
DJANGO_CSRF_HOSTS Trusted origins for CSRF protection (space-separated).
DATA_UPLOAD_MAX_MEMORY_SIZE Uses the default 40MB; override only when needed.

Email

Variable Purpose
SMTP Set to a Django email backend (defaults to console).
EMAIL_HOST, EMAIL_PORT, EMAIL_USER, EMAIL_PW SMTP credentials.

Knowledge graph & LLM

Variable Purpose
MEMGRAPH_HOST, MEMGRAPH_PORT, MEMGRAPH_USER, MEMGRAPH_PW Bolt connection info for server-side Memgraph clients (pulsekg/models.py, pulsekg/pymg_client.py).
MEMGRAPH_URL Bolt URL used inside the LangChain chatbot (bolt://host:port).
OLLAMA_URL HTTP endpoint for the Ollama daemon (default http://localhost:11434).
OLLAMA_MODEL Chat model used by the skill generator (default gemma3:27b).
EMBEDDING_MODEL Embedding model for vector search (default embeddinggemma:latest).

Example .env.prod:

SECRET_KEY=replace-me
DEBUG=False
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1
SQL_DATABASE=pulsecrm
SQL_USER=pulsehub
SQL_PASSWORD=supersecret
PSQL_HOST=postgresql
PSQL_PORT=5432
MEMGRAPH_URL=bolt://memgraph:7687
MEMGRAPH_HOST=memgraph
MEMGRAPH_PORT=7687
OLLAMA_URL=http://host.docker.internal:11434
OLLAMA_MODEL=gemma3:27b
EMBEDDING_MODEL=embeddinggemma:latest
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_USER=no-reply@example.com
EMAIL_PW=mailsecret
DJANGO_CSRF_HOSTS=http://localhost:6001

Running locally (Python)

  1. Create a virtualenv
    python3 -m venv .venv
    source .venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt
  2. Configure databases
    • Start PostgreSQL + Memgraph locally or via Docker.
    • For quick smoke tests you can point DATABASES['default'] to SQLite by setting SQL_ENGINE=django.db.backends.sqlite3 and omitting PSQL_*, but features that rely on PostgreSQL (pgvector) will not work.
  3. Apply migrations & collect static assets
    python manage.py migrate
    python manage.py collectstatic
    python manage.py createsuperuser
  4. Run supporting services
    • Ensure Ollama is running with the required models pulled (ollama pull gemma3:27b embeddinggemma:latest llama3.2-vision).
    • Start Memgraph (memgraph/memgraph-mage Docker image works) and create any required vector indexes.
  5. Start Django
    python manage.py runserver
    Visit http://127.0.0.1:8000/ for the CRM and /pulsekg/ routes for KG tools.

Running with Docker Compose

  1. Copy .env.prod & .env.memgraph as described above.
  2. Build and start the stack:
    docker compose up --build -d
  3. Services:
    • web: Django + Gunicorn (runs entrypoint.sh, exposes port 8000 inside the network).
    • nginx: Serves on http://localhost:6001, proxies to Gunicorn, and serves /static/ + /media/.
    • postgresql: pgvector-enabled Postgres (volume pg_data).
    • db: MySQL (only needed for legacy data import; docker-compose-test.yaml can seed it from pulsecrm.sql if provided).
    • memgraph: memgraph/memgraph-mage image with health check and Bolt (7687) / HTTP (7444) ports. Adjust .env.memgraph if you secure it.
  4. To expose database ports for local tooling, use docker-compose-test.yaml:
    docker compose -f docker-compose-test.yaml up --build
    This variant also mounts a SQL dump into MySQL for local experiments and maps PostgreSQL (5432), Memgraph (7688/7445), and MySQL ports to the host.
  5. Logs & management:
    docker compose logs -f web
    docker compose exec web python manage.py createsuperuser
    docker compose down -v  # remove volumes if you want a clean slate

Background services

  • Memgraph: Required for all pulsekg features. When running locally without Docker, start it via docker run -p 7687:7687 -p 7444:7444 memgraph/memgraph-mage. The app expects people/projects/skills nodes to exist; use the admin views (/pulsekg/create-person, /pulsekg/admin-assign-project) or MemgraphService helper methods to seed data.
  • Ollama: Install from https://ollama.com, start ollama serve, and pull the models you reference in env vars. Business-card scanning requires a multimodal model (llama3.2-vision), while skill extraction/chat use text models.
  • pgvector: Enable the extension in PostgreSQL (CREATE EXTENSION IF NOT EXISTS vector;) before running migrations if you plan to store vector data.

Operational workflows

  • CRM (app):
    • Navigate to /personen, /unternehmen, /branchen, /interaktion for CRUD.
    • Use the global search (/search/) which queries people, companies, and interactions simultaneously (app/views.py:48).
    • Export contacts via /personen/export or /unternehmen/<id>/export (CSV or Outlook format via app/utils.py:6).
    • User management under /user/ integrates with Memgraph: on creation/edit staff users can opt-in to automatically syncing a person node (app/views.py:292).
  • Business card workflow:
    • Upload images at /scan/. BusinessCardUploadView stores the file in MEDIA_ROOT/tmp/, calls extract_business_card_info (Ollama vision), and pre-fills both person + company forms.
    • Confirm/edit the extracted fields and submit; forms route to BusinessCardProcessView which persists both models.
  • Knowledge graph dashboards (pulsekg):
    • /pulsekg/dashboard shows the logged-in user’s skills/projects/repos/publications read from Memgraph.
    • /pulsekg/manage_* endpoints let users add/remove relationships by reusing MemgraphService.
    • Staff-only helpers create standalone nodes and assign projects.
    • /pulsekg/graph-data/ returns nodes/edges for visualisations, while /pulsekg/chat/ hosts the LangChain chat UI.
  • Skill generation:
    • /pulsekg/generate-skills/<type>/ (types: pub, project, repo, subproject) runs mine_skills which sends prompts (see pulsekg/prompt_library/*.txt) to Ollama. Confirmed skills are ingested into Memgraph through helper functions in memgraph_tools.py.
  • Chatbot:
    • Chat POST requests hit pulsekg.views.chat_view. The LangChain agent runs tool calls (run-cypher-query, get-vector-indices, vector-search) and validates every Cypher query so only read-only operations reach Memgraph (pulsekg/cypher_validator.py).

Testing & maintenance

  • Run the Django test suite (currently minimal) with:
    python manage.py test app pulsekg
  • Check migrations:
    python manage.py makemigrations
    python manage.py migrate
  • Collect static assets when deploying:
    python manage.py collectstatic --no-input

Troubleshooting

  • Cannot connect to Memgraph: Confirm MEMGRAPH_HOST/PORT and MEMGRAPH_URL line up. When using Docker, set them to the service name (memgraph) and ensure Bolt is exposed if you connect from the host.
  • Ollama errors: Make sure ollama serve is running and the requested model is pulled. Set OLLAMA_URL to http://host.docker.internal:11434 when the Django container must reach a host daemon.
  • Static files missing in Docker: Run docker compose exec web python manage.py collectstatic --no-input if the entrypoint was skipped, and ensure the static volume is mounted to Nginx.
  • MySQL migration issues: Use the DATABASES['second'] connection as a read-only handle to the legacy DB and follow the dedicated migration guide.
  • Business card extraction fails: Verify the uploaded image is reachable under MEDIA_ROOT/tmp/ and that the Ollama vision model supports images (update to the latest Ollama release if needed).

Next steps

  • Seed Memgraph with base data (people, skills, projects) so dashboards and chat have context.
  • Configure SMTP creds if you plan to send password resets (CustomPasswordResetView).

About

PulseHub is a platform that combines a classic CRM for relationship management with a Memgraph‑backed knowledge graph, LLM‑assisted data entry, and chat interfaces

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages