Files
TicketingSystem/README.md
josh 429a530fc8
All checks were successful
Build & Push / Build Server (push) Successful in 1m35s
Build & Push / Build Client (push) Successful in 40s
Use prisma db push instead of migrate deploy on startup
Eliminates the need to generate and commit migration files locally
before first deploy. Schema is synced directly from schema.prisma
on container start.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:59:55 -04:00

204 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TicketingSystem
Internal ticketing system with CTI-based routing, severity levels, and n8n/automation integration.
## Features
- **CTI routing** — tickets are categorised by Category → Type → Item, reroutable at any time
- **Severity 15** — SEV 1 (critical) through SEV 5 (minimal); dashboard sorts by severity
- **Status lifecycle** — Open → In Progress → Resolved → Closed; resolved tickets auto-close after 14 days
- **Comments** — threaded comments per ticket with author attribution
- **Roles** — Admin, Agent, Service (API key auth for automation accounts)
- **Admin panel** — manage users and the full CTI hierarchy via UI
- **n8n ready** — service accounts authenticate via `X-Api-Key` header
---
## Production Deployment
### Prerequisites
- Docker + Docker Compose
- Nginx Proxy Manager pointed at the host port (default `3080`)
- Access to your Gitea container registry
### 1. Copy files to your server
```bash
scp docker-compose.yml .env.example user@your-server:~/ticketing/
```
### 2. Configure environment
```bash
cd ~/ticketing
cp .env.example .env
```
Edit `.env`:
```env
REGISTRY=gitea.thewrightserver.net
TAG=latest
POSTGRES_PASSWORD=<strong password>
JWT_SECRET=<output of: openssl rand -hex 64>
CLIENT_URL=http://tickets.thewrightserver.net
PORT=3080
```
Point NPM at `http://<host-ip>:3080` for the proxy host.
### 3. Deploy
```bash
docker compose pull
docker compose up -d
```
### 5. Seed (first deploy only)
```bash
docker compose exec server npm run db:seed
```
This creates:
- `admin` user (password: `admin123`) — **change this immediately**
- `goddard` service account — API key is printed to the console; copy it now
---
## Development
### Requirements
- Node.js 22+
- PostgreSQL (local or via Docker)
### Start Postgres
```bash
docker run -d \
--name ticketing-pg \
-e POSTGRES_DB=ticketing \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16-alpine
```
### Server
```bash
cd server
cp .env.example .env # set DATABASE_URL and JWT_SECRET
npm install
npm run db:migrate # creates tables + migration files
npm run db:seed # seeds admin + Goddard + sample CTI
npm run dev # http://localhost:3000
```
### Client
```bash
cd client
npm install
npm run dev # http://localhost:5173 (proxies /api to :3000)
```
---
## n8n Integration (Goddard)
The `goddard` service account authenticates via API key — no login flow needed.
**Create a ticket from n8n:**
```
POST https://tickets.thewrightserver.net/api/tickets
X-Api-Key: sk_<goddard api key>
Content-Type: application/json
{
"title": "[Plex] Backup - 2026-03-30T02:00:00",
"overview": "Automated nightly Plex backup completed.",
"severity": 5,
"categoryId": "<TheWrightServer category ID>",
"typeId": "<Automation type ID>",
"itemId": "<Backup item ID>",
"assigneeId": "<Goddard user ID>"
}
```
CTI IDs can be fetched from:
- `GET /api/cti/categories`
- `GET /api/cti/types?categoryId=<id>`
- `GET /api/cti/items?typeId=<id>`
To regenerate the Goddard API key: Admin → Users → refresh icon next to Goddard.
---
## CI/CD
Push to `main` triggers `.gitea/workflows/build.yml`, which builds and pushes two images in parallel:
| Image | Tag |
|---|---|
| `$REGISTRY/josh/ticketing-server` | `latest`, `<git sha>` |
| `$REGISTRY/josh/ticketing-client` | `latest`, `<git sha>` |
**Gitea repository secrets/variables required:**
| Name | Type | Value |
|---|---|---|
| `REGISTRY` | Variable | `gitea.thewrightserver.net` |
| `REGISTRY_TOKEN` | Secret | Gitea personal access token with `write:packages` |
Set these under **Repository → Settings → Actions → Variables / Secrets**.
To deploy a specific commit SHA instead of latest:
```bash
TAG=<sha> docker compose up -d
```
---
## Environment Variables
| Variable | Required | Description |
|---|---|---|
| `DATABASE_URL` | Yes | PostgreSQL connection string |
| `JWT_SECRET` | Yes | Secret for signing JWTs — use `openssl rand -hex 64` |
| `CLIENT_URL` | Yes | Allowed CORS origin (your domain) |
| `PORT` | No | Server port (default: `3000`) |
| `REGISTRY` | Deploy | Container registry hostname |
| `POSTGRES_PASSWORD` | Deploy | Postgres password |
| `DOMAIN` | Deploy | Public domain for Traefik routing |
| `TAG` | Deploy | Image tag to deploy (default: `latest`) |
---
## Ticket Severity
| Level | Label | Meaning |
|---|---|---|
| 1 | SEV 1 | Critical — immediate action required |
| 2 | SEV 2 | High — significant impact |
| 3 | SEV 3 | Medium — standard priority |
| 4 | SEV 4 | Low — minor issue |
| 5 | SEV 5 | Minimal — informational / automated |
Tickets are sorted SEV 1 → SEV 5 on the dashboard. Paging by severity is planned for a future release.
---
## Ticket Status Lifecycle
```
OPEN → IN_PROGRESS → RESOLVED ──(14 days)──→ CLOSED
re-opens reset
the 14-day timer
```