Skip to content

cherryaugusta/lawpulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LawPulse

AI-Powered Legal Document Auditor built with Django, Django REST Framework, Django Channels, React, Vite, Redis, PostgreSQL, and Docker Compose.

Overview

LawPulse is a LegalTech web application for uploading PDF contracts, extracting risky clauses, and reviewing them in a side-by-side interface. The backend parses uploaded PDF files, stores page-level text, extracts potentially risky clauses using a LangChain-backed service with a heuristic fallback, and streams live progress updates over WebSockets. The frontend provides a contract viewer, extracted text panel, clause list, and review form.

This repository follows a strict Windows-first execution path for local development at:

D:\Projects\LawPulse

Why This Project Matters

LawPulse is designed as both a portfolio-grade demonstration of full-stack engineering and a production-oriented reference for document-processing workflows. It showcases:

  • backend API design with Django REST Framework
  • real-time progress delivery with Django Channels and Redis
  • contract-aware frontend behavior with React and TypeScript
  • PDF processing and clause extraction workflows
  • Docker-based reproducibility across application services
  • observable request handling through custom latency headers
  • OpenAPI-first documentation through drf-spectacular

Key Engineering Signals

This repository demonstrates the following engineering themes:

  • API-first backend design with documented endpoints and a root health response
  • real-time system behavior through WebSocket status updates during audit execution
  • frontend-backend contract awareness through strict TypeScript usage and explicit base URL handling
  • operational reproducibility with Docker Compose for frontend, backend, PostgreSQL, and Redis
  • development discipline through clear setup instructions and validation checkpoints
  • portfolio readiness through screenshot evidence, admin coverage, Swagger visibility, and clean repository structure

Canonical Baseline

Use these versions as the project baseline:

  • Python 3.13.12
  • Django 5.2
  • Node.js 24 LTS
  • Redis 7
  • PostgreSQL 17

Important Runtime Corrections

This project includes three critical execution corrections:

  1. Python version is fixed to 3.13.12

    • Do not use Python 3.12 for this project.
  2. Frontend PDF loading uses absolute backend media URLs

    • The frontend converts Django media URLs into absolute backend URLs so react-pdf loads from:
    • http://127.0.0.1:8000/...
    • instead of incorrectly attempting:
    • http://127.0.0.1:5173/...
  3. A root health endpoint exists at /

    • http://127.0.0.1:8000/ loads successfully and returns a backend health response.

Stack

  • Django 5.2
  • Django REST Framework
  • drf-spectacular Swagger / OpenAPI
  • Django Channels
  • Redis
  • React
  • Vite
  • TypeScript (strict mode)
  • PostgreSQL
  • LangChain
  • react-pdf
  • Docker Compose

Features

  • Upload PDF contracts
  • Parse contract pages into stored page text
  • Extract risky clauses with LangChain-backed logic and heuristic fallback
  • Stream live processing updates via WebSockets
  • Side-by-side contract viewer and clause review interface
  • Review extracted clauses with a structured form
  • Custom request latency middleware with X-Request-Latency-Ms
  • Swagger / OpenAPI documentation
  • Django admin for jobs, pages, and clauses
  • Local Windows development workflow
  • Full Dockerized stack for frontend, backend, PostgreSQL, and Redis

Architecture Summary

Backend responsibilities

The Django backend is responsible for:

  • receiving uploaded PDF contracts
  • extracting and persisting page-level text
  • generating audit jobs and risky clause outputs
  • exposing REST endpoints for job creation and retrieval
  • broadcasting live progress messages over WebSockets
  • exposing admin and OpenAPI documentation surfaces
  • adding request timing metadata through custom middleware

Frontend responsibilities

The React frontend is responsible for:

  • uploading source PDF files
  • rendering contract pages via react-pdf
  • displaying extracted text and risky clause lists
  • presenting a review workflow for extracted clauses
  • tracking live progress from the WebSocket channel
  • handling corrected backend-origin media URLs for PDF rendering

Infrastructure responsibilities

Redis and PostgreSQL support the runtime model:

  • Redis supports Channels-backed real-time communication
  • PostgreSQL supports containerized relational persistence
  • Docker Compose orchestrates the full local stack

Project Structure

D:\Projects\LawPulse
├── .gitignore
├── README.md
├── LICENSE
├── docker-compose.yml
├── docs
│   └── screenshots
│       ├── backend-admin.png
│       ├── backend-response-headers.png
│       ├── backend-swagger-ui.png
│       ├── frontend-completed-view.png
│       ├── frontend-empty-state.png
│       ├── frontend-processing.png
│       └── frontend-selected-clause.png
├── backend
│   ├── .env
│   ├── .env.example
│   ├── Dockerfile
│   ├── manage.py
│   ├── requirements.txt
│   ├── auditor
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── consumers.py
│   │   ├── models.py
│   │   ├── routing.py
│   │   ├── serializers.py
│   │   ├── urls.py
│   │   ├── views.py
│   │   └── services
│   │       ├── __init__.py
│   │       ├── llm.py
│   │       └── pdf_audit.py
│   └── config
│       ├── asgi.py
│       ├── middleware.py
│       ├── settings.py
│       ├── urls.py
│       └── wsgi.py
└── frontend
    ├── .env
    ├── Dockerfile
    ├── package.json
    ├── tsconfig.app.json
    ├── vite.config.ts
    └── src
        ├── api.ts
        ├── App.css
        ├── App.tsx
        ├── index.css
        ├── main.tsx
        ├── types.ts
        └── components
            ├── PdfViewerPane.tsx
            ├── RiskForm.tsx
            └── RiskList.tsx

Screenshots

Frontend

Frontend empty state Frontend processing Frontend completed view Frontend selected clause

Backend

Backend Swagger UI Backend admin Backend response headers

Quick Start

For the fastest path, use either the local Windows workflow or the full Docker workflow.

Local Windows workflow

Backend terminal:

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py runserver

Frontend terminal:

cd D:\Projects\LawPulse\frontend
npm run dev

Redis terminal:

docker start lawpulse-redis-local

Full Docker workflow

cd D:\Projects\LawPulse
docker compose up --build

Stop the containerized stack

cd D:\Projects\LawPulse
docker compose down

If a terminal command hangs or needs to be interrupted, press:

CTRL + C

Preflight

Install the following on Windows before starting:

  • Python 3.13.12 (64-bit)
  • Node.js 24 LTS
  • Git for Windows
  • Docker Desktop
  • Visual Studio Code

Verify tools in PowerShell:

where.exe python
python --version
py -3.13 --version
py --list
node --version
npm --version
git --version
docker --version
docker compose version

Success means:

  • every command prints a version
  • py -3.13 --version works
  • Docker Desktop is running
  • Python 3.13.12 is visible and usable
  • Python 3.12 is not used for this project

Initial Folder Layout

Create the project folders:

cd D:\Projects
mkdir LawPulse
cd D:\Projects\LawPulse
mkdir backend
mkdir frontend
mkdir docs
mkdir docs\screenshots

Expected structure:

D:\Projects\LawPulse
├── backend
├── frontend
└── docs
    └── screenshots

Repository Setup

Initialize the repository:

cd D:\Projects\LawPulse
git init
git branch -M main

Create root .gitignore:

# OS
.DS_Store
Thumbs.db

# Python
backend/.venv/
backend/__pycache__/
backend/**/__pycache__/
backend/*.sqlite3
backend/db.sqlite3
backend/.pytest_cache/
backend/.mypy_cache/
backend/.ruff_cache/
backend/media/
backend/staticfiles/

# Python env files
backend/.env

# Node
frontend/node_modules/
frontend/dist/

# Frontend env
frontend/.env.local
frontend/.env.*.local

# Root / generic env
.env
.env.*

# VS Code
.vscode/

# Logs
*.log

# Screenshots temp exports
*.tmp.png

Backend Setup

1. Create and activate the virtual environment

cd D:\Projects\LawPulse\backend
py -3.13 -m venv .venv
.\.venv\Scripts\Activate.ps1

If PowerShell blocks activation:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
.\.venv\Scripts\Activate.ps1

Successful activation shows the prompt prefixed with:

(.venv)

To leave the virtual environment later, run:

deactivate

2. Create requirements.txt

Create D:\Projects\LawPulse\backend\requirements.txt:

Django>=5.2,<5.3
djangorestframework>=3.16,<3.17
drf-spectacular>=0.28,<0.29
channels>=4.3,<4.4
channels_redis>=4.3,<4.4
daphne>=4.2,<4.3
django-cors-headers>=4.7,<4.8
dj-database-url>=3.0,<3.1
psycopg[binary]>=3.2,<3.3
python-dotenv>=1.1,<1.2
pypdf>=5.4,<5.6
langchain>=0.3,<0.4
langchain-openai>=0.3,<0.4
pydantic>=2.11,<2.12

Install dependencies:

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt

Validate the environment:

python -m pip list
python -c "import django; print(django.get_version())"

3. Scaffold Django project and app

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
django-admin startproject config .
python manage.py startapp auditor
mkdir auditor\services
New-Item auditor\services\__init__.py -ItemType File

Frontend Setup

1. Scaffold Vite React TypeScript app

cd D:\Projects\LawPulse\frontend
npm create vite@latest . -- --template react-ts
npm install
npm install react-pdf pdfjs-dist react-hook-form zod @hookform/resolvers

Confirm strict TypeScript in frontend\tsconfig.app.json:

"strict": true

Optional validation:

cd D:\Projects\LawPulse\frontend
npm run build

Backend Environment Files

Create backend\.env.example:

DEBUG=True
SECRET_KEY=django-insecure-change-me
ALLOWED_HOSTS=127.0.0.1,localhost
CORS_ALLOWED_ORIGINS=http://127.0.0.1:5173,http://localhost:5173

DATABASE_URL=sqlite:///D:/Projects/LawPulse/backend/db.sqlite3
REDIS_URL=redis://127.0.0.1:6379/0

LLM_MODEL=gpt-4o-mini
OPENAI_API_KEY=
OPENAI_BASE_URL=

Create backend\.env:

DEBUG=True
SECRET_KEY=django-insecure-change-me-now
ALLOWED_HOSTS=127.0.0.1,localhost
CORS_ALLOWED_ORIGINS=http://127.0.0.1:5173,http://localhost:5173

DATABASE_URL=sqlite:///D:/Projects/LawPulse/backend/db.sqlite3
REDIS_URL=redis://127.0.0.1:6379/0

LLM_MODEL=gpt-4o-mini
OPENAI_API_KEY=
OPENAI_BASE_URL=

Backend Configuration

Key backend behavior in the final build:

  • config/settings.py loads environment variables from .env
  • the root endpoint / returns a JSON health response
  • media is served in development when DEBUG=True
  • Channels is configured to use Redis
  • custom request latency middleware adds X-Request-Latency-Ms
  • DRF schema generation is exposed through drf-spectacular

Root health response

When the backend is running, this endpoint should work:

http://127.0.0.1:8000/

Expected response shape:

{
  "name": "LawPulse API",
  "status": "ok",
  "docs": "/api/docs/",
  "schema": "/api/schema/",
  "admin": "/admin/"
}

Backend validation checks

Use these commands after wiring configuration:

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py check
python manage.py showmigrations

Backend Database and Admin

Run migrations and create an admin user:

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py makemigrations
python manage.py migrate
python manage.py check
python manage.py createsuperuser

Success means:

  • migrations complete without errors
  • python manage.py check reports no issues
  • superuser is created successfully

Local Redis for Windows Development

Start a local Redis helper container:

docker run --name lawpulse-redis-local -p 6379:6379 -d redis:7

If it already exists:

docker start lawpulse-redis-local

Verify:

docker ps

To stop the local Redis helper when needed:

docker stop lawpulse-redis-local

Run Backend Locally

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py runserver

These pages should load:

  • http://127.0.0.1:8000/
  • http://127.0.0.1:8000/api/docs/
  • http://127.0.0.1:8000/admin/

Frontend Configuration

Create frontend .env

Create frontend\.env:

VITE_API_BASE_URL=http://127.0.0.1:8000
VITE_WS_BASE_URL=ws://127.0.0.1:8000

Important frontend runtime note

The frontend must use the corrected src/api.ts that converts media URLs into absolute backend URLs before react-pdf receives them.

This is required so PDF files load from the backend server rather than the Vite dev server origin.

Frontend validation checks

Run these checks before normal development use:

cd D:\Projects\LawPulse\frontend
npm install
npm run build

A successful build is a strong signal that the TypeScript and Vite setup is healthy.

Run Frontend Locally

cd D:\Projects\LawPulse\frontend
npm install
npm run dev

Open:

http://127.0.0.1:5173

Verify the following:

  • upload a PDF contract
  • live status updates appear
  • the PDF renders
  • the risky clauses list populates
  • clicking a clause updates the form
  • extracted text highlighting updates
  • the PDF loads from the backend media URL correctly

API Endpoints

Swagger UI

http://127.0.0.1:8000/api/docs/

OpenAPI schema

http://127.0.0.1:8000/api/schema/

Root health

http://127.0.0.1:8000/

Audit jobs

  • GET /api/audit-jobs/
  • POST /api/audit-jobs/
  • GET /api/audit-jobs/{id}/

WebSocket updates

ws://127.0.0.1:8000/ws/audit-jobs/{id}/

Operational Notes

Health and observability

The repository includes observable signals useful for engineering review:

  • root health response at /
  • OpenAPI documentation at /api/docs/
  • schema visibility at /api/schema/
  • request timing header through X-Request-Latency-Ms

Development assumptions

This repository is intentionally opinionated:

  • Windows-first local pathing is the primary documented workflow
  • Python 3.13.12 is treated as mandatory
  • frontend and backend ports are fixed for consistency
  • Redis is required for the real-time flow
  • .env.example is the safe configuration reference
  • .env must remain local and uncommitted

Scope note

This repository is positioned as a full-stack engineering showcase and local reproducibility reference. It is not presented as a finished legal-risk classifier or legal advice system.

Docker

Backend Dockerfile

Create backend\Dockerfile:

FROM python:3.13-slim

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /app

RUN apt-get update && apt-get install -y build-essential libpq-dev && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["sh", "-c", "python manage.py migrate && daphne -b 0.0.0.0 -p 8000 config.asgi:application"]

Frontend Dockerfile

Create frontend\Dockerfile:

FROM node:24-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 5173

CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]

Docker Compose

Create docker-compose.yml in the project root:

services:
  db:
    image: postgres:17
    container_name: lawpulse-db
    environment:
      POSTGRES_DB: lawpulse
      POSTGRES_USER: lawpulse
      POSTGRES_PASSWORD: lawpulse
    ports:
      - "5432:5432"
    volumes:
      - lawpulse_postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7
    container_name: lawpulse-redis
    ports:
      - "6379:6379"

  backend:
    build:
      context: ./backend
    container_name: lawpulse-backend
    command: sh -c "python manage.py migrate && daphne -b 0.0.0.0 -p 8000 config.asgi:application"
    environment:
      DEBUG: "True"
      SECRET_KEY: docker-secret-key-change-me
      ALLOWED_HOSTS: 127.0.0.1,localhost,backend
      CORS_ALLOWED_ORIGINS: http://127.0.0.1:5173,http://localhost:5173
      DATABASE_URL: postgres://lawpulse:lawpulse@db:5432/lawpulse
      REDIS_URL: redis://redis:6379/0
      LLM_MODEL: gpt-4o-mini
      OPENAI_API_KEY: ""
      OPENAI_BASE_URL: ""
    volumes:
      - ./backend:/app
    ports:
      - "8000:8000"
    depends_on:
      - db
      - redis

  frontend:
    build:
      context: ./frontend
    container_name: lawpulse-frontend
    environment:
      VITE_API_BASE_URL: http://127.0.0.1:8000
      VITE_WS_BASE_URL: ws://127.0.0.1:8000
    volumes:
      - ./frontend:/app
      - /app/node_modules
    ports:
      - "5173:5173"
    depends_on:
      - backend

volumes:
  lawpulse_postgres_data:

Run the full containerized stack

Stop local processes and the local Redis helper first:

docker stop lawpulse-redis-local

Then run:

cd D:\Projects\LawPulse
docker compose up --build

Success means:

  • frontend runs on http://127.0.0.1:5173
  • backend runs on http://127.0.0.1:8000
  • Swagger runs on http://127.0.0.1:8000/api/docs/

Screenshot Evidence

Save the following files into:

D:\Projects\LawPulse\docs\screenshots

Backend screenshots

  1. backend-swagger-ui.png

    • page: http://127.0.0.1:8000/api/docs/
    • include visible Swagger title
    • include visible GET /api/audit-jobs/
    • include visible POST /api/audit-jobs/
  2. backend-admin.png

    • page: http://127.0.0.1:8000/admin/
    • log in
    • include visible Audit Jobs, Audit Pages, Risk Clauses
  3. backend-response-headers.png

    • open browser developer tools
    • make a backend request
    • capture response headers
    • include X-Request-Latency-Ms

Frontend screenshots

  1. frontend-empty-state.png

    • app before upload
  2. frontend-processing.png

    • while PDF is processing
    • include visible progress or status
  3. frontend-completed-view.png

    • after processing
    • include left PDF pane
    • include extracted text
    • include risk list
    • include form on the right
  4. frontend-selected-clause.png

    • after clicking a clause
    • include selected list item
    • include updated form
    • include extracted text highlight

Stage screenshots:

cd D:\Projects\LawPulse
git add docs\screenshots
git status

Suggested Repository Metadata

For a stronger GitHub presentation, configure the repository with:

  • repository name: lawpulse
  • description: AI-powered legal document auditor with Django, DRF, Channels, React, Redis, PostgreSQL, and Docker Compose
  • topics: django, djangorestframework, django-channels, react, typescript, vite, redis, postgresql, docker-compose, openapi, legaltech, pdf-processing, websockets

Day-to-Day Command Map

Backend local workflow

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Frontend local workflow

cd D:\Projects\LawPulse\frontend
npm install
npm run dev

Redis local workflow

docker start lawpulse-redis-local

Full Docker workflow

cd D:\Projects\LawPulse
docker compose up --build

Stop Docker workflow

cd D:\Projects\LawPulse
docker compose down

Standard Git workflow

cd D:\Projects\LawPulse
git status
git add .
git commit -m "feat: describe one focused change"
git push

Acceptance Checklist

Backend acceptance

Confirm all are true:

  • http://127.0.0.1:8000/api/docs/ loads
  • POST /api/audit-jobs/ exists
  • GET /api/audit-jobs/ works
  • GET /api/audit-jobs/{id}/ returns nested pages and clauses
  • X-Request-Latency-Ms exists in response headers

WebSocket acceptance

Confirm all are true:

  • browser connects to ws://127.0.0.1:8000/ws/audit-jobs/{id}/
  • progress messages arrive during processing

Frontend acceptance

Confirm all are true:

  • Vite app runs
  • PDF uploads
  • risky clauses populate
  • selecting a clause updates the form
  • selected text highlights in extracted text panel
  • PDF renders from backend media URL correctly

Docker acceptance

Confirm all are true:

  • docker compose up --build starts db, redis, backend, and frontend
  • frontend communicates with backend successfully

Git / GitHub acceptance

Confirm all are true:

  • repository is on GitHub
  • no secrets are committed
  • screenshots render in the README

One-Command Launch Summary

Local Windows development

Backend terminal:

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py runserver

Frontend terminal:

cd D:\Projects\LawPulse\frontend
npm run dev

Redis terminal:

docker start lawpulse-redis-local

Full containerized stack

cd D:\Projects\LawPulse
docker compose up --build

Final Lock-In Notes

  • Use Python 3.13.12

  • Use Django 5.2

  • Use Node.js 24 LTS

  • Use Redis 7

  • Use PostgreSQL 17

  • Keep local development ports fixed as:

    • backend: 8000
    • frontend: 5173
    • Redis: 6379
  • Keep the corrected frontend\src\api.ts absolute URL handling for media files

  • Keep the root endpoint / in the backend so health verification works cleanly

Local Development Quick Reference

Backend

cd D:\Projects\LawPulse\backend
.\.venv\Scripts\Activate.ps1
python manage.py migrate
python manage.py runserver

Frontend

cd D:\Projects\LawPulse\frontend
npm install
npm run dev

Redis

docker start lawpulse-redis-local

Full stack

cd D:\Projects\LawPulse
docker compose up --build

Notes on Secrets

Do not commit:

  • backend\.env
  • any real API keys
  • any personal credentials

The repository should include backend\.env.example as the safe template and keep backend\.env ignored by Git.

Summary

LawPulse is the complete single-path build for an AI-powered legal document auditor with:

  • Django backend APIs
  • WebSocket progress updates
  • PDF upload and parsing
  • clause extraction and review
  • React side-by-side viewer UI
  • Redis-backed Channels support
  • PostgreSQL-ready Docker deployment
  • documented Windows-first local workflow

License

This project is licensed under the MIT License.

Copyright (c) 2026 Cherry Augusta

See the LICENSE file for full details.

About

AI-powered legal contract auditor with Django, React, WebSockets, and LangChain that extracts risky clauses from uploaded PDFs.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors