70 lines
3.2 KiB
Markdown
70 lines
3.2 KiB
Markdown
|
|
# FORGE
|
||
|
|
|
||
|
|
A ServiceNow ticket dashboard for the *Marketing Web Presence* L3 queues —
|
||
|
|
RITM/SCTASK requests pulled out of ServiceNow and shown as an operational board
|
||
|
|
plus closed-ticket analytics. Ported from the **Let it Snow** Chrome extension
|
||
|
|
into a full-stack web app, built on the shape of the *Husky repo list* template.
|
||
|
|
|
||
|
|
```
|
||
|
|
┌──────────────┐ Bearer token ┌───────────────┐ Postgres
|
||
|
|
│ Chrome ext │ ──── POST /api/sync ─▶│ FORGE server │ ────────────▶ forge DB
|
||
|
|
│ (Snow Sync) │ │ Express + TS │
|
||
|
|
└──────────────┘ └───────┬───────┘
|
||
|
|
▲ │ serves
|
||
|
|
reads ServiceNow ▼
|
||
|
|
Table API in-page ┌───────────────────────────┐
|
||
|
|
│ React client (Vite + TS) │
|
||
|
|
│ Board · Closed · Stats │
|
||
|
|
└───────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
## Stack
|
||
|
|
|
||
|
|
- **client/** — React 18 + Vite + TypeScript, SCSS modules, react-router. Three
|
||
|
|
views: **Active board** (filters, search, ticket detail + activity timeline),
|
||
|
|
**Closed** (cost / time-to-first-reply analytics), **Statistics** (distribution).
|
||
|
|
- **server** (`index.ts` + `server/`) — Express + TypeScript on Postgres. Schema
|
||
|
|
self-bootstraps in `initDB()` and seeds the bundled ticket archives on first
|
||
|
|
boot. REST: `GET /api/tickets`, `/api/tickets/:number`, `/api/stats`, `/healthz`,
|
||
|
|
and a token-authed `POST /api/sync` ingest.
|
||
|
|
- **extension/** — a Manifest V3 Chrome extension ("FORGE Snow Sync") that reads
|
||
|
|
active RITM tickets from the ServiceNow Table API and pushes them to the server
|
||
|
|
with an API token, exactly like the Husky sync extension.
|
||
|
|
|
||
|
|
## Quick start (local)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. a Postgres named `forge` (compose brings one up, or use your own)
|
||
|
|
docker compose up -d db # or point DATABASE_URL at any Postgres
|
||
|
|
|
||
|
|
cp .env.example .env # DATABASE_URL defaults to the compose db
|
||
|
|
|
||
|
|
# 2. install + run both server and client with live reload
|
||
|
|
npm install
|
||
|
|
npm run dev # server :3000, client :5173 (proxies /api)
|
||
|
|
```
|
||
|
|
|
||
|
|
Open http://localhost:5173 and sign in with the `AUTH_USER` / `AUTH_PASS` you
|
||
|
|
set in `.env` (the read UI is auth-gated; see [docs/SETUP.md](docs/SETUP.md#3-log-in-read-api-auth)).
|
||
|
|
On first boot the server seeds the ticket archives
|
||
|
|
in `server/data/*.json` (**100 active + 866 closed** after de-duping the ~99
|
||
|
|
tickets that appear in both), so the board is populated before any real sync
|
||
|
|
runs. Those archives are generated from a Let it Snow storage dump — see
|
||
|
|
[docs/SETUP.md](docs/SETUP.md#seed-data) to regenerate them.
|
||
|
|
|
||
|
|
## Production
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker compose up -d --build # app on host :3099, bundled Postgres
|
||
|
|
```
|
||
|
|
|
||
|
|
Behind the Synology reverse proxy this is what **forge.mycloud.dp.ua** maps to.
|
||
|
|
|
||
|
|
See **[docs/SETUP.md](docs/SETUP.md)** for the sync token + Chrome extension setup.
|
||
|
|
|
||
|
|
## Tests
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm test # client (vitest) + server (vitest)
|
||
|
|
```
|