# Version history

**Location:** repository root (`Version History.md`), one directory above `Product/`. The running app serves this file at **`/whats-new`** (Markdown).

Maintain this file **incrementally**: add a new section at the **top** for each major release (e.g. V2), with date and a concise list of user-visible changes and notable technical updates. Older releases stay below.

---

## V2 — 2026-05-09

The **VeloSync Product** is now publicly hosted at **https://velosync.net/Product**, reachable from the marketing site's hero **Explore Live Dashboard** button. Path-prefix friendly Express, public read-only viewer, jira-md-export cron parked.

### Highlights

- **Live demo hosting:** Product runs on the same Ubuntu box as the marketing site. Single Nginx server block routes `/Product/*` → `velosync-product` PM2 app (`:3001`), everything else → `velosync-website` (`:3002`). Reuses the same Let's Encrypt cert; no Certbot re-run needed when Product is added.
- **Marketing button live:** Hero CTA renamed **"Explore Demo Dashboard" → "Explore Live Dashboard"**, with copy now noting `demo / demo` credentials. `NEXT_PUBLIC_DEMO_URL=https://velosync.net/Product` in [`WebSite/deploy/ubuntu/pm2-velosync-website.config.cjs`](WebSite/deploy/ubuntu/pm2-velosync-website.config.cjs) and the production env example.
- **`DEMO_MODE=1` posture:** New env var. Auto-bootstraps a `demo` / `demo` viewer in `rbac.json`, advertises it on `/login` with a green callout, and pre-fills the form. Idempotent — safe to leave on across restarts.
- **Path-prefix support (`BASE_PATH=/Product`):** New [`Product/lib/base-path.js`](Product/lib/base-path.js) provides:
  - **`stripBasePath` middleware** — rewrites `/Product/api/foo` → `/api/foo` at the front of the chain so existing routes stay written for the root.
  - **`<base href>` + `window.url(p)` injection** in every served HTML so relative anchors and `fetch(window.url('/api/...'))` calls resolve correctly.
  - **`redirect(res, p)` helper** prepends BASE_PATH to local redirects (server-side OAuth + auth gates).
  - **Cookie path = BASE_PATH** so sessions don't bleed onto the marketing site at `/`.
- **OAuth-aware:** OAuth `REDIRECT_URI` / `POST_LOGOUT_REDIRECT_URI` defaults now include BASE_PATH. Branding API (`/api/branding`) returns BASE_PATH-prefixed URLs so the client can drop them straight into `img.src`.
- **Absolute-path sweep:** ~50 absolute `<a href="/...">` / `<img src="/...">` / `<script src="/...">` references across `index.html`, `login.html`, `project-detail.html`, `admin/settings.html`, `Explore/SearchJira.html`, `ResourceInsights/ResourceInsights.html`, `chatbot/ui/standalone.html` converted to relative form. `~24` `fetch('/...')` and `window.location='/...'` call sites switched to `window.url(...)`.
- **No more jira-md-export cron in production:** [`Product/ecosystem.config.cjs`](Product/ecosystem.config.cjs) and the new [`Product/deploy/ubuntu/pm2-velosync-product.config.cjs`](Product/deploy/ubuntu/pm2-velosync-product.config.cjs) ship with a single `apps[]` entry. Internal installs that want the cron back can register it on top by hand.
- **New deploy bundle:** [`Product/deploy/ubuntu/`](Product/deploy/ubuntu) — env example, PM2 manifest, README. Mirrors the existing `WebSite/deploy/ubuntu/` pattern.
- **Updated Nginx config:** [`WebSite/deploy/ubuntu/nginx-velosync.conf`](WebSite/deploy/ubuntu/nginx-velosync.conf) gains a `location /Product/` block (with `client_max_body_size 25M` for admin uploads) ahead of the existing `location /`.

### Smoke-test checklist (local, BASE_PATH path-prefix)

```bash
# Local dev with the new prefix (simulate prod)
cd Product
BASE_PATH=/Product PORT=3001 DEMO_MODE=1 PUBLIC_BASE_URL=http://localhost:3001 npm start

# In another terminal
curl -sI http://localhost:3001/Product/login        # 200
curl -sI http://localhost:3001/Product/api/branding # 200
curl -sI http://localhost:3001/login                # 404 (correctly NOT mounted at root)
```

Browser at `http://localhost:3001/Product/`:

1. Auto-redirects to `/Product/login`.
2. Green "Live demo" callout visible; form pre-filled `demo / demo`.
3. Sign in → dashboard renders.
4. Project tile → `/Product/project-detail.html?...` opens.
5. Admin Tools → Search Jira → `/Product/Explore/SearchJira.html` opens.
6. Logout → `/Product/login`.

### Local dev (legacy, BASE_PATH empty)

`BASE_PATH=""` (or unset) keeps everything mounted at root with zero behavior change for existing dev workflows. The base-path injection then adds `<base href="/">` (no-op for absolute URLs).

---

## V1 — 2026-04-19

First production-aligned release of the **VeloSync Product** (Node dashboard + Jira export pipeline + admin console).

### Highlights

- **Authentication:** Microsoft Entra ID (Azure AD) with PKCE; optional **local username/password** (`AUTH_MODE`, `ALLOW_LOCAL_LOGIN`); bootstrap `admin` / `admin` when `rbac.json` is missing and local sign-in is allowed; session-based access to the app and `/api/*`.
- **RBAC:** `rbac.json` — fuzzy-matched **Microsoft display names** → admin; **local users** with bcrypt hashes, roles, CRUD via Admin API; Manage users UI explains Microsoft vs local modes and hides irrelevant blocks.
- **Admin — Settings:** Branding (logo, favicon, site title, tagline), Jira setup (writes `jira-md-export/.env`), optional connectors toggles + credentials (`data/connectors.json`), HTTPS/SSL upload, platform env, **Projects** editor (`projects.json`) with compact rows and expandable details (stages, sprint filters, TestRail IDs, WC field, full overwrite), **Data Sync Job** (PM2/cron hints, restart hooks), local user management, theme toggle, onboarding banner, reveal/revert env backup flows.
- **Environment:** Unified **Product `.env`** merged with **`jira-md-export/.env`** (export path wins on conflict); portable paths relative to Product root where applicable.
- **Integrations UI:** Static icons under `/integrations` (Jira, Microsoft, Confluence, GitHub, Copilot, Cursor, TestRail, OpenRouter).
- **OpenRouter:** Server-side proxy for LLM calls; connector test support; optional TLS relaxation for corporate proxies (`ALLOW_INSECURE_TLS`).
- **Export pipeline:** `jira-md-export` driven by `projects.json`, connectors config, and Jira credentials; admin actions can signal dependency changes for scheduled jobs.

### Known constraints (V1)

- Automated test suite is minimal; smoke-test auth, admin save paths, and one export cycle before tagging releases.
- **Azure-only** deployments still need a valid **`rbac.json`** with `roles.admin` populated, or SSO users remain viewers until names are added.
- Tailwind **CDN** on admin pages: classes applied only from JavaScript may need companion CSS (nav chip text is handled in dashboard CSS).

### Architecture (V1)

```mermaid
flowchart TB
  subgraph clients [Clients]
    Browser[Browser]
  end

  subgraph product [Product Node server]
    Express[Express + session]
    Static[Static: index, Explore, assets]
    AdminUI[Admin HTML/JS]
    AuthN[Auth: Azure MSAL / local login]
    RBAC[RBAC: rbac.json]
    AdminAPI[Admin APIs: lib/admin-routes.js]
    Branding[Branding: lib/branding.js]
    Connectors[Connectors: lib/connectors-config.js]
    DataSync[Data sync job: lib/data-sync-job.js]
    OpenRouter[OpenRouter proxy]
  end

  subgraph external [External services]
    Entra[Microsoft Entra ID]
    Jira[Atlassian Jira Cloud]
    OR[OpenRouter]
    Opt[Optional: GitHub, TestRail, Confluence, Cursor, etc.]
  end

  subgraph pipeline [Export pipeline]
    JME[jira-md-export]
    PM2[PM2 / cron optional]
  end

  subgraph disk [On disk]
    Env[jira-md-export/.env + Product .env]
    Proj[projects.json]
    Conn[data/connectors.json]
    Rbac[rbac.json]
  end

  Browser --> Express
  Express --> Static
  Express --> AdminUI
  Express --> AuthN
  AuthN --> Entra
  AuthN --> RBAC
  RBAC --> Rbac
  Express --> AdminAPI
  AdminAPI --> Env
  AdminAPI --> Proj
  AdminAPI --> Conn
  AdminAPI --> Branding
  AdminAPI --> DataSync
  Express --> OpenRouter
  OpenRouter --> OR
  AdminAPI --> JME
  JME --> Env
  JME --> Proj
  JME --> Conn
  JME --> Jira
  JME --> Opt
  PM2 --> JME
  DataSync --> PM2
```

**Data flow (simplified):** The browser talks to **Express** for pages, session auth, branding, and JSON APIs. **Admin** mutates env, `projects.json`, `connectors.json`, `rbac.json`, SSL files, and branding uploads. **jira-md-export** reads the same env/projects/connectors (and Jira tokens) to pull data; **PM2** (if used) runs that job on a schedule and can be restarted when config changes.

---

<!-- Future releases: add new ## Vx block above this line -->
