Commit graph

102 commits

Author SHA1 Message Date
9459d65e02 docs: add AUTOTASK_API_GUIDE.md to docs folder 2026-03-21 18:07:30 -04:00
679fe3871c feat: add OpenClaw read-only Datto RMM API endpoints
GET /api/openclaw/datto-rmm/sites
GET /api/openclaw/datto-rmm/devices         (filters: siteUid, online, deleted, page, limit)
GET /api/openclaw/datto-rmm/devices/[uid]
GET /api/openclaw/datto-rmm/devices/[uid]/audit  (always live)
GET /api/openclaw/datto-rmm/alerts          (filters: resolved, siteUid, deviceUid, limit)
GET /api/openclaw/datto-rmm/alerts/open

- All protected by x-openclaw-key header
- Default: queries Pulse DB (datto_rmm_devices/alerts/sites tables)
- ?live=true: proxies to Datto RMM API via DattoRMMClient
- Responses include source:'db'|'live' for data freshness awareness
2026-03-21 17:45:19 -04:00
ff9e34cafe feat: add Autotask tags sync (tag groups, tags, ticket tag associations)
- Migration 057: autotask_tag_groups, autotask_tags, and junction tables
  (ticket_tags, company_tags, configuration_item_tags, contact_tags)
- Add TAG_GROUPS and TAGS to EntityType enum and dependency map
- Add mapTagGroup() and mapTag() entity mapper functions
- Add syncTagGroups(), syncTags(), syncTicketTagAssociations() methods
- Wire TicketTagAssociations bulk sync into full/incremental sync flow
- Add 'exist' operator to QueryFilter type
- No FK on ticket_id (tagged tickets may be outside 2yr sync window)

Synced: 26 tag groups, 7299 tags, 10141 ticket-tag associations
2026-03-20 09:22:40 -04:00
fe9f806c50 feat: mobile — filter all queries to Wulf Managed companies only
All mobile dashboard and ticket list queries now INNER JOIN companies
on user_defined_fields->>'MSP Service Model' = 'Wulf Managed', scoping
all stats (open total, by priority, by queue, SLA, recent activity)
and ticket list to managed clients only. 349 open tickets in scope.
2026-03-18 00:08:41 -04:00
012c7bde50 feat: mobile timeline — render links as tappable [link] in notes and time entries
- Replace stripHtml() with renderContent() that:
  1. Extracts <a href="...">...</a> anchors before stripping HTML
  2. Strips remaining HTML tags cleanly
  3. Detects bare https?:// URLs in plain text
  4. Renders each as a tappable <a>[link]</a> with text-primary underline
- Collapsed note preview still shows plain text (no link clutter)
- Expanded note/time-entry body shows inline [link] elements
2026-03-18 00:05:56 -04:00
c8be128c5c feat: companies sync — add UDFs and fix all field mappings
Migration 056:
- ADD user_defined_fields JSONB (GIN indexed)
- ADD parent_company_id, web_address, create_date, company_category_id
- ADD is_client_portal_active, is_task_fire_active, is_comanaged
- ADD country_id, bill_to_country_id, bill_to_address_to_use
- ADD invoice_email_message_id, purchase_order_template_id
- ADD additional_address_information, sic_code, stock_market, etc.

entity-mapper.ts mapCompany():
- Fix broken snake_case field refs (was data.invoice_method, data.last_activity_date etc.)
- All corrected to actual Autotask camelCase API names (invoiceMethod, lastActivityDate, etc.)
- was data.webSiteURL → data.webAddress
- was data.taxExempt → data.isTaxExempt
- was data.lastTrackedModifiedDateTime (various) → data.lastTrackedModifiedDateTime
- Add UDF conversion: userDefinedFields[] array → JSONB {name: value} object
- 38 UDFs now stored: PassportalID, MimecastID, MSP Service Model, Short Name,
  Workstation Lifecycle Plan, Seats (End Users), CSProfileUID, UniFiID, etc.
2026-03-17 23:56:40 -04:00
8315a46da0 fix: mobile ticket timeline — hide system/workflow notes by default
- API: marks note_type 13,91,93,94,99,101 as is_system=true
  (13=workflow rule fired, 91=workflow templates, 99=RMM system notes,
   93/94=merge/absorb, 101=other system)
- Frontend: system notes filtered out by default; 'Show system' toggle
  in timeline header reveals them
- Time entry expanded card uses bg-muted/border-border (dark-mode safe)
  instead of hard-coded bg-blue-50 which was unreadable in dark theme
- Priority labels and colors corrected to match actual Autotask values
- Status labels expanded to full set
2026-03-17 23:49:50 -04:00
5719daa84b fix: mobile dashboard priority labels now join priorities table
- API: replaced hardcoded wrong map (1=Critical etc) with JOIN on priorities table
- API: sorted by count DESC instead of priority value
- Frontend: PRIORITY_COLOR/TEXT maps updated to cover all 10 actual Autotask values (1-11)
- Middleware: added /api/mobile to publicRoutes (was getting auth-redirected)
2026-03-17 23:44:00 -04:00
5be7b22953 feat: OpenClaw external agent sync API at /api/openclaw/*
- API key auth via x-openclaw-key header (OPENCLAW_API_KEY env var)
- GET  /api/openclaw/sync/status
- POST /api/openclaw/sync/autotask/incremental
- POST /api/openclaw/sync/autotask/full
- POST /api/openclaw/sync/autotask/entity   { entities: [...] }
- POST /api/openclaw/sync/datto-rmm          { syncType: full|incremental }
- POST /api/openclaw/sync/sentinelone
- POST /api/openclaw/sync/veeam              { syncType: full|incremental }
- POST /api/openclaw/sync/zoom
- POST /api/openclaw/sync/engagement
- POST /api/openclaw/sync/qbo                { syncType: full|incremental }
- POST /api/openclaw/sync/zabbix
- POST /api/openclaw/sync/itglue
All routes bypass Better Auth middleware, delegate to existing sync services
2026-03-17 23:26:44 -04:00
eea66de129 docs: refresh database skill — timezone (UTC), full picklist tables, updated row counts 2026-03-17 23:05:57 -04:00
7ce06803dc fix: time entries incremental sync uses lastModifiedDateTime not dateWorked
Previously the incremental filter compared dateWorked >= lastSyncTime,
meaning edits to existing entries (hours adjusted, notes changed, PTO
blocks entered in advance) were never picked up after initial ingestion.

Switch both the lastModifiedField mapping and buildTimeEntriesFilter to
use lastModifiedDateTime so any created or modified entry is captured
on the next scheduled sync.
2026-03-17 23:01:18 -04:00
b6c2681a69 fix: Mimecast 7-day chunk windows, 30-day retention limit, two-pass from+to domain filter 2026-03-17 16:53:46 -04:00
22bea85648 fix: Mimecast two-pass sync (from+to wulfconsulting.com), correct filter handling 2026-03-17 16:44:01 -04:00
c1479511bf fix: Mimecast correct credentials, x-mc-account header, no-ms date format, accountCode in body 2026-03-17 16:38:13 -04:00
25bb70cfa6 feat: Mimecast email integration — message logs, threat events, 120d retention, admin UI 2026-03-17 16:23:47 -04:00
7792e91587 ui: clarify date range doesn't apply to configuration items and other non-date entities 2026-03-17 15:59:19 -04:00
597ffbee9f fix: widen all VARCHAR columns in configuration_items to TEXT
Serial numbers, hostnames, SNMP strings, RMM identifiers, backup type UDF
all exceed VARCHAR limits in real data. Convert all to TEXT to prevent
future truncation errors during sync.
2026-03-17 15:52:57 -04:00
7762cf284e fix: widen VARCHAR(50) columns in configuration_items that exceed limit
IP addresses, MACs, and mobile numbers can exceed 50 chars (IPv6, UUIDs).
Widen datto_internal_ip, datto_remote_ip, rmm_device_audit_external_ip_address,
rmm_device_audit_ip_address to VARCHAR(255); mac_address and mobile_number to VARCHAR(100).
2026-03-17 15:48:35 -04:00
cb293ea843 fix: configuration_items sync — correct camelCase field mapping, store all UDFs in udfs JSONB
- Fix mapConfigurationItem() to use Autotask camelCase field names (was using
  snake_case keys that never matched, leaving costs/Datto/RMM fields empty)
- Map all 60+ fields explicitly: costs, Datto device fields, RMM audit fields,
  location, vendor, SNMP, backup dates, source cost, etc.
- Store entire userDefinedFields array as udfs JSONB (keyed by UDF name)
- Retain backup_type_udf VARCHAR column for backward compat
- Migration 052: add udfs JSONB column + GIN index to configuration_items
2026-03-17 15:39:42 -04:00
0f1083f5b6 feat: mobile app — scaffold, ticket dashboard, finance AR overview, invoice drill-down 2026-03-17 15:31:56 -04:00
c1351fc6ca docs: update database skill with QBO, Zabbix, Auth domains and refreshed row counts 2026-03-17 08:52:38 -04:00
02c81bf4e4 feat: enable Entra ID authentication
- Enable Better Auth middleware (was bypassed with return NextResponse.next())
- Re-enable AuthProvider in root layout
- Add public routes for webhooks, sync, kiosk, QBO, legal, health endpoints
- Set Microsoft Entra ID credentials and production Better Auth URLs
- Hide Engagement and Admin nav sections from non-super-admins
- Fix auth DB columns: snake_case → camelCase for Better Auth compatibility
- Add twoFactorEnabled column to user table
2026-03-17 08:49:20 -04:00
b98c67482a feat: QuickBooks Online integration
- Add QBO OAuth2 client with token refresh (lib/services/qbo-client.ts)
- Add QBO sync service for invoices, payments, deposits, purchases, journal entries, reports (lib/services/qbo-sync-service.ts)
- Add QBO types (lib/types/qbo.ts)
- Add API routes: /api/qbo/auth, /api/qbo/sync, /api/qbo/disconnect
- Add /admin/qbo status and sync management page
- Add legal pages: /legal/eula, /legal/privacy (Intuit app assessment)
- Add QBO nav link under Admin
- Fix reports: remove invalid summarize_column_by, add accounting_method from Preferences API, add showrows=all&showcols=all
- Add CashFlow report type alongside P&L and BalanceSheet
- Add NoReportData check to skip empty report months
- Add intuit_tid capture in error messages
- Add redirect: follow for cluster routing
- Migration 051: qbo_tokens, qbo_invoices, qbo_payments, qbo_deposits, qbo_transactions, qbo_reports tables

Also includes earlier work:
- Ping flap suppression pipeline step
- Ticket digest reports with LLM analysis
- Zabbix WAN monitor and gap analysis
- Kiosk is_deleted filter fixes
- Datto RMM ping target enrichment
- Entity sync soft-delete detection
2026-03-17 07:39:55 -04:00
c518eefdb2 feat: Morning NOC Summary adaptive card for Teams
- Add MorningSummaryService with Zabbix aggregation and adaptive card builder
- Add webhook delivery system with Teams incoming webhooks
- Add admin UI at /admin/morning-summary for webhook/config management
- Add API routes: /send, /test, /webhooks, /webhooks/[id], /config, /history
- Register morning-summary cron job in SyncScheduler (Mon-Fri 6:30 AM)
- Add outages_only filter (Unavailable triggers only)
- Fix host resolution: use getTriggerEnabledHosts to exclude disabled hosts
- Fix resolved events: event.get value:1 scoped to window with r_eventid filter
- Remove emojis from fact rows and section headers in card
- Remove Open Zabbix button (duplicate of View Problems)
- Add migrations: morning_summary_config + morning_summaries tables
- Add outages_only column to morning_summary_config
2026-03-11 09:34:51 -04:00
19605f82aa feat: IT Glue integration, workflow engine, pipelines, Zabbix WAN, notification channels, backup status UI improvements, nav alignment fixes 2026-02-27 14:52:14 -05:00
ed6c4a8b65 feat: Add SentinelOne integration
- Add SentinelOne API client (lib/services/sentinelone-client.ts)
  - Paginated fetching for sites, agents, threats
  - JWT token auth via S1_API_URL / S1_API_TOKEN env vars

- Add SentinelOne sync service (lib/services/sentinelone-sync-service.ts)
  - Full sync: sites, agents, threats into s1_* tables
  - Sync history tracking with per-entity results

- Add DB migration 038: s1_sites, s1_agents, s1_threats,
  s1_company_mappings, s1_sync_history tables

- Add API routes:
  - POST/GET /api/sentinelone/sync
  - GET/POST/DELETE /api/sentinelone/company-mappings
  - GET /api/sentinelone/coverage (fixed Cartesian product bug)

- Add UI pages:
  - /admin/sync/sentinelone — sync admin with history + stats
  - /sentinelone/coverage — AV coverage report per site
  - /sentinelone/mappings — map S1 sites to Autotask companies

- Wire SentinelOne into admin sync overview card grid
- Add SentinelOne Sync to app navigation
- Fix docker-compose: remove explicit S1 env var entries that
  were overwriting env_file values with empty strings
2026-02-27 05:31:31 -05:00
d7c3dc7168 feat: Autotask webhook integration, TicketNotes, Datto RMM, workflow engine, Veeam agents/alarms, AI triage, misc improvements 2026-02-20 10:28:15 -05:00
347cf4e298 feat: dual-tab DetailModal with Formatted and Raw views
- Formatted tab: grouped sections (Overview, Parties, Classification, Dates, System)
- ID-to-label resolution for status, priority, source, queue, company type
- Elegant bordered table layout with muted label column
- Clickable phone/URL fields, monospace IDs, formatted dates
- Description rendered in its own block for tickets
- Raw tab: all fields with monospace keys, copy-on-hover
- Auto-detects ticket vs company data for appropriate grouping
- Shadcn Tabs, Separator, Badge used throughout
2026-02-19 21:00:33 -05:00
6ccdb156ba fix: remove hardcoded sm:max-w-lg from DialogContent so className overrides work
- Removed sm:max-w-lg default that was overriding max-w-7xl in DetailModal
- DialogContent now respects whatever max-w class is passed via className
- Fixes data browser detail modal not widening as expected
2026-02-19 20:51:57 -05:00
2eee5e09f0 style: widen data browser detail modal from max-w-4xl to max-w-7xl 2026-02-19 20:46:41 -05:00
3c13defacb feat: kiosk UI updates - new cards, gauge chart, performance improvements
- Updated kiosk stats API with expanded metrics
- New components: company-tickets-card, gauge-chart, service-desk-card, ticket-leaders-card
- Updated cycling-display, kpi-card, and ticker components
- Added performance.css for kiosk optimizations
- Added Wulf logo asset
2026-02-19 15:31:23 -05:00
5dc7a7e66b feat: Veeam VSPC backup integration - sync, compliance, UI
- Database: 7 Veeam tables + backup_type_udf column on configuration_items
- API Client: VSPC REST API v3 client with pagination, rate limiting, Bearer auth
- Sync Service: full/incremental sync for orgs, servers, repos, jobs, agent jobs, workloads
- Scheduler: veeam-incremental (30min) and veeam-full (daily 2AM) schedules
- Compliance Engine: cross-references Autotask config items vs Veeam workloads
- API Endpoints: backup-status, companies, workloads, jobs, repos, compliance, sync
- UI: Backup Status page with Overview + Contract Compliance tabs
- Navigation: added Backup Status link with HardDrive icon
- Docker: added VEEAM_VSPC_URL and VEEAM_VSPC_API_KEY env vars to compose
2026-02-11 21:04:28 -05:00
a1e0e7c7c0 feat: improve ticker layout and speed controls
- Restructured ticker to show ticket number and title on first line
- Company name now displays on second line below ticket
- Adjusted ticker speed slider range: 8s-120s (was 10s-120s)
- Changed step from 5s to 2s for finer speed control
- Allows 25% faster speed adjustment (down to 8s)
- Better two-line layout for improved readability
2026-02-05 08:13:25 -05:00
73a2e9b9a3 perf: optimize ticker animation and increase speed
- Added translate3d(0,0,0) for hardware acceleration
- Added font smoothing for better rendering
- Reduced default ticker speed from 60s to 30s (2x faster)
- Improved animation smoothness to reduce jitter
- Better GPU acceleration with backface-visibility and willChange
2026-02-05 07:58:33 -05:00
4a545b5f5c fix: use container class to align navigation with dashboard cards
- Changed from max-w-6xl to container mx-auto
- Restored left-4 and right-4 positioning for logo and theme toggle
- Navigation edges now align perfectly with dashboard card edges
- Matches the same container padding used throughout the app
2026-02-04 09:00:33 -05:00
b7e43c2232 style: align navigation edges with card content
- Removed container class, using max-w-6xl with px-4 directly
- Changed absolute positioning from left-4/right-4 to left-0/right-0
- Navigation edges now align perfectly with card edges
- Logo lines up with Dashboard text on left
- Theme toggle aligns with card edge on right
2026-02-04 08:50:41 -05:00
4316d0187f style: constrain navigation width to match content cards
- Added max-w-6xl to navigation container
- Navigation now aligns with KPI cards on wide screens
- Prevents navigation from stretching too wide
- Maintains consistent layout alignment
2026-02-04 08:48:09 -05:00
94f960bdbf fix: replace all favicon files with Wulf logo
- Replaced favicon.ico with Wulf logo PNG
- Removed old icon.svg (triangle icon)
- Added icon.png with Wulf logo
- All favicon formats now use Wulf logo
- Should fix persistent triangle icon issue
2026-02-04 08:45:19 -05:00
f49767d1eb fix: update favicon to use Wulf logo PNG format
- Added favicon.png copy of Wulf logo
- Updated metadata to use PNG favicon with multiple size options
- Should fix triangle icon issue in browser tab
- Favicon now properly displays Wulf logo
2026-02-04 08:12:35 -05:00
7b3830a388 fix: move Wulf logo to left navbar, correct spelling to Wulf
- Replaced Pulse icon with Wulf logo on left side of navbar
- Removed duplicate logo from right side
- Corrected alt text from 'Wulff' to 'Wulf'
- Logo now appears next to Pulse branding on left
2026-02-03 23:52:56 -05:00
98199f671d feat: add Wulff Consulting logo to navigation and favicon
- Added Wulff logo (W_RGB.png) to public directory
- Updated favicon to use Wulff logo
- Added logo to upper right of navigation bar (h-10)
- Logo appears next to theme toggle
- Links to home page when clicked
2026-02-03 23:49:58 -05:00
13fd13afd6 style: remove all top padding on kiosk display
- Changed to px-4 pb-4 pt-0 (zero top padding)
- KPI cards now sit right against navigation bar
- Maximizes vertical screen space for TV display
2026-02-03 23:41:47 -05:00
60b58b3f57 style: reduce top padding on kiosk display
- Changed padding from p-16 to p-4 pt-2
- Brings KPI cards closer to navigation bar
- Better use of screen space for TV display
2026-02-03 23:39:38 -05:00
f27b23bec8 fix: pre-populate classifications instead of syncing from Autotask API
- Autotask REST API doesn't expose ClassificationIcons endpoint
- Created migration to populate 17 standard classification icons
- Removed sync button from UI (classifications are pre-loaded)
- Includes: Tools Only, Co-Managed, Wulf 365 Essentials, Partner, etc.
- Users can now select any classification to exclude from kiosk
2026-02-03 20:54:35 -05:00
b222d97225 feat: add classification icons sync from Autotask
- Created company_classifications table to store Autotask classification icons
- Added getClassificationIcons() method to AutotaskClient
- Created /api/sync/classifications endpoint (GET/POST)
- Updated kiosk settings UI to dynamically load classifications
- Added 'Sync from Autotask' button to pull latest classifications
- Removed hardcoded classification list
- Display classification name and description in checkboxes
- Allow excluding any classification synced from Autotask
2026-02-03 20:48:08 -05:00
9940c20379 fix: parse excluded_classifications as array and handle companies API response
- Fixed settings API to parse excluded_classifications as array
- Fixed companies API response handling (returns {companies: []} not array)
- Resolves TypeError: excluded_classifications.filter is not a function
- Resolves TypeError: s.sort is not a function
2026-02-03 09:20:50 -05:00
root
1d99a8f659 feat: add classification-based filtering and fix company name display
- Added classification column to companies table
- Created excluded_classifications setting (default: Tools Only)
- Updated kiosk stats and activity APIs to filter by classification
- Added comprehensive classification filtering UI with checkboxes
- Support for common classifications (Tools Only, Wulff Consulting Client, Customer)
- Allow custom classification entry
- Fixed company name display in settings (convert string IDs properly)
- Classification filtering works alongside company ID exclusions
2026-02-03 09:17:07 -05:00
root
62ec703f81 feat: increase ticket font sizes and fix company name display
- Increased ticket number font from text-lg to text-2xl
- Increased company name font from text-sm to text-lg
- Increased ticket title font from text-xs to text-base
- Increased padding on ticket cards for better spacing
- Fixed company ID to name conversion in settings page
- Ensure excluded_company_ids are parsed as numbers for proper lookup
2026-02-03 09:09:46 -05:00
root
26bfd503f1 feat: add kiosk settings UI and co-managed client filtering
- Created kiosk_settings table for configuration storage
- Added API endpoints for kiosk settings (GET/POST)
- Filter out co-managed clients (configurable company exclusions)
- Built comprehensive settings UI at /kiosk/settings
- Allow excluding specific companies from kiosk display
- Configurable cycle interval, refresh interval, and RMM alert toggle
- Updated dashboard link to point to settings page
- Applied company exclusion filter to all ticket queries and activity feed
- Default excludes Thrasher Group (ID: 29861361)
2026-02-03 08:32:42 -05:00
root
724791121a feat: add top 3 tickets display on kiosk KPI cards
- Show company name and ticket title for top 3 tickets per category
- Critical tickets sorted by priority then create date
- Waiting tickets sorted by oldest activity
- Stale tickets sorted by oldest activity
- Overdue tickets sorted by most overdue
- Closed tickets sorted by most recent
- Adjusted card layout to accommodate ticket list
2026-02-03 08:25:27 -05:00