feat: helpdesk pivot — tickets + Entra device inventory #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/helpdesk-pivot"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Pivots
vinnie/HelpDesk(forked fromopenplatform/app-template) into the v1 ESPO IT helpdesk app. Five commits, broken up to be reviewable:375ad492971225006c9f3d1c18c769bf35fWhat this app does
Tickets — classic helpdesk ticket model. Anyone signed in can file a ticket (open/in_progress/waiting/resolved/closed × low/normal/high/urgent); only the creator can edit or delete.
resolved_atis stamped on transition into a terminal status, cleared on transition back. Owner-only edit/delete in v1; assignee-aware permissions (via Forgejo group membership) is the natural follow-up.Devices — Intune-managed device inventory cached from Microsoft Graph.
POST /api/devices/syncpages throughdeviceManagement/managedDevices, upserts onentra_id, and records every attempt todevice_sync_runs(success/fail +error_message). The/devicespage surfaces last-sync metadata above the table.The Entra integration uses client-credentials against the existing
ESPOHelpDeskapp registration documented in/Users/vinnieespo/ESPO/HelpDesk/Cloud/FUTURE-HELPDESK-APP.md. Required env vars:AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET.Review-standards checklist
Every API route has been written against
13-review-standards:Object.create(null)sortable allowlist on every list route%/_/\escape withESCAPE '\\'on every q-searchcreated_by/assignee_idin any client response — joined for display names insteadany/as/@ts-ignorewithout justificationTest coverage (
bun:test, full module mocking)tickets-api.test.ts— 23 cases: 401 on every route, validation, prototype-pollution guards, ILIKE escape, allowlist sort, resolved_at stamp/clear, owner-only edit/deletedevices-api.test.ts— 7 cases: 401, default-50 pagination, unknown-compliance 400, ILIKE escape, sync run open/close happy path, unknown compliance normalised tounknown, failure path returns 502/SYNC_FAILED + UPDATEs run withsucceeded=FALSE+error_messageCaveats
This repo is
vinnie/HelpDesk(personal namespace) rather thanespo-corp/helpdeskbecause the platform'screate_appMCP tool currently fails with a 403 missingwrite:organizationscope on its Forgejo token (issue openplatform/op-api#94). Consequently:espo-corpviacreate_appand replay these commits there.Test plan
bun install && bun typecheck— passesbun test— 30 cases pass/unauthenticated → sign-in card renders/tickets/new→ redirects to/tickets/[id]/devicesshows the empty state until Entra creds are configured + sync runs once- /api/tickets GET (paginated list w/ q + status filter) POST (auth required, Zod-validated, parameterised) - /api/tickets/:id GET / PATCH / DELETE PATCH stamps resolved_at on terminal status, clears it on transition back. Owner-only edit/delete. - /api/devices GET (paginated, q across name/user/serial, compliance filter) - /api/devices/sync POST: opens device_sync_runs row, pages Graph, upserts every managedDevice on entra_id, closes the run with success/failure + error_message. All routes follow review-standards: session check first, parameterised SQL, Object.create(null) sortable allowlist, ILIKE wildcard escape, no created_by / assignee_id in response projections.- / Dashboard. Status counts (open/in_progress/waiting/ resolved/closed) + ten most-recent tickets. Replaces the old items home. - /tickets Full paginated list with q + status filters and allowlisted sort. - /tickets/[id] Detail view. Selects created_by server-side to compute canEdit, strips it before passing to client. - /tickets/new Form. Pre-fills requester_email with the signed-in user's email. - /devices Cached Intune inventory. Surfaces last sync run summary (timestamp, success/failure, error_message) above the table; SyncDevicesButton triggers a fresh pull.