Project Hub — Desktop app + backend

This repository contains a React+Vite frontend packaged as an Electron desktop app, and a small Node/Express backend using lowdb for JSON persistence. Development builds and packaged macOS installer artifacts are stored in releases/.

Quick links

  • Releases: releases/ (DMG, ZIP, packaged .app)
  • Frontend: frontend/
  • Backend: backend/

Development

  1. Backend (fast, using Docker):
# from project root
cd backend
# install deps (if needed)
npm install
# build image and run (example)
docker build -t project-manager-backend:latest .
docker run -d --name project-manager-api -p 4000:4000 \
	-v project_manager_data:/app/data \
	-e NODE_ENV=production -e PORT=4000 -e HOST=0.0.0.0 \
	-e CORS_ORIGIN="http://localhost:5173" -e WRITE_API_KEY="dev-key" \
	--restart unless-stopped project-manager-backend:latest

Or use docker compose up -d if you prefer Compose.

Endpoints

  • Health: GET /health
  • API root: GET /api/projects, GET /api/members, etc.

Config / env vars

  • PORT (default 4000)
  • HOST (default 0.0.0.0)
  • DB_FILE (optional path to db file)
  • CORS_ORIGIN (comma-separated allowed origins)
  • WRITE_API_KEY (if set, write operations require x-api-key header)
  1. Frontend (dev)
cd frontend
npm install
npm run electron:dev   # starts Vite and launches Electron

Runtime API URL

The app now supports runtime API endpoint configuration:

  • In the desktop UI, click Server in the top-right and set the API base URL (example: http://localhost:4000/api).
  • The value is persisted in Electron app storage and used on next requests without rebuilding.
  • If no runtime value is set, the app falls back to VITE_API_URL, then http://localhost:4000/api.

Write authentication (WRITE_API_KEY)

  • If backend sets WRITE_API_KEY, all POST/PUT/DELETE endpoints require x-api-key.
  • Frontend and Electron now propagate this key automatically when provided via:
    • WRITE_API_KEY (preferred for Electron runtime)
    • VITE_WRITE_API_KEY (frontend build-time fallback)
  • GET endpoints remain readable without API key unless you add additional auth middleware.

Build & releases

  • Build renderer and package Electron (mac example):
cd frontend
npm run electron:build
  • Built artifacts are placed into frontend/dist/ and this projects releases/ directory after packaging.

  • Verified release build (runs persistence check before packaging):

npm run build:verified
  • Verified release build with backend restart check:
npm run build:verified:restart
  • One-command verified release pipeline (persistence test + frontend build + dist sync + Electron packaging):
npm run release:verified
  • Same as above, but also verifies persistence across backend restart:
npm run release:verified:restart

Unsigned macOS Gatekeeper note

These builds are currently unsigned. macOS Gatekeeper may prevent opening the app. Users can bypass with one of the following (instruct users to accept the risk):

# Open by right-clicking the app and choosing "Open", or run:
xattr -r -d com.apple.quarantine "/Applications/Project Hub.app"
# or for a packaged app in releases:
xattr -r -d com.apple.quarantine "releases/Project Hub.app"

CI / Distribution suggestions

  • Add a GitHub Actions workflow to build and upload unsigned artifacts to GitHub Releases (I can add this).
  • To avoid Gatekeeper prompts for wide distribution, sign and notarize the app (requires Apple Developer account and credentials).

Security & production notes

  • lowdb (JSON file) is fine short-term for small teams. For production/many users, migrate to a proper DB (Postgres, managed DB).
  • Use WRITE_API_KEY or user accounts to protect write operations; always run behind TLS (reverse proxy like nginx/Traefik) for public hosting.

Need help?

I can add a GitHub Actions workflow to build/upload unsigned releases, or add signing/notarization steps if you acquire an Apple Developer account. Tell me which and Ill scaffold it.

Persistence self-test

Run this before release to verify that created records are persisted and can be read back:

npm run test:persistence

If your backend is running under Docker Compose and you also want to verify persistence across a backend restart:

npm run test:persistence:restart

Optional env vars:

  • API_BASE (default http://localhost:4000/api)
  • WRITE_API_KEY (needed if backend write endpoints are protected)

Wiring smoke test

Run a focused integration check for task/member/invite route wiring:

npm run test:wiring

Optional env vars for this test:

  • API_BASE (default http://localhost:4000/api)
  • WRITE_API_KEY (required if write endpoints are protected)
Description
Project Hub - Project management app
Readme 319 KiB
Languages
JavaScript 82.7%
HTML 16.1%
CSS 0.7%
Dockerfile 0.5%