grm-shared-library 1.1.241 → 1.1.242

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/cjs/index.js +1 -0
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/modules/permission/data/permissions.data.js +8 -0
  4. package/dist/cjs/modules/permission/data/permissions.data.js.map +1 -1
  5. package/dist/cjs/modules/permission/enums/permission-actions.enum.js +17 -0
  6. package/dist/cjs/modules/permission/enums/permission-actions.enum.js.map +1 -1
  7. package/dist/cjs/modules/permission/enums/permissions-module.enum.js +1 -0
  8. package/dist/cjs/modules/permission/enums/permissions-module.enum.js.map +1 -1
  9. package/dist/cjs/modules/responder/constants/responder.const.js +124 -0
  10. package/dist/cjs/modules/responder/constants/responder.const.js.map +1 -0
  11. package/dist/cjs/modules/responder/dtos/responder.dto.js +582 -0
  12. package/dist/cjs/modules/responder/dtos/responder.dto.js.map +1 -0
  13. package/dist/cjs/modules/responder/enums/responder.enums.js +142 -0
  14. package/dist/cjs/modules/responder/enums/responder.enums.js.map +1 -0
  15. package/dist/cjs/modules/responder/index.js +29 -0
  16. package/dist/cjs/modules/responder/index.js.map +1 -0
  17. package/dist/cjs/modules/responder/interfaces/responder-dispatch.js +3 -0
  18. package/dist/cjs/modules/responder/interfaces/responder-dispatch.js.map +1 -0
  19. package/dist/cjs/modules/responder/interfaces/responder-policy.js +3 -0
  20. package/dist/cjs/modules/responder/interfaces/responder-policy.js.map +1 -0
  21. package/dist/cjs/modules/responder/interfaces/responder.js +3 -0
  22. package/dist/cjs/modules/responder/interfaces/responder.js.map +1 -0
  23. package/dist/cjs/modules/responder/utils/responder.util.js +65 -0
  24. package/dist/cjs/modules/responder/utils/responder.util.js.map +1 -0
  25. package/dist/cjs/modules/role/data/roles.data.js +25 -4
  26. package/dist/cjs/modules/role/data/roles.data.js.map +1 -1
  27. package/dist/cjs/modules/tracking/enums/tracking-provider-code.enum.js +8 -0
  28. package/dist/cjs/modules/tracking/enums/tracking-provider-code.enum.js.map +1 -1
  29. package/dist/esm/index.js +1 -0
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/modules/permission/data/permissions.data.js +8 -0
  32. package/dist/esm/modules/permission/data/permissions.data.js.map +1 -1
  33. package/dist/esm/modules/permission/enums/permission-actions.enum.js +17 -0
  34. package/dist/esm/modules/permission/enums/permission-actions.enum.js.map +1 -1
  35. package/dist/esm/modules/permission/enums/permissions-module.enum.js +1 -0
  36. package/dist/esm/modules/permission/enums/permissions-module.enum.js.map +1 -1
  37. package/dist/esm/modules/responder/constants/responder.const.js +121 -0
  38. package/dist/esm/modules/responder/constants/responder.const.js.map +1 -0
  39. package/dist/esm/modules/responder/dtos/responder.dto.js +560 -0
  40. package/dist/esm/modules/responder/dtos/responder.dto.js.map +1 -0
  41. package/dist/esm/modules/responder/enums/responder.enums.js +139 -0
  42. package/dist/esm/modules/responder/enums/responder.enums.js.map +1 -0
  43. package/dist/esm/modules/responder/index.js +13 -0
  44. package/dist/esm/modules/responder/index.js.map +1 -0
  45. package/dist/esm/modules/responder/interfaces/responder-dispatch.js +2 -0
  46. package/dist/esm/modules/responder/interfaces/responder-dispatch.js.map +1 -0
  47. package/dist/esm/modules/responder/interfaces/responder-policy.js +2 -0
  48. package/dist/esm/modules/responder/interfaces/responder-policy.js.map +1 -0
  49. package/dist/esm/modules/responder/interfaces/responder.js +2 -0
  50. package/dist/esm/modules/responder/interfaces/responder.js.map +1 -0
  51. package/dist/esm/modules/responder/utils/responder.util.js +59 -0
  52. package/dist/esm/modules/responder/utils/responder.util.js.map +1 -0
  53. package/dist/esm/modules/role/data/roles.data.js +24 -3
  54. package/dist/esm/modules/role/data/roles.data.js.map +1 -1
  55. package/dist/esm/modules/tracking/enums/tracking-provider-code.enum.js +8 -0
  56. package/dist/esm/modules/tracking/enums/tracking-provider-code.enum.js.map +1 -1
  57. package/dist/types/index.d.ts +1 -0
  58. package/dist/types/modules/permission/enums/permission-actions.enum.d.ts +3 -0
  59. package/dist/types/modules/permission/enums/permissions-module.enum.d.ts +2 -1
  60. package/dist/types/modules/responder/constants/responder.const.d.ts +67 -0
  61. package/dist/types/modules/responder/dtos/responder.dto.d.ts +144 -0
  62. package/dist/types/modules/responder/enums/responder.enums.d.ts +128 -0
  63. package/dist/types/modules/responder/index.d.ts +7 -0
  64. package/dist/types/modules/responder/interfaces/responder-dispatch.d.ts +144 -0
  65. package/dist/types/modules/responder/interfaces/responder-policy.d.ts +55 -0
  66. package/dist/types/modules/responder/interfaces/responder.d.ts +113 -0
  67. package/dist/types/modules/responder/utils/responder.util.d.ts +24 -0
  68. package/dist/types/modules/role/data/roles.data.d.ts +7 -0
  69. package/dist/types/modules/tracking/enums/tracking-provider-code.enum.d.ts +9 -1
  70. package/package.json +1 -1
@@ -0,0 +1,144 @@
1
+ import { ResponseUnitDispatchStatus } from '../../dispatch/enums/response-unit-dispatch-status.enum';
2
+ import { ResponderArrivalMethod, ResponderDispatchListState, ResponderReportField, ResponderReportOutcome } from '../enums/responder.enums';
3
+ /** `POST /responder/duty` - go on duty with one of the caller's units. */
4
+ export declare class StartResponderDutyDto {
5
+ responseUnitId: number;
6
+ }
7
+ /** `POST /responder/duty/end` - go off duty. Idempotent: ending no duty is not an error. */
8
+ export declare class EndResponderDutyDto {
9
+ reason?: string;
10
+ }
11
+ /** `POST /response-units/:id/responders/:userId/end-duty` - the control room ends someone's duty. */
12
+ export declare class EndResponderDutyByControlCentreDto extends EndResponderDutyDto {
13
+ }
14
+ /** `POST /response-units/:id/responders` - link a Responder account to a unit. */
15
+ export declare class AddResponseUnitResponderDto {
16
+ userId: number;
17
+ }
18
+ /** `GET /responder/dispatches`. Newest first. */
19
+ export declare class ResponderDispatchListQueryDto {
20
+ state?: ResponderDispatchListState;
21
+ page?: number;
22
+ limit?: number;
23
+ /** `123` or `#123`: only that incident's dispatches. */
24
+ search?: string;
25
+ }
26
+ /** A position fix the phone took, sent as evidence with an action. */
27
+ export declare class ResponderLocationFixDto {
28
+ latitude: number;
29
+ longitude: number;
30
+ accuracyMetres?: number;
31
+ /** When the phone took the fix (ISO 8601). */
32
+ recordedAt: string;
33
+ }
34
+ /**
35
+ * `POST /responder/dispatches/:dispatchId/status` - acknowledge, set off,
36
+ * arrive, complete or decline.
37
+ *
38
+ * Idempotent by target: asking for the status the dispatch already has returns
39
+ * it unchanged (HTTP 200) instead of a conflict, so a retry after a lost
40
+ * response is safe. `clientActionId` is recorded with the change for the audit.
41
+ */
42
+ export declare class RespondToDispatchDto {
43
+ status: ResponseUnitDispatchStatus;
44
+ clientActionId: string;
45
+ /** Why - required to decline, and for a manual arrival, when policy says so. */
46
+ reason?: string;
47
+ /** The phone's position when the action was taken, when it has one. */
48
+ location?: ResponderLocationFixDto;
49
+ /** ON_SCENE only: how the arrival was established. Defaults to GPS when a location is sent. */
50
+ arrivalMethod?: ResponderArrivalMethod;
51
+ }
52
+ export declare class ResponderChecklistAnswerDto {
53
+ itemId: string;
54
+ checked: boolean;
55
+ }
56
+ /**
57
+ * `POST /responder/dispatches/:dispatchId/report` - submit, or amend, the
58
+ * response report. The first submission is idempotent on `clientReportId`; an
59
+ * amendment must name the `expectedVersion` it was edited from.
60
+ */
61
+ export declare class SubmitResponderReportDto {
62
+ clientReportId: string;
63
+ /** Absent for the first submission; the version being amended otherwise. */
64
+ expectedVersion?: number;
65
+ summary: string;
66
+ actionsTaken?: string;
67
+ outcome: ResponderReportOutcome;
68
+ personsContacted?: string;
69
+ handoverTo?: string;
70
+ followUpRequired: boolean;
71
+ followUpNotes?: string;
72
+ remarks?: string;
73
+ checklist?: ResponderChecklistAnswerDto[];
74
+ /** DMS file ids (images, documents, videos) to attach to the incident with this report. */
75
+ attachmentIds?: number[];
76
+ }
77
+ export declare class ResponderPositionSampleDto {
78
+ latitude: number;
79
+ longitude: number;
80
+ accuracyMetres?: number;
81
+ altitudeMetres?: number;
82
+ /** Metres per second, as the phone reports it. */
83
+ speedMetresPerSecond?: number;
84
+ headingDegrees?: number;
85
+ /** When the phone took the fix (ISO 8601) - never the upload time. */
86
+ recordedAt: string;
87
+ /** The OS flagged it as a mock location. Kept and flagged, never used for arrival. */
88
+ isMocked?: boolean;
89
+ }
90
+ /**
91
+ * `POST /responder/positions` - positions of the unit the caller is on duty
92
+ * with. The server decides the unit from the caller's active duty session;
93
+ * the client never names one.
94
+ */
95
+ export declare class ReportResponderPositionsDto {
96
+ samples: ResponderPositionSampleDto[];
97
+ }
98
+ export declare class ResponderLocationPolicyDto {
99
+ onDutyIntervalSeconds?: number;
100
+ activeIntervalSeconds?: number;
101
+ distanceFilterMetres?: number;
102
+ maxAccuracyMetres?: number;
103
+ staleAfterSeconds?: number;
104
+ }
105
+ export declare class ResponderArrivalPolicyDto {
106
+ radiusMetres?: number;
107
+ allowManualConfirmation?: boolean;
108
+ manualReasonRequired?: boolean;
109
+ }
110
+ export declare class ResponderDispatchPolicyDto {
111
+ allowDecline?: boolean;
112
+ declineReasonRequired?: boolean;
113
+ }
114
+ export declare class ResponderChecklistItemDto {
115
+ id: string;
116
+ label: string;
117
+ required: boolean;
118
+ }
119
+ export declare class ResponderReportPolicyDto {
120
+ requiredToComplete?: boolean;
121
+ requiredFields?: ResponderReportField[];
122
+ checklist?: ResponderChecklistItemDto[];
123
+ minPhotos?: number;
124
+ }
125
+ export declare class ResponderEvidencePolicyDto {
126
+ allowPhotos?: boolean;
127
+ allowDocuments?: boolean;
128
+ allowVideo?: boolean;
129
+ maxImageMegabytes?: number;
130
+ maxDocumentMegabytes?: number;
131
+ maxVideoMegabytes?: number;
132
+ }
133
+ export declare class ResponderReporterContactPolicyDto {
134
+ visible?: boolean;
135
+ }
136
+ /** An organization's override of DEFAULT_RESPONDER_POLICY; every part optional. */
137
+ export declare class ResponderPolicyDto {
138
+ location?: ResponderLocationPolicyDto;
139
+ arrival?: ResponderArrivalPolicyDto;
140
+ dispatch?: ResponderDispatchPolicyDto;
141
+ report?: ResponderReportPolicyDto;
142
+ evidence?: ResponderEvidencePolicyDto;
143
+ reporterContact?: ResponderReporterContactPolicyDto;
144
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * The responder app: field personnel (role `Responder`) who staff a response
3
+ * unit, go on duty with it, receive its dispatches on their phone and report
4
+ * progress, arrival, position and the outcome back to the control room.
5
+ *
6
+ * A responder is linked to the units they may staff by an explicit membership
7
+ * (clarion-organization, managed by whoever holds update:response-unit). There
8
+ * is deliberately no implicit link by phone number: a crew phone typed into a
9
+ * unit form is not proof that an app account belongs to that crew.
10
+ */
11
+ /** Whether a responder is currently on duty with one of their units. */
12
+ export declare enum ResponderDutyStatus {
13
+ ON_DUTY = "ON_DUTY",
14
+ OFF_DUTY = "OFF_DUTY"
15
+ }
16
+ /** A duty session's own lifecycle. One session is ACTIVE per responder at most. */
17
+ export declare enum ResponderDutySessionStatus {
18
+ ACTIVE = "ACTIVE",
19
+ ENDED = "ENDED"
20
+ }
21
+ /** Why a duty session ended. */
22
+ export declare enum ResponderDutyEndReason {
23
+ /** The responder went off duty in the app. */
24
+ RESPONDER = "RESPONDER",
25
+ /** The control room ended it (update:response-unit). */
26
+ CONTROL_CENTRE = "CONTROL_CENTRE",
27
+ /** The responder was removed from the unit while on duty with it. */
28
+ MEMBERSHIP_REMOVED = "MEMBERSHIP_REMOVED",
29
+ /** The unit was deactivated or deleted while the responder was on duty with it. */
30
+ UNIT_DEACTIVATED = "UNIT_DEACTIVATED"
31
+ }
32
+ /** How an arrival on scene was established by the responder. */
33
+ export declare enum ResponderArrivalMethod {
34
+ /** The phone's position was within the organization's arrival radius. */
35
+ GPS = "GPS",
36
+ /** The responder confirmed it by hand (with a reason, when policy asks for one). */
37
+ MANUAL = "MANUAL"
38
+ }
39
+ /** How a response ended, as the responder reports it. */
40
+ export declare enum ResponderReportOutcome {
41
+ RESOLVED_ON_SCENE = "RESOLVED_ON_SCENE",
42
+ HANDED_OVER = "HANDED_OVER",
43
+ REFERRED = "REFERRED",
44
+ NO_ACTION_REQUIRED = "NO_ACTION_REQUIRED",
45
+ FALSE_ALARM = "FALSE_ALARM",
46
+ UNABLE_TO_LOCATE = "UNABLE_TO_LOCATE",
47
+ OTHER = "OTHER"
48
+ }
49
+ /** The free-text fields of a responder report a policy may make mandatory. */
50
+ export declare enum ResponderReportField {
51
+ SUMMARY = "summary",
52
+ ACTIONS_TAKEN = "actionsTaken",
53
+ PERSONS_CONTACTED = "personsContacted",
54
+ HANDOVER_TO = "handoverTo",
55
+ REMARKS = "remarks"
56
+ }
57
+ /** Which dispatches `GET /responder/dispatches` lists. */
58
+ export declare enum ResponderDispatchListState {
59
+ /** DISPATCHED, ACKNOWLEDGED, EN_ROUTE, ON_SCENE. */
60
+ ACTIVE = "ACTIVE",
61
+ /** COMPLETED, CANCELLED, REJECTED. */
62
+ HISTORY = "HISTORY",
63
+ ALL = "ALL"
64
+ }
65
+ /** How a unit's live position reaches clarion-response-tracking. */
66
+ export declare enum ResponderTrackingMode {
67
+ /** The on-duty responder's phone reports the unit's position. */
68
+ PHONE = "PHONE",
69
+ /** The unit has an enabled hardware tracker binding; the phone stays quiet so the two never compete. */
70
+ UNIT_DEVICE = "UNIT_DEVICE",
71
+ /** The caller is not on duty, so no position is accepted. */
72
+ NOT_ON_DUTY = "NOT_ON_DUTY"
73
+ }
74
+ /**
75
+ * `data.action` of the pushes clarion-notification sends a responder's phone.
76
+ * Every one carries `dispatchId`, `incidentId` and `route`; none carries the
77
+ * reporter's name, number, address or the incident description, because a
78
+ * push is shown on a lock screen.
79
+ */
80
+ export declare enum ResponderPushAction {
81
+ /** A unit the responder is on duty with was dispatched. */
82
+ DISPATCH_ASSIGNED = "RESPONDER_DISPATCH_ASSIGNED",
83
+ /** The control room stood the unit down (CANCELLED). */
84
+ DISPATCH_STOOD_DOWN = "RESPONDER_DISPATCH_STOOD_DOWN",
85
+ /** Any other status change made by somebody else (control room, lifecycle, tracking). */
86
+ DISPATCH_UPDATED = "RESPONDER_DISPATCH_UPDATED"
87
+ }
88
+ /**
89
+ * Machine-readable refusals of the responder endpoints, in the error body's
90
+ * `code` (the same `{statusCode, code, message, ...details}` envelope the
91
+ * dispatch endpoints use).
92
+ */
93
+ export declare enum ResponderErrorCode {
94
+ /** The caller does not hold the Responder role. */
95
+ NOT_A_RESPONDER = "RESPONDER_NOT_A_RESPONDER",
96
+ /** The responder account has no control centre, so nothing can be scoped. */
97
+ NO_CONTROL_CENTRE = "RESPONDER_NO_CONTROL_CENTRE",
98
+ UNIT_NOT_FOUND = "RESPONDER_UNIT_NOT_FOUND",
99
+ /** The caller is not a member of that unit. */
100
+ NOT_A_UNIT_MEMBER = "RESPONDER_NOT_A_UNIT_MEMBER",
101
+ UNIT_INACTIVE = "RESPONDER_UNIT_INACTIVE",
102
+ /** Already on duty with ANOTHER unit; end that duty first. `details.activeDuty` names it. */
103
+ ALREADY_ON_DUTY = "RESPONDER_ALREADY_ON_DUTY",
104
+ NOT_ON_DUTY = "RESPONDER_NOT_ON_DUTY",
105
+ /** Membership: the user is not a Responder of the unit's organization and control centre. */
106
+ USER_NOT_ELIGIBLE = "RESPONDER_USER_NOT_ELIGIBLE",
107
+ ALREADY_A_MEMBER = "RESPONDER_ALREADY_A_MEMBER",
108
+ MEMBERSHIP_NOT_FOUND = "RESPONDER_MEMBERSHIP_NOT_FOUND",
109
+ /** The dispatch does not exist or is not for one of the caller's units (never says which). */
110
+ DISPATCH_NOT_FOUND = "RESPONDER_DISPATCH_NOT_FOUND",
111
+ /** The move is not one a responder may make from the current status. `details.currentStatus`. */
112
+ INVALID_STATUS_TRANSITION = "RESPONDER_INVALID_STATUS_TRANSITION",
113
+ REASON_REQUIRED = "RESPONDER_REASON_REQUIRED",
114
+ DECLINE_NOT_ALLOWED = "RESPONDER_DECLINE_NOT_ALLOWED",
115
+ MANUAL_ARRIVAL_NOT_ALLOWED = "RESPONDER_MANUAL_ARRIVAL_NOT_ALLOWED",
116
+ /** Completing needs the response report first (organization policy). */
117
+ REPORT_REQUIRED = "RESPONDER_REPORT_REQUIRED",
118
+ /** A report can only be written once the unit reached the scene. */
119
+ REPORT_NOT_ALLOWED = "RESPONDER_REPORT_NOT_ALLOWED",
120
+ /** The report changed since the version the client edited. `details.currentVersion`. */
121
+ REPORT_VERSION_CONFLICT = "RESPONDER_REPORT_VERSION_CONFLICT",
122
+ /** The incident is closed or archived, so its reports can no longer be amended. */
123
+ REPORT_LOCKED = "RESPONDER_REPORT_LOCKED",
124
+ /** A required report field or checklist item is missing. `details.missing`. */
125
+ REPORT_INCOMPLETE = "RESPONDER_REPORT_INCOMPLETE",
126
+ /** An attachment id is not a file the caller may link. */
127
+ ATTACHMENT_NOT_READABLE = "RESPONDER_ATTACHMENT_NOT_READABLE"
128
+ }
@@ -0,0 +1,7 @@
1
+ export * from './enums/responder.enums';
2
+ export * from './interfaces/responder-policy';
3
+ export * from './interfaces/responder';
4
+ export * from './interfaces/responder-dispatch';
5
+ export * from './constants/responder.const';
6
+ export * from './dtos/responder.dto';
7
+ export * from './utils/responder.util';
@@ -0,0 +1,144 @@
1
+ import { ResponseUnitDispatchStatus } from '../../dispatch/enums/response-unit-dispatch-status.enum';
2
+ import { ResponseUnitDispatchTransitionSource } from '../../dispatch/enums/response-unit-dispatch-transition-source.enum';
3
+ import { ResponderArrivalMethod, ResponderReportOutcome, ResponderTrackingMode } from '../enums/responder.enums';
4
+ /** The incident as a dispatched responder sees it. */
5
+ export interface ResponderIncidentSummary {
6
+ id: number;
7
+ /** `#<id>` - the reference the control room quotes. */
8
+ reference: string;
9
+ class: string;
10
+ emergencyType: string | null;
11
+ status: string;
12
+ priority: string;
13
+ categoryName: string | null;
14
+ typeName: string | null;
15
+ description: string | null;
16
+ /** Null when the incident has no usable coordinates. */
17
+ location: {
18
+ latitude: number;
19
+ longitude: number;
20
+ } | null;
21
+ physicalAddress: string | null;
22
+ isAnonymous: boolean;
23
+ /** Null when anonymous, or when the organization hides reporter contact from responders. */
24
+ reporter: {
25
+ name: string | null;
26
+ phoneNumber: string | null;
27
+ } | null;
28
+ /** The incident chat, when it has one. */
29
+ conversationId: string | null;
30
+ organizationId: number;
31
+ controlCentreId: number | null;
32
+ createdAt: string;
33
+ updatedAt: string;
34
+ }
35
+ /** Whether the responder's report exists, without its body. */
36
+ export interface ResponderReportState {
37
+ submitted: boolean;
38
+ reportId: number | null;
39
+ version: number | null;
40
+ submittedAt: string | null;
41
+ }
42
+ /** One dispatch of one of the responder's units, with its incident. */
43
+ export interface ResponderDispatch {
44
+ id: number;
45
+ reference: string;
46
+ incidentId: number;
47
+ responseUnitId: number;
48
+ responseUnitName: string;
49
+ responseUnitType: string | null;
50
+ status: ResponseUnitDispatchStatus;
51
+ statusChangedAt: string;
52
+ statusSource: ResponseUnitDispatchTransitionSource;
53
+ statusReason: string | null;
54
+ dispatchedAt: string;
55
+ acknowledgedAt: string | null;
56
+ enRouteAt: string | null;
57
+ onSceneAt: string | null;
58
+ completedAt: string | null;
59
+ cancelledAt: string | null;
60
+ rejectedAt: string | null;
61
+ arrivalSource: string | null;
62
+ /** What the dispatcher wrote when sending the unit. */
63
+ notes: string | null;
64
+ /** Distance from the unit to the incident at dispatch time. */
65
+ distanceMetres: number | null;
66
+ /** The statuses THIS caller may set next, already filtered by policy. */
67
+ allowedStatuses: ResponseUnitDispatchStatus[];
68
+ report: ResponderReportState;
69
+ incident: ResponderIncidentSummary;
70
+ }
71
+ /** Another unit sent to the same incident. */
72
+ export interface ResponderCoResponder {
73
+ dispatchId: number;
74
+ responseUnitId: number;
75
+ responseUnitName: string;
76
+ responseUnitType: string | null;
77
+ status: ResponseUnitDispatchStatus;
78
+ dispatchedAt: string;
79
+ }
80
+ /** `GET /responder/dispatches/:dispatchId`. */
81
+ export interface ResponderDispatchDetail extends ResponderDispatch {
82
+ otherUnits: ResponderCoResponder[];
83
+ /** What the responder recorded when arriving, if they did. */
84
+ arrivalEvidence: ResponderArrivalEvidence | null;
85
+ }
86
+ /** What a responder's arrival rested on - stored with the dispatch for the audit. */
87
+ export interface ResponderArrivalEvidence {
88
+ method: ResponderArrivalMethod;
89
+ latitude: number | null;
90
+ longitude: number | null;
91
+ accuracyMetres: number | null;
92
+ /** Distance from the fix to the incident, computed by the server. */
93
+ distanceMetres: number | null;
94
+ recordedAt: string | null;
95
+ reason: string | null;
96
+ }
97
+ export interface ResponderDispatchPage {
98
+ data: ResponderDispatch[];
99
+ meta: {
100
+ total: number;
101
+ page: number;
102
+ limit: number;
103
+ totalPages: number;
104
+ hasNextPage: boolean;
105
+ hasPreviousPage: boolean;
106
+ };
107
+ }
108
+ /** `GET|POST /responder/dispatches/:dispatchId/report`. */
109
+ export interface ResponderDispatchReport {
110
+ id: number;
111
+ reference: string;
112
+ dispatchId: number;
113
+ incidentId: number;
114
+ responseUnitId: number;
115
+ submittedByUserId: number;
116
+ /** Starts at 1; every amendment adds one. */
117
+ version: number;
118
+ summary: string;
119
+ actionsTaken: string | null;
120
+ outcome: ResponderReportOutcome;
121
+ personsContacted: string | null;
122
+ handoverTo: string | null;
123
+ followUpRequired: boolean;
124
+ followUpNotes: string | null;
125
+ remarks: string | null;
126
+ checklist: {
127
+ itemId: string;
128
+ checked: boolean;
129
+ }[];
130
+ attachmentIds: number[];
131
+ submittedAt: string;
132
+ updatedAt: string;
133
+ /** Whether the caller may still amend it (submitter, incident not closed). */
134
+ amendable: boolean;
135
+ }
136
+ /** `POST /responder/positions`. */
137
+ export interface ResponderPositionBatchResult {
138
+ accepted: number;
139
+ rejected: number;
140
+ /** Why individual samples were refused (`TOO_OLD`, `IN_FUTURE`, `INACCURATE`, `INVALID`). */
141
+ rejectedReasons: Record<string, number>;
142
+ responseUnitId: number | null;
143
+ trackingMode: ResponderTrackingMode;
144
+ }
@@ -0,0 +1,55 @@
1
+ import { ResponderReportField } from '../enums/responder.enums';
2
+ /** One item of the closure checklist an organization asks its responders to confirm. */
3
+ export interface ResponderChecklistItem {
4
+ /** Stable id, so an answer survives the label being reworded. */
5
+ id: string;
6
+ label: string;
7
+ required: boolean;
8
+ }
9
+ /**
10
+ * An organization's operational rules for its responders. Trusted configuration:
11
+ * served by clarion-organization, enforced by the services that own each rule.
12
+ */
13
+ export interface ResponderPolicy {
14
+ location: {
15
+ onDutyIntervalSeconds: number;
16
+ activeIntervalSeconds: number;
17
+ distanceFilterMetres: number;
18
+ maxAccuracyMetres: number;
19
+ staleAfterSeconds: number;
20
+ };
21
+ arrival: {
22
+ /** Within this distance of the incident a GPS arrival is accepted. */
23
+ radiusMetres: number;
24
+ /** Whether a responder outside the radius (or without a fix) may confirm arrival by hand. */
25
+ allowManualConfirmation: boolean;
26
+ manualReasonRequired: boolean;
27
+ };
28
+ dispatch: {
29
+ allowDecline: boolean;
30
+ declineReasonRequired: boolean;
31
+ };
32
+ report: {
33
+ /** The responder cannot mark the dispatch COMPLETED before submitting a report. */
34
+ requiredToComplete: boolean;
35
+ requiredFields: ResponderReportField[];
36
+ checklist: ResponderChecklistItem[];
37
+ minPhotos: number;
38
+ };
39
+ evidence: {
40
+ allowPhotos: boolean;
41
+ allowDocuments: boolean;
42
+ allowVideo: boolean;
43
+ maxImageMegabytes: number;
44
+ maxDocumentMegabytes: number;
45
+ maxVideoMegabytes: number;
46
+ };
47
+ reporterContact: {
48
+ /** Whether a responder sees the (non-anonymous) reporter's name and number. */
49
+ visible: boolean;
50
+ };
51
+ }
52
+ /** A partial override as stored on the organization; anything absent keeps the default. */
53
+ export type ResponderPolicyOverride = {
54
+ [K in keyof ResponderPolicy]?: Partial<ResponderPolicy[K]>;
55
+ };
@@ -0,0 +1,113 @@
1
+ import { ResponseUnitAvailability } from '../../response-unit/enums/response-unit/response-unit-availability.enum';
2
+ import { ResponderDutyEndReason, ResponderDutySessionStatus } from '../enums/responder.enums';
3
+ import { ResponderPolicy } from './responder-policy';
4
+ /** A unit as the responder app shows it: enough to pick it and to recognise it. */
5
+ export interface ResponderUnitSummary {
6
+ id: number;
7
+ name: string;
8
+ /** `Vehicle`, `Person` or `Team`. */
9
+ type: string;
10
+ /** Vehicle units: `Ambulance`, `Security`, ... */
11
+ vehicleType: string | null;
12
+ registrationNumber: string | null;
13
+ /** The unit's own phone (vehicle / person units); teams have none. */
14
+ phoneNumber: string | null;
15
+ capabilities: string[];
16
+ isActive: boolean;
17
+ /** The manual status the control room sets (`Operational`, `On Duty`, ...). */
18
+ operationalStatus: string | null;
19
+ /** From the manual status only; an active dispatch makes a unit ENGAGED in clarion-incident. */
20
+ availability: ResponseUnitAvailability;
21
+ organizationId: number;
22
+ controlCentreId: number | null;
23
+ station: {
24
+ name?: string | null;
25
+ address?: string | null;
26
+ } | null;
27
+ }
28
+ /** One stretch of duty: a responder staffing one unit. */
29
+ export interface ResponderDutySession {
30
+ id: number;
31
+ userId: number;
32
+ responseUnitId: number;
33
+ /** Copied at start so the record reads right after a rename. */
34
+ responseUnitName: string;
35
+ organizationId: number;
36
+ controlCentreId: number | null;
37
+ status: ResponderDutySessionStatus;
38
+ startedAt: string;
39
+ endedAt: string | null;
40
+ endReason: ResponderDutyEndReason | null;
41
+ endReasonText: string | null;
42
+ /** Who ended it - the responder, or the control-room user. */
43
+ endedByUserId: number | null;
44
+ }
45
+ export interface ResponderOrganizationSummary {
46
+ id: number;
47
+ name: string;
48
+ logo: string | null;
49
+ phoneNumber: string | null;
50
+ email: string | null;
51
+ countryCode: string | null;
52
+ }
53
+ export interface ResponderControlCentreSummary {
54
+ id: number;
55
+ name: string;
56
+ phoneNumber: string | null;
57
+ email: string | null;
58
+ logo: string | null;
59
+ }
60
+ /** `GET /responder/me` - everything the app needs to know who and where the responder is. */
61
+ export interface ResponderProfile {
62
+ userId: number;
63
+ organization: ResponderOrganizationSummary;
64
+ controlCentre: ResponderControlCentreSummary | null;
65
+ /** The units the responder may go on duty with (memberships), active ones first. */
66
+ units: ResponderUnitSummary[];
67
+ activeDuty: ResponderDutySession | null;
68
+ /** The organization's effective policy (defaults merged with its override). */
69
+ policy: ResponderPolicy;
70
+ /** The server's clock, so the app can tell how far off the phone's is. */
71
+ serverTime: string;
72
+ }
73
+ /** A responder linked to a unit, as the admin's unit screen lists them. */
74
+ export interface ResponseUnitResponder {
75
+ id: number;
76
+ responseUnitId: number;
77
+ userId: number;
78
+ organizationId: number;
79
+ controlCentreId: number | null;
80
+ createdByUserId: number | null;
81
+ createdAt: string;
82
+ /** The account, when clarion-authentication could be read; null otherwise. */
83
+ user: {
84
+ id: number;
85
+ name: string;
86
+ email: string | null;
87
+ phoneNumber: string | null;
88
+ } | null;
89
+ /** Set while this responder is on duty with THIS unit. */
90
+ activeDuty: {
91
+ sessionId: number;
92
+ startedAt: string;
93
+ } | null;
94
+ }
95
+ /** Internal: a user's units, duty and policy - for clarion-incident and clarion-response-tracking. */
96
+ export interface ResponderInternalUnits {
97
+ userId: number;
98
+ organizationId: number | null;
99
+ controlCentreId: number | null;
100
+ /** Units the user is a member of (whatever their status). */
101
+ responseUnitIds: number[];
102
+ activeDuty: {
103
+ sessionId: number;
104
+ responseUnitId: number;
105
+ startedAt: string;
106
+ } | null;
107
+ policy: ResponderPolicy;
108
+ }
109
+ /** Internal: who is on duty with a unit - for clarion-notification's dispatch pushes. */
110
+ export interface ResponderInternalUnitOnDuty {
111
+ responseUnitId: number;
112
+ userIds: number[];
113
+ }
@@ -0,0 +1,24 @@
1
+ import { ResponseUnitDispatchStatus } from '../../dispatch/enums/response-unit-dispatch-status.enum';
2
+ import { ResponderPolicy, ResponderPolicyOverride } from '../interfaces/responder-policy';
3
+ /**
4
+ * The organization's effective policy: the defaults with its override laid over
5
+ * them, part by part. Unknown keys in a stored override are ignored, so an old
6
+ * row can never smuggle a setting the code no longer knows into the app.
7
+ */
8
+ export declare function resolveResponderPolicy(override: ResponderPolicyOverride | null | undefined): ResponderPolicy;
9
+ /** Whether a responder may move a dispatch from `from` to `to`, before policy. */
10
+ export declare function canResponderTransitionDispatch(from: ResponseUnitDispatchStatus, to: ResponseUnitDispatchStatus): boolean;
11
+ /** The statuses a responder may set next, with the policy applied (no decline when it is off). */
12
+ export declare function responderAllowedDispatchStatuses(from: ResponseUnitDispatchStatus, policy: Pick<ResponderPolicy, 'dispatch'>): ResponseUnitDispatchStatus[];
13
+ /** What a responder's report is missing under the policy - field names and `checklist:<id>`. */
14
+ export declare function missingResponderReportItems(report: {
15
+ summary?: string | null;
16
+ actionsTaken?: string | null;
17
+ personsContacted?: string | null;
18
+ handoverTo?: string | null;
19
+ remarks?: string | null;
20
+ checklist?: {
21
+ itemId: string;
22
+ checked: boolean;
23
+ }[] | null;
24
+ }, policy: Pick<ResponderPolicy, 'report'>): string[];
@@ -1,2 +1,9 @@
1
1
  import { Role } from "../interfaces/role";
2
+ /**
3
+ * The responder app, for the people who staff a response unit. Each action is
4
+ * confined to the caller's own memberships, duty and unit by the service that
5
+ * owns it (clarion-organization, clarion-incident, clarion-response-tracking),
6
+ * so holding one says nothing about anybody else's unit.
7
+ */
8
+ export declare const RESPONDER_APP_PERMISSIONS: string[];
2
9
  export declare const ROLES_DATA: Role[];
@@ -22,5 +22,13 @@ export declare enum TrackingProviderCode {
22
22
  /** Generic WebSocket adapter (reserved). */
23
23
  GENERIC_WEBSOCKET = "GENERIC_WEBSOCKET",
24
24
  /** Generic HTTP polling adapter (reserved). */
25
- GENERIC_HTTP_POLLING = "GENERIC_HTTP_POLLING"
25
+ GENERIC_HTTP_POLLING = "GENERIC_HTTP_POLLING",
26
+ /**
27
+ * The responder app: the phone of the responder on duty with a unit reports
28
+ * the unit's position (`POST /tracking/responder/positions`). Inbound only -
29
+ * there is no connection to open, so the connector never runs a session
30
+ * for it. Used only for units with no enabled hardware tracker binding, so
31
+ * a vehicle's tracker and a crew member's phone never compete.
32
+ */
33
+ MOBILE_APP = "MOBILE_APP"
26
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grm-shared-library",
3
- "version": "1.1.241",
3
+ "version": "1.1.242",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",