The Problem

Collaborative document editing usually means signing up for a heavyweight SaaS product or wiring together half a dozen services. This repo is a self-contained, Dockerized alternative: a lightweight editor with import, sharing, and attachments that runs entirely on your own infrastructure.

What This Does

DocEngine is a full-stack document editor. The backend (backend/app/) is a FastAPI service with Postgres persistence, Alembic migrations, JWT auth, and role-based permissions. The frontend (frontend/src/) is a React 18 + TypeScript SPA using TipTap for rich-text editing. Documents autosave 800ms after typing stops, with conflict detection.

Import supports .txt, .md, and .docx (images/tables dropped, stated up front). Sharing grants viewer or editor roles by email. The repo includes a seed script (backend/app/seed.py) that creates four demo users with pre-populated documents.

How It Is Wired

Execution starts at backend/app/main.py for the API and frontend/src/main.tsx for the SPA. The frontend routes through frontend/src/api/client.ts (8 modules depend on it) to REST endpoints handled by routers in backend/app/routers/. Services in backend/app/services/ contain business logic — document_service.py and permission_service.py are the core. Repositories (backend/app/repositories/) abstract SQLAlchemy queries.

The module graph shows frontend/src/types/index.ts as the hub: 14 modules import it, so changes there ripple widely. frontend/src/pages/DocumentEditorPage.tsx has the highest cognitive load (10 imports, instability 0.91) — it's where editor state, autosave, and sharing converge. The graph is clean: 94 modules, 76 edges, zero circular dependencies.

The system touches Postgres (documents, users, shares, versions, attachments), the filesystem (storage/uploads/ for attachments), and the network (JWT auth, import file uploads).

How To Use It

git clone https://github.com/moses-y/docengine
cd docengine
cp .env.example .env
docker compose up --build

Open http://localhost:5173. Login with alice@ajaia.test / demo1234. The API container runs migrations and seeding automatically on startup.

Local dev without Docker: backend uses uvicorn app.main:app --reload from backend/; frontend uses npm run dev from frontend/. Tests: pytest -q in backend/ (integration tests self-skip without Docker), npm test in frontend/.

Real-World Use

A small team or internal tool needing document editing without external SaaS dependencies. The seeded users and permission matrix (404 for strangers, 403 for under-privileged viewers — tested exhaustively in tests/test_permissions.py) make it suitable as a starting point for a production internal knowledge base or report-generation tool.

Code Health & Issues

Static analysis found 9 findings (1 high, 8 medium):

  • High — deep nesting in backend/app/seed.py and backend/tests/test_sanitize.py (indentation depth 8). Flatten with guard clauses.
  • Medium — hub module frontend/src/types/index.ts (14 dependents). Keep stable.
  • Medium — duplicated code across backend/app/database.py, backend/app/models/ files. Extract shared helpers.
  • Medium — broad exception handling in database.py, security.py, and integration conftest.py. Catch specific exceptions.

SDLC gaps: no CI workflow, no LICENSE file (all rights reserved by default), and the backend Dockerfile runs as root with an unpinned python:3.12-slim base image. Dependencies are stale — 17 of 31 packages are multiple major versions behind (jsdom is 5 majors behind).

The Bottom Line

Solid, well-structured full-stack project with good test coverage and clean module boundaries. The gaps are operational — CI, licensing, container hardening — not architectural. Worth using as a reference for FastAPI + React patterns, or as a starting point for a self-hosted document tool if you add the missing SDLC plumbing.