- Add dedicated REST endpoints for feature CRUD (GET/POST/PUT/DELETE /api/projects/:id/features) - Add normalizeFeatureEntry() with updatedAt, updatedBy, shippedAt lifecycle - Auto-set shippedAt when status transitions to 'shipped' - Frontend api.js: getFeatures, createFeature, updateFeature, deleteFeature methods - App.jsx: optimistic CRUD handlers using dedicated feature endpoints - Project list: feature-status filter dropdown + 5-way sort (feature activity, feature status, project status, due date, name) - Project cards: feature log preview (latest entry + in-flight count) - FeaturesTab: filter by status, sort by updatedAt desc - FeatureRow: show updatedAt, updatedBy, shippedAt metadata; updatedBy edit field
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
- 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 requirex-api-keyheader)
- 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, thenhttp://localhost:4000/api.
Write authentication (WRITE_API_KEY)
- If backend sets
WRITE_API_KEY, all POST/PUT/DELETE endpoints requirex-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 project’sreleases/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_KEYor 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 I’ll 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(defaulthttp://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(defaulthttp://localhost:4000/api)WRITE_API_KEY(required if write endpoints are protected)