# Setup (Development) ## Prerequisites - Node.js 20+ - PostgreSQL 14+ (local or remote) - npm 10+ ## 1. Clone & configure ```bash git clone https://git.sysdaemon.xyz/x3/openStack.git cd openStack cp .env.example .env ``` Edit `.env`: | Variable | Purpose | Example | |----------|---------|---------| | `DATABASE_URL` | Backend Postgres connection | `postgres://openstack:openstackpw@localhost:5432/openstack` | | `JWT_SECRET` | Signing key for auth tokens (min 32 random chars) | `openssl rand -hex 32` | | `JWT_EXPIRES_IN` | Token lifetime | `7d` | | `CORS_ORIGIN` | Allowed frontend origin(s), comma-separated | `http://localhost:5173` | | `VITE_API_URL` | Frontend -> backend base URL | `http://localhost:3000/api` | | `VITE_SOCKET_URL` | Frontend -> Socket.IO URL | `http://localhost:3000` | | `PORT` | Backend listen port | `3000` | ## 2. Database ```bash createdb openstack psql "$DATABASE_URL" < backend/src/db/schema.sql # or: cd backend && npm install && npm run migrate ``` Verify: ```bash psql "$DATABASE_URL" -c "SELECT * FROM users LIMIT 1;" ``` ## 3. Backend ```bash cd backend npm install npm run dev # watch mode on http://localhost:3000 curl http://localhost:3000/api/health # -> {"ok":true,"db":"up"} ``` ## 4. Frontend ```bash cd frontend npm install npm run dev # http://localhost:5173 ``` Open the frontend, **Register** the first user, create a workspace, invite teammates by email (they must register with the same email first). ## Troubleshooting - `DATABASE_URL is not set` — you forgot `.env` or didn't export it. Backend reads `backend/.env` too if you copy `.env` there, otherwise set env in shell. - `db: down` on `/api/health` — Postgres unreachable; check `DATABASE_URL`, firewall, `pg_isready`. - CORS errors — `CORS_ORIGIN` must exactly match the frontend origin (scheme+host+port). - Socket.IO `Invalid token` — log out/in again; token may have expired. - `relation "users" does not exist` — schema not applied; run migrate step. - Postgres.app on macOS hangs on `psql -h localhost` — use the socket (`psql -h /tmp`) or set a password and use TCP; see HOSTING notes.