Commit Graph

28 Commits

Author SHA1 Message Date
jared 7fb60a365e Suppress title-only update comments to stop hourly comment spam
Lint / PHP (phpcs PSR-12) (push) Failing after 45s
Lint / JS (eslint) (push) Successful in 19s
Security / PHP Security (semgrep) (push) Failing after 1m37s
Lint / Deploy (push) Has been skipped
Lint / Notify on failure (push) Successful in 2s
Comments on worsening condition now only fire on priority escalation.
Title and description updates are silent — title changes (e.g. rising
Power_On_Hours counters) were generating a comment on every hourly run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:16:41 -04:00
jared fb3b607bd1 Resolve merge conflict in create_ticket_api.php OSD regex
Lint / PHP (phpcs PSR-12) (push) Failing after 33s
Lint / JS (eslint) (push) Successful in 15s
Security / PHP Security (semgrep) (push) Failing after 2m20s
Lint / Deploy (push) Has been skipped
Lint / Notify on failure (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:10:14 -04:00
jared dad7c24bff Fix hwmonDaemon hash collisions and automated comment formatting
- source_type (auto vs manual) added to dedup hash so automated
  tickets never collide with manually created ones
- OSD-specific subtype (osd_down_N) so each OSD gets its own ticket
- Description refreshed on every automated update (current sensor data)
- Comments on worsening condition only fire on meaningful changes
- ASCII art descriptions wrapped in fenced code blocks in comments
- Reopen comment also uses fenced code block

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:09:12 -04:00
jared 9e9d8a33e3 Fix hwmonDaemon hash collisions and automated description rendering
Lint / PHP (phpcs PSR-12) (push) Successful in 40s
Lint / JS (eslint) (push) Successful in 13s
Security / PHP Security (semgrep) (push) Failing after 1m59s
Lint / Deploy (push) Successful in 5s
Lint / Notify on failure (push) Has been skipped
- Include source_type (auto vs manual) in dedup hash so automated
  tickets never collide with manually created ones. This was causing
  hwmonDaemon to hijack manual task tickets that shared the same
  cluster/category/environment tags.

- Include specific OSD ID in hash subtype (osd_down_N) so each OSD
  failure gets its own ticket instead of all colliding to osd_down.

- Wrap hwmonDaemon report descriptions in fenced code blocks in
  comments so ASCII art box-drawing renders correctly instead of
  collapsing into a paragraph blob.

- Refresh ticket description on every automated update so the ticket
  body shows current sensor data, not stale values from first report.

- Only post a worsening-condition comment when title or priority
  actually changed (not just a description refresh).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:06:13 -04:00
jared c90bdc8ac8 style: auto-fix 1340 phpcs PSR-12 violations via phpcbf; exclude MissingNamespace and SideEffects
Lint / PHP (phpcs PSR-12) (push) Failing after 29s
Lint / JS (eslint) (push) Successful in 12s
2026-04-13 20:56:10 -04:00
jared 6b89a14a47 Fix ticket ID generation in create_ticket_api.php to avoid leading zeros
Use random_int(100000000-999999999) so IDs are always 9 digits without
a leading zero, matching the behaviour of TicketModel::createTicket().
The old sprintf('%09d', mt_rand(1, ...)) could produce IDs like
000123456 which broke PHP array key lookups elsewhere.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 13:06:08 -04:00
jared 09292119e6 Only send Matrix notification on priority escalation, not title updates
Title changes (e.g. rising Power_On_Hours counter) were firing a Matrix
ping every hour. Notifications now only trigger when priority escalates
to a higher severity level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:43:22 -04:00
jared 499060795e Use drive serial for dedup hash; update title/priority on worsened conditions
Two changes to the external ticket API:

1. Serial-based dedup: generateTicketHash() now uses the `serial` field
   from the hwmonDaemon payload as the stable drive identifier instead of
   extracting /dev/sdX from the title. Device path is kept as a fallback
   for payloads without a serial field (backwards compatible).
   Hash key renamed from `device` to `drive` to reflect this.

2. Active-ticket updates: when a duplicate is detected and the ticket is
   still open, the API now compares the incoming title and priority against
   the existing ticket. If the title changed or priority escalated (lower
   number), the ticket is updated and a comment is added explaining what
   changed. Previously the API silently returned "Duplicate ticket" with
   no update.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:55:15 -04:00
jared fe9c6b3ee0 Rewrite create_ticket_api.php dedup logic: reopen closed tickets on recurrence
Instead of crashing (PHP 8.2 TypeError) or silently failing on duplicate hash,
the API now:
- Checks for any existing ticket with the same hash (no 24h limit)
- If open/pending/in-progress: returns Duplicate ticket with existing ID
- If closed: reopens the ticket, posts a recurrence comment, returns action=reopened
- If new: creates the ticket as before
- Wraps INSERT in try/catch for mysqli_sql_exception to handle race conditions
  gracefully when multiple nodes POST simultaneously

Also improves the hash function:
- Ceph issues now include a subtype (bluestore_slow, clock_skew, osd_down, etc.)
  so different Ceph warnings get distinct tickets instead of colliding
- LXC storage issues include the container ID so each container gets its own ticket
- Fixed potential null-subject issue in preg_match for missing titles
- Added early input validation (400 + JSON error) before any processing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:40:36 -04:00
jared 570b1749da Fix PHP 8.2 TypeError crash in create_ticket_api.php on missing title
generateTicketHash() passed $data['title'] to preg_match() before any
input validation. In PHP 8.2, preg_match() with null subject throws
TypeError, causing HTTP 500 with empty body. hwmonDaemon saw this as
"Expecting value: line 1 column 1 (char 0)" and failed to create tickets
on all nodes.

Moved input validation before the hash call: missing or empty title now
returns HTTP 400 with proper JSON error instead of crashing. Also removed
the redundant late URL-encoded fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:07:11 -04:00
jared f59913910f Replace Discord webhook notifications with Matrix (hookshot)
- Add helpers/NotificationHelper.php: shared Matrix webhook sender
  that reads MATRIX_WEBHOOK_URL and MATRIX_NOTIFY_USERS from config
- Remove sendDiscordWebhook() from TicketController; call
  NotificationHelper::sendTicketNotification() instead
- Replace 60-line Discord embed block in create_ticket_api.php
  with a single NotificationHelper call
- config/config.php: DISCORD_WEBHOOK_URL → MATRIX_WEBHOOK_URL +
  new MATRIX_NOTIFY_USERS key (comma-separated Matrix user IDs)
- .env.example: updated env var names and comments

Payload sent to hookshot includes notify_users array so the
JS transform can build proper @mention links for each user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 19:17:46 -05:00
jared 15063838bd Fix Discord webhook showing localhost instead of APP_DOMAIN
create_ticket_api.php was not including config/config.php, so
$GLOBALS['config'] was empty when UrlHelper::ticketUrl() checked
for APP_DOMAIN, causing it to fall back to localhost.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 12:31:49 -05:00
jared 5b2a2c271e Add security logging, domain validation, and output helpers
- Add authentication failure logging to AuthMiddleware (session expiry,
  access denied, unauthenticated access attempts)
- Add UrlHelper for secure URL generation with host validation against
  configurable ALLOWED_HOSTS whitelist
- Add OutputHelper with consistent XSS-safe escaping functions (h, attr,
  json, url, css, truncate, date, cssClass)
- Add validation to AuditLogModel query parameters (pagination limits,
  date format validation, action/entity type validation, IP sanitization)
- Add APP_DOMAIN and ALLOWED_HOSTS configuration options

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:51:16 -05:00
jared 8b89114607 Unify Discord webhook notifications between API and manual ticket creation
- Standardized embed format across both ticket creation paths
- Added consistent priority colors (P1-P5) with distinct hex values
- Added priority labels (e.g., "P1 - Critical" instead of just "1")
- Added Source field showing hostname extracted from ticket title
- Added Status field to both webhook formats
- Added footer distinguishing "Automated Alert" vs "Manual Entry"
- Added timestamp to API endpoint webhooks
- Added error logging for failed webhook calls
- Added timeout (10s) to API endpoint curl calls
- Added null check for webhook URL in API endpoint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 11:11:40 -05:00
jared 11a593a7dd refactor: Code cleanup and documentation updates
Bug fixes:
- Fix ticket ID extraction using URLSearchParams instead of split()
- Add error handling for query result in get_users.php
- Make Discord webhook URLs dynamic (use HTTP_HOST)

Code cleanup:
- Remove debug console.log statements from dashboard.js and ticket.js
- Add getTicketIdFromUrl() helper function to both JS files

Documentation:
- Update Claude.md: fix web server (nginx not Apache), add new notes
- Update README.md: add keyboard shortcuts, update setup instructions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:01:20 -05:00
jared be505b7312 Implement comprehensive improvement plan (Phases 1-6)
Security (Phase 1-2):
- Add SecurityHeadersMiddleware with CSP, X-Frame-Options, etc.
- Add RateLimitMiddleware for API rate limiting
- Add security event logging to AuditLogModel
- Add ResponseHelper for standardized API responses
- Update config.php with security constants

Database (Phase 3):
- Add migration 014 for additional indexes
- Add migration 015 for ticket dependencies
- Add migration 016 for ticket attachments
- Add migration 017 for recurring tickets
- Add migration 018 for custom fields

Features (Phase 4-5):
- Add ticket dependencies with DependencyModel and API
- Add duplicate detection with check_duplicates API
- Add file attachments with AttachmentModel and upload/download APIs
- Add @mentions with autocomplete and highlighting
- Add quick actions on dashboard rows

Collaboration (Phase 5):
- Add mention extraction in CommentModel
- Add mention autocomplete dropdown in ticket.js
- Add mention highlighting CSS styles

Admin & Export (Phase 6):
- Add StatsModel for dashboard widgets
- Add dashboard stats cards (open, critical, unassigned, etc.)
- Add CSV/JSON export via export_tickets API
- Add rich text editor toolbar in markdown.js
- Add RecurringTicketModel with cron job
- Add CustomFieldModel for per-category fields
- Add admin views: RecurringTickets, CustomFields, Workflow,
  Templates, AuditLog, UserActivity
- Add admin APIs: manage_workflows, manage_templates,
  manage_recurring, custom_fields, get_users
- Add admin routes in index.php

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:55:01 -05:00
jared 8c7211d311 Add Ceph cluster-wide ticket deduplication support
Update generateTicketHash() to exclude hostname from hash for
cluster-wide Ceph issues, enabling proper deduplication across
all nodes in the cluster.

Cluster-wide issues detected by:
- [cluster-wide] tag in title
- HEALTH_ERR or HEALTH_WARN in title
- "cluster usage" in title

This prevents all nodes from creating duplicate tickets for the
same cluster-wide issue (e.g., Ceph HEALTH_WARN).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:53:45 -05:00
jared de9da756e9 Fix duplicate ticket creation for evolving SMART errors
Problem: When SMART errors evolved on the same drive, new tickets were created
instead of updating the existing ticket. This happened because the hash was
based on specific error values (e.g., "Reallocated_Sector_Ct: 8") instead of
just the issue category.

Root Cause:
- Old hash included specific SMART attribute names and values
- When errors changed (8 → 16 reallocated sectors, or new errors appeared),
  the hash changed, allowing duplicate tickets
- Only matched "Warning" attributes, missing "Critical" and "Error X occurred"
- Only matched /dev/sd[a-z], missing NVMe devices

Solution:
- Hash now based on: hostname + device + issue_category (e.g., "smart")
- Does NOT include specific error values or attribute names
- Supports both /dev/sdX and /dev/nvmeXnY devices
- Detects issue categories: smart, storage, memory, cpu, network

Result:
 Same drive, errors evolve → Same hash → Updates existing ticket
 Different device → Different hash → New ticket
 Drive replaced → Different device → New ticket
 NVMe devices now supported

Example:
Before:
- "Warning Reallocated: 8" → hash abc123
- "Warning Reallocated: 16" → hash xyz789 (NEW TICKET - bad!)

After:
- "Warning Reallocated: 8" → hash abc123
- "Warning Reallocated: 16" → hash abc123 (SAME TICKET - good!)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-07 19:27:13 -05:00
jared b29ee6653b Fix .env file parsing to properly handle quoted values
- Updated parse_ini_file to use INI_SCANNER_TYPED
- Added quote stripping for all .env value parsing
- Fixes database connection and Discord webhook issues when values are quoted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 16:52:35 -05:00
jared 7b25ec1dd1 SSO Update :) 2026-01-01 15:40:32 -05:00
jared d7a5ab3576 Update create_ticket_api.php 2025-11-29 12:52:27 -05:00
jared e05434137c Fixed MAJOR bugs, currently at a semi-stable state 2025-09-05 11:08:56 -04:00
jared 1fe7bc0f93 Better deduplication 2025-05-15 08:33:13 -04:00
jared e563f1d791 Updated precog for regex drive ticket deduplication 2025-03-03 18:23:44 -05:00
jared e52192469a Moved data variable before use 2025-02-27 22:12:28 -05:00
jared 7228709ff6 Ticket Deduplication with the hwmonDaemon script 2025-02-27 21:39:47 -05:00
jared 5120afddf5 Added discord webhooks, better filtering, and automated ticket creation 2024-12-02 21:21:10 -05:00
jared 891291c5eb First Commit 2024-11-30 19:48:01 -05:00