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): ```bash # 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) 2) Frontend (dev) ```bash 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): ```bash cd frontend npm run electron:build ``` - Built artifacts are placed into `frontend/dist/` and this project’s `releases/` directory after packaging. - Verified release build (runs persistence check before packaging): ```bash npm run build:verified ``` - Verified release build with backend restart check: ```bash npm run build:verified:restart ``` - One-command verified release pipeline (persistence test + frontend build + dist sync + Electron packaging): ```bash npm run release:verified ``` - Same as above, but also verifies persistence across backend restart: ```bash 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): ```bash # 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 I’ll scaffold it. Persistence self-test Run this before release to verify that created records are persisted and can be read back: ```bash npm run test:persistence ``` If your backend is running under Docker Compose and you also want to verify persistence across a backend restart: ```bash 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: ```bash 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)