4 Commits

Author SHA1 Message Date
josh 2177162300 Config and housekeeping cleanup
Build & Push / Test (client) (push) Successful in 29s
Build & Push / Test (server) (push) Successful in 28s
Build & Push / Build Client (push) Successful in 53s
Build & Push / Build Server (push) Successful in 2m21s
- .gitignore: add coverage/, .vscode/, .idea/
- .env.example files: add header comments clarifying production vs dev,
  add SMTP vars to server dev template
- Validate SavedView filters on load with safeParse fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 20:45:46 -04:00
josh edf4c5eb3c Phase 2b: backend services, routes, and notification triggers
Attachments: multer-backed uploads with random-hex filenames,
streaming downloads with Content-Disposition, 25MB limit,
mimetype allowlist, audit entries, orphan cleanup on DB failure.

Full-text search: searchTicketIds + searchComments via raw SQL
ranked with ts_rank, composable filters via Prisma.sql/join,
hydrated with findMany and reordered via Map to preserve rank.

Pagination: listTicketsPaged returns {data,total,page,pageSize}
only when page/pageSize present (array response stays default,
so the Goddard n8n flow is unchanged).

Bulk actions: reassign/close/setSeverity/setStatus on POST /bulk,
writes one audit entry per ticket via createMany.

Analytics: summarize(window) runs 5 parallel groupBy + raw-SQL
queries for open-by-severity, status counts, queue load,
age buckets, percentile_cont median resolution hours.

CSV export streams matching tickets via res.write; saved views
CRUD with per-user ownership checks (403 cross-user, 404 missing).

Notifications: in-app Notification rows gated by prefs, email via
nodemailer (SMTP_HOST-gated, no-op when unset), outgoing webhooks
with HMAC-SHA256 signed POST and 3-retry exponential backoff.
Triggers wired into createTicket/updateTicket/addComment; mention
detection via parseMentions skips self-notify.

Infra: docker-compose uploads volume + SMTP env passthrough;
.env.example SMTP section.

43 server tests passing (attachment/webhook/notification/savedView
services covered; bulkAction covered in ticketService).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 15:56:33 -04:00
josh 8b0273e70b Remove Traefik — use simple port binding for NPM
Build & Push / Build Server (push) Successful in 52s
Build & Push / Build Client (push) Successful in 39s
Stack uses Tailscale + Nginx Proxy Manager, not Traefik.
Client exposes PORT (default 3080) for NPM to proxy to.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:51:49 -04:00
josh 21894fad7a Initial commit: TicketingSystem
Build & Push / Build Client (push) Failing after 9s
Build & Push / Build Server (push) Failing after 28s
Internal ticketing app with CTI routing, severity levels, and n8n integration.

Stack: Express + TypeScript + Prisma + PostgreSQL / React + Vite + Tailwind
- JWT auth for users, API key auth for service accounts (Goddard/n8n)
- CTI hierarchy (Category > Type > Item) for ticket routing
- Severity 1-5, auto-close resolved tickets after 14 days
- Gitea Actions CI/CD building separate server/client images
- Production docker-compose.yml with Traefik integration

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