Commit Graph

5 Commits

Author SHA1 Message Date
Gjermund Høsøien Wiggen
e960df61ad feat: implement full scrip action engine with real executors
- SendEmail: real nodemailer transport with SMTP config, dynamic recipient resolution
  (static + ticket creator/owner lookup), Handlebars template support
- Webhook: HTTP POST/any method with configurable headers and JSON body
- FetchMetadata: external HTTP fetch, Handlebars URL/body templating,
  auto-adds result as comment/correspondence on ticket
- RunScript: arbitrary async JS execution with helpers (addComment,
  createTransaction, updateTicket, touchTicket), ticket context, and
  Drizzle ORM access
- SetCustomField: lookup by id/key/name, clear+insert value, record
  CustomFieldChange transaction
- CreateTransaction: insert arbitrary transaction record
- Add OnCustomFieldChange condition
- Pass condition_config to evaluator in engine

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 10:42:59 +02:00
Gjermund Høsøien Wiggen
04b4e28d21 Change ticket IDs from UUID to sequential integers
Backend:
- tickets.id: uuid → integer GENERATED ALWAYS AS IDENTITY
- transactions.ticket_id, custom_field_values.ticket_id: uuid → integer
- Routes convert string params to Number() for DB queries
- ScripEngine.prepare takes ticketId: number
- ActionPayload.ticketId: string → number

Frontend:
- Ticket.id: string → number, Transaction.ticket_id: string → number
- API functions accept number params
- formatTicketId() helper returns TKT-0001 format
- Ticket rows display TKT-XXXX, detail page uses formatTicketId

Migration: drops FKs, clears data, alters column types, re-adds FKs
2026-06-07 23:23:05 +02:00
Gjermund Høsøien Wiggen
3a98027f5e fix: scrip engine condition matching and ticket GET endpoint
- engine.ts: remove transaction_type-based scrip filtering. Now uses condition evaluator
  exclusively (matching by scrip.condition_type against transaction types was incorrect —
  'OnResolve' ≠ 'StatusChange'). All non-disabled, queue-matching scrips are evaluated.
- tickets.ts: fix GET /:id — replace broken Drizzle 'with' relation with manual CF join.
  Set up Drizzle relations needed for proper schema typing (customFieldValues → customFields).
2026-06-07 21:48:04 +02:00
Gjermund Høsøien Wiggen
1f238330c7 feat: scrip engine implementation — real SMTP, webhooks, DB actions
- config.ts: add SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM
- engine.ts: prepare() queries real scrips from DB, matches by queue_id + condition_type, loads lifecycle for OnResolve context, renders Handlebars templates, builds PreparedScrip. commit() dispatches to real action executors.
- actions.ts: SendEmail via nodemailer SMTP, Webhook via fetch POST, SetCustomField writes to custom_field_values table
- conditions.ts: OnResolve uses LifecycleValidator.isResolvedStatus()
- tickets.ts: updated to pass lifecycleDef context to scrip engine
- nodemailer installed
- Port changed to 9876 (8080 occupied by Apache)

Verification: bun run src/index.ts starts server, GET /health returns {"status":"ok","version":"0.1.0"}
2026-06-07 21:38:56 +02:00
Gjermund Høsøien Wiggen
1136227510 TypeScript/Bun project scaffold
- Stack: Bun, Hono, Drizzle ORM, Zod, Handlebars, Pino
- Models: ticket, queue, transaction, scrip, template, custom_field, user, lifecycle
- Scrip engine: prepare/commit two-phase dispatch, template rendering, mock actions
- Lifecycle validator: state machine transition validation with wildcard support
- Routes: health, tickets (full CRUD + preview + transactions), queues, scrips, custom-fields, lifecycles
- Middleware: Pino logging, error handler
- Database: Drizzle ORM schema + initial migration (10 tables)
- Type-check: passes (tsc --noEmit, zero errors)
2026-06-07 21:21:50 +02:00