docs: add Auvik section, expand projects/tasks vs tickets distinction

- Add Auvik Network Management section (§4): auvik_tenants and
  auvik_tenant_mappings schema, sample data, join patterns, note that
  device inventory is fetched live from API not stored in DB
- Add Auvik hostname naming convention note (ynghynswp27 pattern)
- Expand projects section with full column list and relationship to tickets
- Expand tasks section with clear tickets vs projects vs tasks distinction,
  real-world examples (Switch [Config/Build/Deploy] task naming), and
  query patterns for project tasks vs ticket sub-tasks
- Add project/task/Auvik join pattern examples to §13
- Update §14 Important Notes: Auvik cross-platform link, tickets/projects/tasks
  guidance for query intent, updated row counts (March 2026)
- Renumber sections 5-12 → 6-13 to accommodate new Auvik section
- Update domain table to include Auvik row
This commit is contained in:
Claude 2026-03-24 11:33:29 -04:00
parent d1fb9db9d4
commit 4d75a099d7

View file

@ -18,6 +18,7 @@
|---|---|---|---|
| **Autotask PSA** | tickets, time_entries, companies, contacts, resources, configuration_items, contracts, projects, tasks, ticket_notes | 152K tickets, 156K time entries, 7K CIs | Service desk, billing, contracts, clients |
| **Datto RMM** | datto_rmm_alerts, datto_rmm_devices, datto_rmm_sites | 21K alerts, 3.6K devices | Remote monitoring & management |
| **Auvik** | auvik_tenants, auvik_tenant_mappings | 17 tenants, 15 mappings | Network management — device inventory fetched live from API; tenant/company links stored in DB |
| **SentinelOne** | s1_agents, s1_threats, s1_sites | 2.8K agents, 4.1K threats | Endpoint security |
| **Veeam** | veeam_organizations, veeam_backup_jobs, veeam_backup_agents, veeam_alarms, veeam_protected_workloads, veeam_repositories, veeam_backup_servers | ~2.5K total | Backup & disaster recovery |
| **IT Glue** | itg_organizations, itg_configurations, itg_passwords, itg_flexible_assets, itg_contacts, itg_documents, itg_expirations, itg_domains, itg_locations | 14.7K configs | IT documentation |
@ -196,21 +197,75 @@ Line items on contracts.
- `company_id``companies.id`
- `service_name` (text), `unit_price`, `quantity`
### projects (~291 rows, 36 columns)
### projects (~314 rows, 36 columns)
Planned engagements for client work — distinct from reactive service tickets. A project has a defined scope, timeline, and budget. Think of projects as the planned/scheduled side of the business (switch deployments, onboarding, infrastructure upgrades) while tickets are the reactive/support side.
**Key columns:**
- `id`, `company_id`, `project_name`, `status`, `type`
- `project_lead_resource_id``resources.id`
- `start_date_time`, `end_date_time`, `actual_hours`, `estimated_time`
- `id` (bigint PK) — Autotask project ID
- `company_id` (bigint) — FK to `companies.id`
- `project_name` (varchar) — display name
- `project_number` (varchar) — unique identifier string
- `description` (text)
- `status` (int) — project status code
- `type` (int) — project type
- `project_lead_resource_id` (bigint) — FK to `resources.id`
- `owner_resource_id` (bigint) — FK to `resources.id`
- `start_date_time`, `end_date_time` (timestamp) — scheduled window
- `completed_date_time` (timestamp)
- `estimated_time` (numeric) — estimated hours
- `actual_hours` (numeric) — hours logged so far
- `estimated_sale_cost`, `labor_estimated_revenue` (numeric) — financial estimates
- `completed_percentage` (numeric) — 0100
- `last_activity_date_time` (timestamp)
- `is_deleted` (boolean)
### tasks (~4.3K rows, 34 columns)
**Relationship to tickets:** A ticket can optionally be linked to a project via `tickets.project_id`. This is typically used when a ticket was generated as part of project work (e.g. a change request within a project).
Tasks on tickets or projects.
### tasks (~5K rows, 34 columns)
- `ticket_id``tickets.id`
- `project_id``projects.id`
- `assigned_resource_id``resources.id`
- `status`, `priority`, `estimated_hours`, `remaining_hours`
Tasks are discrete units of work that live **inside** a project or a ticket. They are NOT standalone items — every task belongs to either a project (`project_id`) or a ticket (`ticket_id`), not both simultaneously.
**Key difference from tickets:**
- **Tickets** = reactive service desk items. Created by clients, RMM alerts, email, or portal. Queued and triaged.
- **Tasks** = planned steps within a project (or checklist items on a ticket). Created by technicians and project managers. Have structured phases and scheduling.
**Real-world examples of tasks:**
- A "Switch Deployment" project might have tasks: `Switch [Config] - ynghynswp27`, `Switch [Build] - ynghynswp27`, `Switch [Deploy] - ynghynswp27`
- Each task represents a discrete phase of work, assigned to a resource with estimated hours
**Key columns:**
- `id` (bigint PK) — Autotask task ID
- `title` (varchar) — task name
- `description` (text)
- `project_id` (bigint) — FK to `projects.id` (if this is a project task)
- `ticket_id` (bigint) — FK to `tickets.id` (if this is a ticket sub-task)
- `phase_id` (bigint) — project phase grouping (project tasks only)
- `assigned_resource_id` (bigint) — FK to `resources.id`
- `creator_resource_id` (bigint) — FK to `resources.id`
- `status` (int), `priority` (int)
- `task_type` (int)
- `task_number` (varchar) — human-readable number within the project
- `estimated_hours` (numeric), `remaining_hours` (numeric)
- `start_date_time`, `end_date_time` (timestamp) — scheduled window
- `completed_date_time` (timestamp)
- `task_is_billable` (boolean)
- `is_deleted` (boolean)
**Time entries on tasks:** `time_entries.task_id` links work logs to specific tasks. Task time entries also carry `project_id` and `company_id` for quick aggregation without joins.
**Finding project tasks vs ticket tasks:**
```sql
-- Project tasks only
SELECT t.*, p.project_name FROM tasks t
JOIN projects p ON p.id = t.project_id
WHERE t.project_id IS NOT NULL AND t.is_deleted IS NOT TRUE;
-- Ticket sub-tasks only
SELECT t.*, tk.title AS ticket_title FROM tasks t
JOIN tickets tk ON tk.id = t.ticket_id
WHERE t.ticket_id IS NOT NULL AND t.is_deleted IS NOT TRUE;
```
### billing_items (~96K rows)
@ -415,7 +470,58 @@ Join: `issue_types.value = tickets.issue_type`
---
## 4. SentinelOne
## 4. Auvik Network Management
Auvik is the network device management platform used to monitor and manage client network infrastructure (switches, routers, firewalls, APs, etc.). It organizes clients as **tenants** — one tenant per client organization.
**Important:** Auvik **device inventory is NOT stored in the Pulse database.** Device data (hostnames, IPs, device types, configs, firmware) is fetched **live from the Auvik API** at query time. Only the tenant list and their mappings to Autotask companies are persisted in the DB.
### auvik_tenants (~17 rows)
The list of Auvik tenants (client organizations) known to this Pulse instance.
**Key columns:**
- `id` (int PK) — internal DB ID
- `tenant_id` (varchar) — Auvik's unique tenant identifier (numeric string, e.g. `"197643669426944326"`)
- `tenant_name` (varchar) — short name / domain prefix (e.g. `"seubert"`, `"wulfconsulting"`)
- `domain_prefix` (varchar) — same as tenant_name; used in Auvik URLs
- `device_count` (int) — last known device count from sync
- `last_sync_at` (timestamptz) — when this tenant was last synced
- `created_at`, `updated_at` (timestamptz)
**Sample tenants:** vollmer, poha, premierautomation, wulfconsulting, vorteqcoilfinishers, seubert, hynesindustries, greco, therla, and ~8 others.
### auvik_tenant_mappings (~15 rows)
Maps each Auvik tenant to its corresponding Autotask company. This is the cross-platform link between network management and the PSA.
**Key columns:**
- `id` (int PK)
- `auvik_tenant_id` (varchar) — Auvik tenant ID, matches `auvik_tenants.tenant_id`
- `auvik_tenant_name` (varchar) — short name
- `autotask_company_id` (int) — FK to `companies.id`
- `autotask_company_name` (varchar) — denormalized for convenience
- `created_at`, `updated_at` (timestamptz)
**Join pattern — Auvik tenant → Autotask company:**
```sql
SELECT atm.auvik_tenant_name, c.company_name, c.id AS autotask_company_id
FROM auvik_tenant_mappings atm
JOIN companies c ON c.id = atm.autotask_company_id;
```
**What Auvik tracks (via live API, not DB):**
- Network device inventory: switches, routers, firewalls, access points, printers, UPS units
- Device details: hostname, IP addresses, MAC addresses, model, firmware version, vendor
- Online/offline status and last seen time
- Device configurations (running config snapshots — see `/api/auvik/device-config` endpoint)
- Network topology and interface relationships
**Auvik device naming convention:** Hostnames in Auvik follow the pattern `{client_prefix}{device_type}{sequence}`, e.g. `ynghynswp27` = `ynghy` (client) + `nsw` (network switch) + `p27` (port count / unit). These hostnames also appear in Autotask ticket notes and task titles when work is performed on the device.
---
## 6. SentinelOne
### s1_agents (~2.8K rows, 42 columns)
@ -452,7 +558,7 @@ Maps S1 sites to Autotask companies for cross-referencing.
---
## 5. Veeam Backup
## 7. Veeam Backup
### veeam_organizations (~17 columns)
@ -481,7 +587,7 @@ Supporting tables for backup infrastructure.
---
## 6. IT Glue Documentation
## 8. IT Glue Documentation
### itg_organizations (~330 rows)
@ -516,7 +622,7 @@ Supporting IT documentation tables.
---
## 7. Engagement & Communications
## 9. Engagement & Communications
### graph_users
@ -562,7 +668,7 @@ Weekly/monthly aggregates of M365 activity per user.
---
## 8. QuickBooks Online (Accounting)
## 10. QuickBooks Online (Accounting)
### qbo_invoices (~6.9K rows)
@ -616,7 +722,7 @@ Periodic financial reports stored as JSON.
---
## 9. Zabbix NMS
## 11. Zabbix NMS
### zabbix_wan_hosts (~75 rows)
@ -643,7 +749,7 @@ Zabbix alert events.
---
## 10. Authentication (Better Auth + Entra ID)
## 12. Authentication (Better Auth + Entra ID)
### "user" table (~3 rows)
@ -676,7 +782,7 @@ OAuth provider links (Microsoft Entra ID).
---
## 11. Common Join Patterns
## 13. Common Join Patterns
```sql
-- Ticket with company, resource, and status label
@ -740,11 +846,53 @@ FROM zabbix_events ze
JOIN zabbix_wan_hosts zwh ON zwh.host_id = ze.host_id
LEFT JOIN companies c ON c.id = zwh.company_id
WHERE ze.value = 1 ORDER BY ze.clock DESC;
-- Project with all its tasks and hours logged
SELECT p.project_name, p.status, p.actual_hours,
t.title AS task_title, t.status AS task_status,
t.estimated_hours, t.remaining_hours,
r.first_name || ' ' || r.last_name AS assigned_to
FROM projects p
LEFT JOIN tasks t ON t.project_id = p.id AND t.is_deleted IS NOT TRUE
LEFT JOIN resources r ON r.id = t.assigned_resource_id
WHERE p.id = $1 AND p.is_deleted IS NOT TRUE;
-- All time entries for a project (direct + via tasks)
SELECT te.entry_date, te.hours_worked, te.notes,
r.first_name || ' ' || r.last_name AS technician,
t.title AS task_title,
te.billable
FROM time_entries te
JOIN resources r ON r.id = te.resource_id
LEFT JOIN tasks t ON t.id = te.task_id
WHERE te.project_id = $1 AND te.is_deleted IS NOT TRUE
ORDER BY te.entry_date;
-- Hours by technician across all projects this month
SELECT r.first_name || ' ' || r.last_name AS technician,
SUM(te.hours_worked) AS total_hours,
SUM(CASE WHEN te.billable THEN te.hours_worked ELSE 0 END) AS billable_hours
FROM time_entries te
JOIN resources r ON r.id = te.resource_id
WHERE te.project_id IS NOT NULL
AND te.entry_date >= DATE_TRUNC('month', NOW())
AND te.is_deleted IS NOT TRUE
GROUP BY 1 ORDER BY 2 DESC;
-- Auvik tenant → Autotask company → open tickets
SELECT atm.auvik_tenant_name, c.company_name,
COUNT(tk.id) AS open_tickets
FROM auvik_tenant_mappings atm
JOIN companies c ON c.id = atm.autotask_company_id
LEFT JOIN tickets tk ON tk.company_id = c.id
AND tk.status NOT IN (5) -- not Complete
AND tk.is_deleted IS NOT TRUE
GROUP BY 1, 2 ORDER BY 3 DESC;
```
---
## 12. Important Notes
## 14. Important Notes
1. **Soft deletes:** Most Autotask tables have `is_deleted` (boolean) and `deleted_at`. Always add `WHERE is_deleted IS NOT TRUE` unless you want deleted records.
@ -760,7 +908,15 @@ WHERE ze.value = 1 ORDER BY ze.clock DESC;
- RMM → Autotask: `datto_rmm_sites.autotask_company_id = companies.id`
- IT Glue → Autotask: `itg_organizations.psa_id::bigint = companies.id`
- S1 → Autotask: via `s1_company_mappings`
- Auvik → Autotask: `auvik_tenant_mappings.autotask_company_id = companies.id`
- Zoom/Teams → Contacts: `matched_contact_id` / `matched_company_id` columns
- Config Items → RMM: `configuration_items.reference_number` sometimes matches RMM device UIDs
- Auvik hostnames → Autotask tickets/tasks: search `ticket_notes.description` and `tasks.title` for the device hostname (e.g. `ynghynswp27`) to find all work done on a network device
7. **Row counts** (as of March 17, 2026): tickets 152K, time_entries 156K, billing_items 96K, ticket_notes 42K, teams_meetings 14.4K, itg_configurations 14.7K, configuration_items 7K, companies 246, contacts 4.2K, datto_rmm_devices 3.6K, datto_rmm_alerts 21K, s1_agents 2.8K, s1_threats 4.1K, zoom_calls 2.8K, qbo_invoices 6.9K, qbo_transactions 12.1K, qbo_payments 4.5K, qbo_deposits 1.8K, qbo_reports 36, zabbix_wan_hosts 75, zabbix_events 231.
7. **Tickets vs Projects vs Tasks — when to use which:**
- Query `tickets` when asking about: support requests, break/fix, helpdesk, RMM alerts, client-reported issues, SLA performance, response times, queue volumes
- Query `projects` when asking about: planned work, deployments, onboarding, infrastructure upgrades, project status, project hours/budget
- Query `tasks` when asking about: individual steps within a project, task completion rates, who is assigned to what within a project, task-level time tracking. Tasks have both `project_id` (project tasks) and `ticket_id` (ticket sub-tasks) — check which is populated.
- Query `time_entries` for actual hours worked — it spans all three: `ticket_id`, `task_id`, and `project_id` can all be non-null depending on context
8. **Row counts** (as of March 24, 2026): tickets 152K, time_entries 156K, billing_items 96K, ticket_notes 42K, teams_meetings 14.4K, itg_configurations 14.7K, configuration_items 7K, tasks 5K, projects 314, companies 246, contacts 4.2K, datto_rmm_devices 3.6K, datto_rmm_alerts 21K, s1_agents 2.8K, s1_threats 4.1K, auvik_tenants 17, auvik_tenant_mappings 15, zoom_calls 2.8K, qbo_invoices 6.9K, qbo_transactions 12.1K, qbo_payments 4.5K, qbo_deposits 1.8K, qbo_reports 36, zabbix_wan_hosts 75, zabbix_events 231.