- Add permissions logic for status options in corrective actions. - Create tests for permissions functionality. - Implement queries for user authentication and actions management. - Develop Actions page to display and manage corrective actions. - Create authentication pages for login, setup, and password reset. - Add IncidentDetail page to view incident details and associated actions. - Implement Settings page for user management and password changes.
184 lines
4.1 KiB
TypeScript
184 lines
4.1 KiB
TypeScript
// Response shapes returned by the API. Dates are ISO 8601 strings.
|
|
import type {
|
|
actionKinds,
|
|
actionStatuses,
|
|
AreaKind,
|
|
IncidentStatus,
|
|
IncidentType,
|
|
rcaMethods,
|
|
Role,
|
|
rootCauseCategories,
|
|
Severity,
|
|
} from './enums.ts'
|
|
|
|
export type ActionKind = (typeof actionKinds)[number]
|
|
export type ActionStatus = (typeof actionStatuses)[number]
|
|
export type RcaMethod = (typeof rcaMethods)[number]
|
|
export type RootCauseCategory = (typeof rootCauseCategories)[number]
|
|
|
|
export interface UserRef {
|
|
id: string
|
|
name: string
|
|
}
|
|
|
|
export interface User {
|
|
id: string
|
|
email: string
|
|
name: string
|
|
role: Role
|
|
active: boolean
|
|
lastLoginAt: string | null
|
|
createdAt: string
|
|
}
|
|
|
|
export interface Organization {
|
|
id: string
|
|
name: string
|
|
}
|
|
|
|
export interface Area {
|
|
id: string
|
|
siteId: string
|
|
parentId: string | null
|
|
name: string
|
|
kind: AreaKind
|
|
archivedAt: string | null
|
|
}
|
|
|
|
export interface Site {
|
|
id: string
|
|
name: string
|
|
address: string | null
|
|
timezone: string
|
|
archivedAt: string | null
|
|
areas: Area[]
|
|
}
|
|
|
|
export interface Incident {
|
|
id: string
|
|
number: number
|
|
reference: string
|
|
title: string
|
|
type: IncidentType
|
|
severity: Severity
|
|
status: IncidentStatus
|
|
occurredAt: string
|
|
reportedAt: string
|
|
updatedAt: string
|
|
closedAt: string | null
|
|
site: { id: string; name: string }
|
|
area: { id: string; name: string } | null
|
|
locationDetail: string | null
|
|
description: string | null
|
|
immediateAction: string | null
|
|
anonymous: boolean
|
|
reporter: UserRef | null
|
|
}
|
|
|
|
export interface Investigation {
|
|
id: string
|
|
lead: UserRef | null
|
|
method: RcaMethod
|
|
summary: string | null
|
|
startedAt: string
|
|
completedAt: string | null
|
|
}
|
|
|
|
export interface RootCause {
|
|
id: string
|
|
category: RootCauseCategory
|
|
description: string
|
|
whys: string[]
|
|
}
|
|
|
|
export interface CorrectiveAction {
|
|
id: string
|
|
incident: { number: number; reference: string; title: string }
|
|
rootCauseId: string | null
|
|
kind: ActionKind
|
|
title: string
|
|
description: string | null
|
|
assignee: UserRef | null
|
|
dueDate: string | null
|
|
status: ActionStatus
|
|
overdue: boolean
|
|
completedAt: string | null
|
|
verifiedBy: UserRef | null
|
|
verifiedAt: string | null
|
|
createdAt: string
|
|
}
|
|
|
|
export interface Attachment {
|
|
id: string
|
|
fileName: string
|
|
contentType: string
|
|
sizeBytes: number
|
|
uploadedBy: UserRef | null
|
|
createdAt: string
|
|
url: string
|
|
}
|
|
|
|
export interface TransitionOption {
|
|
to: IncidentStatus
|
|
label: string
|
|
/** Why the transition can't happen yet; absent when it is allowed. */
|
|
blockedReason?: string
|
|
}
|
|
|
|
export interface IncidentDetail extends Incident {
|
|
investigation: Investigation | null
|
|
rootCauses: RootCause[]
|
|
actions: CorrectiveAction[]
|
|
attachments: Attachment[]
|
|
transitions: TransitionOption[]
|
|
/** What the signed-in user may do on this incident. */
|
|
can: { edit: boolean; manageInvestigation: boolean; manageActions: boolean }
|
|
}
|
|
|
|
export interface Comment {
|
|
id: string
|
|
author: UserRef | null
|
|
body: string
|
|
createdAt: string
|
|
}
|
|
|
|
export interface TimelineEntry {
|
|
id: number
|
|
at: string
|
|
actor: UserRef | null
|
|
action: string
|
|
changes: Record<string, unknown> | null
|
|
}
|
|
|
|
export interface Paginated<T> {
|
|
items: T[]
|
|
page: number
|
|
pageSize: number
|
|
total: number
|
|
}
|
|
|
|
export interface OverviewStats {
|
|
openIncidents: number
|
|
reportedLast7Days: number
|
|
actionsDueThisWeek: number
|
|
overdueActions: number
|
|
/** Average days from report to close for incidents closed in the last 90 days. */
|
|
averageCloseDays: number | null
|
|
byStatus: Record<IncidentStatus, number>
|
|
actionProgress: { completed: number; total: number }
|
|
/** Incidents per week for the last 12 weeks, oldest first. */
|
|
weeklyTrend: { weekStart: string; count: number }[]
|
|
bySite: { siteId: string; name: string; count: number }[]
|
|
}
|
|
|
|
export interface AnalyticsStats {
|
|
periodDays: number
|
|
total: number
|
|
byType: { type: IncidentType; count: number }[]
|
|
bySeverity: { severity: Severity; count: number }[]
|
|
topRootCause: { category: RootCauseCategory; count: number; share: number } | null
|
|
/** Share of completed actions finished on or before their due date. */
|
|
onTimeActionRate: number | null
|
|
monthlyCompletedActions: { month: string; onTime: number; late: number }[]
|
|
}
|