diff --git a/docs/api/authentication.md b/docs/api/authentication.md index 2613e7f..a9b6d11 100644 --- a/docs/api/authentication.md +++ b/docs/api/authentication.md @@ -6,6 +6,8 @@ sidebar_position: 2 Resgrid as of the v4 version of the API uses the JWT (JSON Web Token) standard with OpenID Connect. You need to auth to the Resgrid API via a specific endpoint before you can call operations against the API. +A system-to-system integration that should not sign in as a person can use a [department API key](#department-api-keys) instead. + ## Connect Operation To Authenticate with the Resgrid API you need to submit a POST request to the the `v4/connect/token` endpoint. Once this is done you will have the data needed to make subsequent calls the the other functions on the Resgrid API. @@ -95,4 +97,56 @@ Example Response: "PreviousPageUrl":null, "NextPageUrl":null } -``` \ No newline at end of file +``` + + +## Department API keys + +Use a **department API key** when another system, rather than a person, calls Resgrid: a scheduling or case-management system that feeds in follow-up calls, a records system that reads calls, a CAD bridge. The key belongs to the department, not to a member, so there is no username or password to store in that system and nothing breaks when someone leaves. + +A department admin creates keys under **Security → API Keys** in the web app ([Security & Permissions](../web-app/security-permissions#api-keys)). Each key: + +- can only call the endpoints of the **scopes** you choose (below), and nothing else; +- has an **expiry date** (30 days to 2 years) after which it stops working; +- can be **revoked** at any time, which takes effect at once; +- can optionally be limited to **source addresses** (IP addresses or CIDR ranges); +- is shown **once**, when it is created. Resgrid stores only a keyed hash of it, so a lost key cannot be recovered: revoke it and create another. + +Send the key in the `X-Resgrid-ApiKey` header. There is no token exchange and no refresh step. Never put a key in a URL or query string, and do not send a bearer token with it. + +```bash +curl -X POST "https://api.resgrid.com/api/v4/Calls/SaveCall" \ + -H "X-Resgrid-ApiKey: rgk_XXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + -H "Content-Type: application/json" \ + -d '{ "Name": "Follow-up visit", "Nature": "Post-discharge check", "Priority": 1, "Type": "Follow-up", "IsPending": true, "ExternalId": "EHR-55120" }' +``` + +### Scopes + +| Scope | Endpoints (`api/v4/...`) | +|---|---| +| `calls.read` | `Calls/GetActiveCalls`, `Calls/GetCall`, `Calls/GetCalls`, `Calls/GetPendingCalls`, `Calls/GetAllPendingScheduledCalls`, `Calls/GetNewCallFieldPolicy` | +| `calls.create` | `Calls/SaveCall`, including pending (`IsPending`) and scheduled (`DispatchOn` / `DispatchOnUtc`) calls | +| `calls.update` | `Calls/EditCall`, `Calls/DispatchCallNow`, `Calls/UpdateScheduledDispatchTime` | +| `calls.close` | `Calls/CloseCall` | +| `reference.read` | `CallTypes/GetAllCallTypes`, `CallPriorities/GetAllCallPriorites`, `Dispatch/GetCallTemplates`, `Groups/GetAllGroups`, `Dispatch/GetRolesForCallGrid` (what you need to fill in a call and its dispatch list) | +| `units.read` | `Units/GetAllUnits`, `UnitStatus/GetAllUnitStatuses` | + +Give a key only the scopes it needs. A system that only feeds in pending calls needs `calls.create` (and `reference.read` if it looks up types, priorities, groups or roles). No other endpoint accepts a key, whatever its scopes: deleting calls, personnel, messages and settings are always out of reach. + +### What a key acts as + +A request made with a key acts for the key's department. Department-wide checks run as the department's managing user, narrowed to the key's scopes, so a call created with a key shows the managing user as the reporting user. Use `ExternalId` (or `ReferenceId`) to carry your own system's id. Departments using [Advanced Data Protection](../web-app/data-protection) receive the protected fields through the broker's encrypt-only lane, the same as other unattended integrations; reads return them redacted. + +### Errors + +| Response | Meaning | +|---|---| +| `401` | The key is missing, unknown, expired, revoked or used from an address it is not allowed from. Also returned by every endpoint a key cannot call. | +| `403` | The key is valid but does not have the scope this endpoint needs, or the request also carries a bearer token. | + +After repeated invalid keys from one address, further attempts from that address are refused for a few minutes. + +### Rotating a key + +Create the new key, switch the other system to it, check its **Last used** column in **Security → API Keys**, then revoke the old one. Every create and revoke is written to the [audit log](../web-app/security-permissions#audit-logs). diff --git a/docs/api/information.md b/docs/api/information.md index 202208d..3224381 100644 --- a/docs/api/information.md +++ b/docs/api/information.md @@ -16,10 +16,46 @@ The Resgrid API Exposes our Swagger documentation to showcase every call and ope | Area | Description | |------|-------------| -| **Authentication** | JWT/OpenID Connect token management | +| **Authentication** | JWT/OpenID Connect token management, and [department API keys](authentication#department-api-keys) for system integrations | | **Statuses** | Personnel and unit status operations | -| **Calls** | Dispatch call management | +| **Calls** | Dispatch call management, including [pending and scheduled calls](#pending-and-scheduled-calls) | | **Calendar** | Calendar events, types, and RSVP | | **Calendar Export** | iCal export, department feed subscriptions, and sync token management (see [Calendar Export API](calendar-export)) | | **Contact Verification** | Email and phone verification | | **Workflows** | Automated workflow management | + +## Pending and scheduled calls + +Another system (case management, scheduling, a referral line) can hand work to your dispatchers without paging anyone: create the call as **pending**. It is saved and numbered, nobody is notified, and it stays out of the active call lists and the field apps until a dispatcher sends it from **Pending Calls** in the web app or the Dispatch app. See [Pending and scheduled calls](../web-app/dispatch-calls#pending-and-scheduled-calls). + +An integration should use a [department API key](authentication#department-api-keys) with the `calls.create` scope rather than a member's login: + +```http +POST /api/v4/Calls/SaveCall +X-Resgrid-ApiKey: rgk_XXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +Content-Type: application/json + +{ + "Name": "Follow-up: post-discharge wellness check", + "Nature": "Clinic requests an in-person check within 24 hours.", + "Priority": 1, + "Type": "Follow-up", + "Address": "550 S Vermont Ave, Los Angeles, CA 90020", + "ContactName": "Client J.R.", + "ExternalId": "EHR-55120", + "IsPending": true +} +``` + +| Endpoint | Purpose | +|---|---| +| `POST Calls/SaveCall` with `"IsPending": true` | Create a pending call. `DispatchList` is optional and kept as the proposed recipients (empty = none, `"0"` = everyone); `DispatchOn` is ignored; the department's dispatch-list and dispatch-time requirements do not apply. Use `ExternalId` for your own case or ticket number. | +| `GET Calls/GetPendingCalls` | Pending calls, oldest first. A call's `State` is `8` while pending. | +| `PUT Calls/DispatchCallNow` | Body `{ "CallId": "123", "DispatchList": "U:5\|R:7" }`. Sends a pending call, or a scheduled call that has not gone out, right now. Leave `DispatchList` out to use the recipients already on the call. Returns 400 with a message when the call is not waiting or has nobody to send to. | +| `PUT Calls/EditCall` | Edits a pending call without notifying anyone. A future `DispatchOn` turns it into a scheduled call. | +| `PUT Calls/CloseCall` | Body `{ "Id": "123", "Type": 1, "Notes": "...", "SendNotification": true }`. Closes a call (close states 1–7). With `SendNotification`, everyone on a call that went out is told it closed: the personnel, groups and roles it was dispatched to, its units, and the incident command team. A pending call, or a scheduled call that never went out, notifies nobody. Returns 400 while the call has an active incident command: close the command first (the Incident Command app can close the call in the same step). | +| `GET Calls/GetAllPendingScheduledCalls`, `PUT Calls/UpdateScheduledDispatchTime` | Scheduled calls that have not been sent yet, and moving their dispatch time. | + +A **scheduled** call is created the same way without `IsPending`, with a future dispatch time: `DispatchOn` in the department's local time, or `DispatchOnUtc` in UTC (for example `"2026-10-07T14:30:00Z"`; it wins when both are sent). It goes out by itself within five minutes of that time, or earlier with `DispatchCallNow`. + +`Priority` is the id of one of your department's call priorities (`GET CallPriorities/GetAllCallPriorites`) and `Type` the name of a call type. Dispatch lists use `P:` personnel, `G:` groups, `R:` roles and `U:` units, separated by `|`. diff --git a/docs/api/map-icons.md b/docs/api/map-icons.md new file mode 100644 index 0000000..756cba6 --- /dev/null +++ b/docs/api/map-icons.md @@ -0,0 +1,148 @@ +--- +sidebar_position: 9 +--- + +# Map Icons API + +Map markers carry the icon a client should draw, and the map icon legend endpoint returns every icon a department's map can show. Both are part of the v4 API and are built from the same department data, so a client that draws its markers and its legend from them always matches the web map. For what the icons mean and how departments set them up, see [Icons by status and priority](../web-app/mapping#icons-by-status-and-priority), [Map icon legend](../web-app/mapping#map-icon-legend) and [Custom map icons](../web-app/mapping#custom-map-icons). + +## Endpoints Overview + +| Endpoint | Method | Auth | Description | +|----------|--------|------|-------------| +| `/api/v4/Mapping/GetMapDataAndMarkers` | GET | Bearer token, `Call_View` | The department map: markers for calls, units, stations, personnel, POIs and hydrants | +| `/api/v4/Mapping/GetUnitMapData` | GET | Bearer token, `Call_View` | One unit and the members seated in its roles | +| `/api/v4/Mapping/GetMapIconLegend` | GET | Bearer token, `Call_View` | Every icon the department's map can show, for an in-app legend | +| `/api/v4/TypeIcons/{key}` | GET | Anonymous | A department's uploaded icon (128 × 128 PNG); `?s={style}` adds a badge in the style's color | +| `/api/v4/TypeIcons/Pins/{base}-{style}` | GET | Anonymous | A built-in pin recolored to a style (32 × 37 PNG, tip at the bottom center) | + +Icon and pin URLs carry `v=` (the palette version) and are served with `Cache-Control: public, max-age=31536000, immutable`. A changed upload gets a new key and a changed palette a new `v`, so a cached image is never stale. + +## Marker icon fields + +Call (`Type` 0), unit (1) and personnel (3) markers carry four icon fields: + +| Field | Description | +|-------|-------------| +| `IconUrl` | The department's uploaded icon: the one uploaded for the current priority or status, else the type's or role's own icon with a badge in the color of `IconStyle`. Null when there is none | +| `PinIconUrl` | The built-in pin the type picked (or the default call, unit or person pin), recolored to `IconStyle` | +| `ImagePath` | The plain bundled icon name (`fire`, `ambulance`, `Call`, `Engine_Responding`, `Person_RespondingCall`), for clients without styled pins | +| `IconStyle` | The style of the priority or status (see [Styles](#styles)) | + +Draw `IconUrl` if set, else `PinIconUrl`, else the bundled `ImagePath` image. If a remote image fails to load, fall back to the next one. Stations, POIs and hydrants have no `PinIconUrl` or `IconStyle`; POIs and POI layers carry their own `IconUrl` when the POI type has an uploaded icon. + +## Styles + +A style is the color group of a status or priority meaning. Keys are stable wire values. + +| Key | Color | Covers | +|-----|-------|--------| +| `available` | `#2E9E44` | Available, Cleared, On Patrol, Completed, In Quarters | +| `dispatched` | `#B7791F` | Dispatched | +| `responding` | `#D93A1E` | Responding, En Route | +| `onscene` | `#1D5FD1` | On Scene, Made Contact, Investigating, At Patient, Searching | +| `transporting` | `#7A3EBE` | Transporting, Delivering, Loading, At Hospital | +| `returning` | `#0C8C99` | Returning | +| `staging` | `#8A6A3A` | Staging, Standby | +| `delayed` | `#607D8B` | On Break | +| `unavailable` | `#3D3D3D` | Unavailable, Maintenance, Not Responding | +| `low` / `medium` / `high` / `emergency` | `#2E8B3E` / `#B59A00` / `#E07800` / `#C8102E` | Call priorities by meaning | +| `unknown` | `#8A8A8A` | A status or priority with no meaning whose name suggests none, or a unit or member with no status | + +A member *On Unit* takes the style of their unit's latest status. + +## Get Map Icon Legend + +``` +GET /api/v4/Mapping/GetMapIconLegend +``` + +Returns the department's legend in the standard v4 envelope. Everything in it comes from the department's own setup: call types, priorities, unit types and their status sets, personnel statuses, roles, POI types, the built-in icon each type picked and every uploaded icon. Fetch it when the legend is opened rather than caching it, so a change shows on the next open. + +### Response data + +| Field | Description | +|-------|-------------| +| `StatusStyles` | The nine status styles in legend order, then `unknown`. Each has `Key`, `Color`, `Meanings` (status meaning values), `UnitStatuses` and `PersonnelStatuses` (the department's own status names in that style), `UnitPinIconUrl` and `PersonPinIconUrl` | +| `PriorityStyles` | `low`, `medium`, `high`, `emergency`, then `unknown`. Each has `Key`, `Color`, `Priorities` (the department's own priority names) and `CallPinIconUrl` | +| `Calls` | Calls with no type first (`Id` null), then each call type by name; one state per active priority | +| `Units` | Units with no type first (`Id` null), then each unit type by name; one state per status of the type's status set (`StatusSetName`, null for the built-in unit statuses) | +| `Personnel` | Members with no role icon first (`Id` null), then each role with an uploaded icon, in role order; one state per personnel status | +| `PoiTypes` | Each POI type: `PoiTypeId`, `Name`, `Color`, `PoiImage`, `ImagePath`, `Marker`, `IconUrl` | + +A row has `Id`, `Name`, `StatusSetName` (units), its own icon (`IconUrl`, `ImagePath`) and `States`. The `Name` of an `Id`-null row is a generic label in the server's language; clients should show their own localized label. A state has: + +| Field | Description | +|-------|-------------| +| `Id` | The stored priority id or status id | +| `Name` | The department's name for it | +| `Color` | The priority's or status's own hex color, or null | +| `IconStyle` | Its style; `unknown` when it has no meaning | +| `IconUrl`, `PinIconUrl`, `ImagePath` | The icon a marker of the row shows in it, as on [markers](#marker-icon-fields) | +| `IsVariant` | True when `IconUrl` was uploaded for this very priority or status | +| `FollowsUnitStatus` | True for the built-in *On Unit* personnel status: on the map the member takes their unit's style, and the gray pin given here applies only when there is no unit status to follow | + +### Example + +```json +{ + "Data": { + "StatusStyles": [ + { + "Key": "available", + "Color": "#2E9E44", + "Meanings": [0, 7, 19, 22, 23], + "UnitStatuses": ["Available", "In Quarters"], + "PersonnelStatuses": ["Standing By"], + "Priorities": [], + "UnitPinIconUrl": "https://api.resgrid.com/api/v4/TypeIcons/Pins/engine-available?v=1", + "PersonPinIconUrl": "https://api.resgrid.com/api/v4/TypeIcons/Pins/person-available?v=1", + "CallPinIconUrl": null + } + ], + "PriorityStyles": [ + { + "Key": "emergency", + "Color": "#C8102E", + "Meanings": [], + "UnitStatuses": [], + "PersonnelStatuses": [], + "Priorities": ["P1 Life threat"], + "UnitPinIconUrl": null, + "PersonPinIconUrl": null, + "CallPinIconUrl": "https://api.resgrid.com/api/v4/TypeIcons/Pins/call-emergency?v=1" + } + ], + "Calls": [ + { + "Id": 11, + "Name": "Structure Fire", + "StatusSetName": null, + "IconUrl": null, + "PinIconUrl": null, + "ImagePath": "fire", + "States": [ + { + "Id": 901, + "Name": "P1 Life threat", + "Color": "#ff0000", + "IconStyle": "emergency", + "IconUrl": null, + "PinIconUrl": "https://api.resgrid.com/api/v4/TypeIcons/Pins/fire-emergency?v=1", + "ImagePath": "fire", + "IsVariant": false, + "FollowsUnitStatus": false + } + ] + } + ], + "Units": [], + "Personnel": [], + "PoiTypes": [] + }, + "PageSize": 1, + "Status": "success" +} +``` + +The Responder, Unit and IC apps show this legend as a sheet over their maps; the web app shows it at **Mapping → Map Icon Legend**. Both are built by `MapIconLegendBuilder` from the department's `MapIconResolver`. diff --git a/docs/apps/big-board.md b/docs/apps/big-board.md index 1f5e796..f8579e4 100644 --- a/docs/apps/big-board.md +++ b/docs/apps/big-board.md @@ -6,6 +6,8 @@ sidebar_position: 5 Resgrid Big Board is a cross-platform application designed for **station displays, command centers, and situational awareness dashboards**. It features a fully customizable widget-based dashboard where users can add, remove, resize, and rearrange information panels to create the perfect overview for their operational needs. The app is primarily optimized for large screens — wall-mounted displays, desktop monitors, and tablets. + + ## Ideal Use Cases - **Station Wall Displays** — Mount a TV or monitor at a fire station or EMS base showing live personnel status, active calls, units, and a map with real-time positions. @@ -56,6 +58,18 @@ Displays all department units with their current status: - **Font size**: Adjustable from 4pt to 30pt - **Group filtering**: Hide specific groups - **Group sort order**: Custom weighted sorting +- **Status timer highlighting**: When the department has [unit status timers](../web-app/department-settings) set, units that have sat in a status too long move to the top in amber (warning) or red (alert) with the time in status. Acknowledged units keep their edge colour with a check mark; muted units show a muted bell and drop back into the list. + +#### Unit Alerts Widget +A compact panel listing only the units that are over a unit status timer, most urgent first. + +Dispatchers (anyone with the **Create Call** permission) can tap an alert to: +- **Acknowledge** it: the unit stays in the list, marked *Seen by* with their name, so everyone knows it is being handled. +- **Mute** it: the unit moves into a collapsed *Muted* section until the status changes, or for 15, 30 or 60 minutes. When a timed mute runs out, the unit comes back as acknowledged. +- **Add a note** explaining the situation, e.g. *"MUG not departed, technical malfunction reported."* or *"Second crew member unavailable, alternative ambulance dispatched."* A department can make the note a required reason with **Reason when acknowledging**, next to the unit status timers: for alerts only, or for warnings and alerts. Acknowledge and Mute then stay disabled until a reason is entered. +- **Clear** an acknowledgement to show the alert at full strength again. + +Acknowledgements are shared: every Big Board in the department updates right away. They only cover the status the unit was in. When the unit reports a new status, the acknowledgement ends. A unit acknowledged at the warning level comes back unacknowledged when it reaches the alert level. Status timers only highlight units on the board; they do not send pages or notifications. #### Calls Widget Displays active dispatch calls: @@ -69,6 +83,7 @@ Interactive **Mapbox GL** map with live pins: - **Toggle markers**: Show/hide calls, stations, units, personnel - **Show linked calls**: Display calls linked to the active call - **Hide labels**: Clean map view for distance viewing +- **Status and priority colors**: call pins take the color of the call's priority and unit and personnel pins the color of their status, with the department's [uploaded icons](../web-app/mapping#custom-map-icons) and status icons ([icons by status and priority](../web-app/mapping#icons-by-status-and-priority)) - **Custom center coordinates**: Set latitude and longitude for the default view #### Weather Widget @@ -164,6 +179,7 @@ Each widget has a dedicated configuration tab accessible from the Configure scre ### Real-Time Updates (SignalR) - Persistent WebSocket connection for real-time event updates - Personnel status/staffing, unit status, and call updates propagate instantly to all widgets +- Unit statuses are reloaded from the server on every update (never from a cached copy), and an update that arrives while a reload is already running triggers one more reload, so the board matches the web dashboard - Auto-reconnect with status display in the sidebar - Manual reconnect button available in the side menu diff --git a/docs/apps/calendar.md b/docs/apps/calendar.md index 0e07d86..96a2176 100644 --- a/docs/apps/calendar.md +++ b/docs/apps/calendar.md @@ -6,6 +6,8 @@ sidebar_position: 1 Resgrid provides a suite of purpose-built applications for emergency services and incident management. All applications are built with **React Native** and **Expo**, sharing a common technology foundation while being tailored to specific operational roles. + + ## Supported Platforms Every Resgrid application supports the following platforms from a single codebase: diff --git a/docs/apps/dispatch.md b/docs/apps/dispatch.md index 701cb78..0b7db4e 100644 --- a/docs/apps/dispatch.md +++ b/docs/apps/dispatch.md @@ -6,6 +6,8 @@ sidebar_position: 4 Resgrid Dispatch is a cross-platform application designed for **dispatchers and coordinators** operating from a dispatch center, station, or remote location. It provides a comprehensive multi-panel dispatch console with real-time resource management, live mapping, activity logging, push-to-talk voice, and integrated call management — all optimized for tablet and desktop use with responsive multi-column layouts. + + ## Ideal Use Cases - **Dispatch Centers** — Dedicated dispatch operators monitoring and managing calls, personnel, and units from a desktop or wall-mounted display. @@ -37,9 +39,9 @@ The dispatch console is the primary interface, providing a multi-panel view that #### Stats Header Real-time statistics banner displaying: -- **Active calls** count -- **Pending calls** count -- **Scheduled calls** count +- **Active calls** count (calls that have been dispatched) +- **Pending calls** count — calls saved but not yet dispatched, waiting for a dispatcher; tap to open **Pending Calls** +- **Scheduled calls** count — calls waiting for their dispatch time; tap to open **Scheduled Calls** - **Available units** count - **Available personnel** count - **On-duty personnel** count @@ -47,7 +49,7 @@ Real-time statistics banner displaying: - **Weather widget** (based on department map center coordinates) #### Active Calls Panel -- List of all active, pending, and scheduled calls with priority indicators +- List of active calls with priority indicators (pending and scheduled calls have their own screens, below) - **Call filter mode** — tap a call to filter all panels (units, personnel, notes, activity log) to show only data related to that call - Priority colour-coded call filter banner when active - Clear filter button to return to all-data view @@ -66,12 +68,15 @@ Real-time statistics banner displaying: #### Personnel & Unit Action Panels - When a personnel member or unit is selected, a dedicated actions panel appears in the activity log area -- **Change status** of selected personnel or unit +- **Change status** of selected personnel or unit. A unit's status starts on the call the unit is working, so the dispatcher does not pick the incident for every status: the call its latest status belongs to (unless that status cleared it), otherwise the one open call it is dispatched to. A call the unit's last clear ended does not count: the call that clear named or, when it named none (back in quarters at its station), every call the unit was sent to before it. A scheduled call counts once it has gone out or its dispatch time has passed. These are the same rules the server uses to [link a status to a call](../web-app/dispatch-calls#which-call-a-status-belongs-to). A unit with more than one call left starts on its last destination or the call selected on the console. The dispatcher can still pick another destination, and a status saved with no destination is still linked to the unit's call by the server - **Change staffing** of selected personnel - View detailed information about the selected resource #### Map Widget - Embedded **Mapbox GL** map with auto-fetched pins for personnel, units, stations, and calls +- Pins use the department's [uploaded icons](../web-app/mapping#custom-map-icons) for unit types, call types, POI types and personnel roles, in the browser, the desktop app and on tablets +- Call pins take the color of the call's priority and unit and personnel pins the color of their status ([icons by status and priority](../web-app/mapping#icons-by-status-and-priority)); pins redraw when a status or call changes, in the browser and desktop app as well as on tablets +- Role icons also show in the personnel panel, the combined resources list and the personnel list (inside each person's status ring), beside each role on a person's screen, and in the dispatch recipient picker beside every role and person - Expand to full-screen map view - Real-time position updates via SignalR @@ -99,15 +104,25 @@ Real-time statistics banner displaying: - **Create new calls** with: - Name, nature/description, priority, and type - Contact name and information - - **Five location input methods**: address search, GPS coordinates, [what3words](https://what3words.com), Plus Code search, and interactive map picker - - **Dispatch selection**: multi-select users, groups, roles, units, or everyone + - **Five location input methods**: address search, GPS coordinates, [what3words](https://what3words.com), Plus Code search, and interactive map picker. A call saved with a typed address that was never searched is geocoded by the server when it is created, so it still gets a location; a department that makes the location *required* needs a real point (search, coordinates or map pick) + - External ID and Reference ID (the referring system's case or ticket numbers) + - **Dispatch selection**: multi-select users, groups, roles, units, or everyone. The picker lists every unit, group, role and person whatever their status (it no longer shows *Everyone* alone when opened before the lists finish loading) + - The location map on New Call and Edit Call draws only the **available** units and personnel near the call, so it shows who can be sent; busy resources stay in the picker with their status for reassigning + - **Schedule dispatch** for a future time (web and desktop), or **Save as pending (do not dispatch yet)**: the call is saved and numbered, nobody is notified and the field apps do not see it; any recipients picked are kept as the proposed dispatch. The button becomes **Save Pending Call** and the call opens on **Pending Calls** - **Call detail view** with priority header, static map preview, and action buttons + - A pending call shows a *Pending — not yet dispatched* banner with **Dispatch**; a scheduled call shows *Scheduled for* its time with **Dispatch now** - Add notes, attach images, attach files, route to call in native Maps - Tabbed content: Info, Contact, Protocols, Dispatched resources, Timeline - - Close call (permission-gated) + - Close call (permission-gated) — **Notify everyone on the call** (on by default) tells the dispatched personnel, groups, roles, units and command team it closed; a call under an active incident command is refused with the reason shown - **Edit call** with the same form schema as creation - Web-specific implementations (`.web.tsx`) for call views, creation, and editing +### Pending and Scheduled Calls +Both are under **Calls** in the side menu (Pending Calls shows a count badge) and behind the console's tiles. They work like the web app's [pending and scheduled calls](../web-app/dispatch-calls#pending-and-scheduled-calls). +- **Pending Calls** — calls waiting for a dispatcher, oldest first, with search: number, name, type, priority, address and when it was received. **Dispatch** opens the recipient picker with any proposed recipients already selected; confirming sends the call and it moves to the active calls. **Cancel Call** closes it as Cancelled without notifying anyone. Pending calls come from *Save as pending* here or on the web, or from another system through the API (`IsPending`). +- **Scheduled Calls** — calls waiting for their dispatch time, with **Dispatch now** to send one early and **Reschedule** on the call. +- Both lists refresh when the server reports a call was added, changed or closed. + ### Additional Screens - **Calls list** — searchable paginated list of all calls - **Personnel list** — all department personnel with status information @@ -149,12 +164,14 @@ Real-time statistics banner displaying: ### Real-Time Updates (SignalR) - Persistent WebSocket connection for real-time event updates - Personnel status/staffing updates, unit status updates, call updates -- Auto-reconnect with background resume refresh -- Events trigger automatic data refresh across all console panels +- Auto-reconnect with background resume refresh; after any reconnect the console reloads units, calls and personnel, so changes made while the connection was down are not missed +- Events trigger automatic data refresh across all console panels. Unit statuses are always reloaded from the server (never from the device's saved copy), and a status change that arrives while a reload is already running triggers one more reload, so the console matches the web dashboard ### Run cards and recommendations -When the department uses [Run Cards](../web-app/run-cards), the New Call screen shows the recommended units and personnel for the call's priority and type (or dispatches them automatically), lets the dispatcher escalate alarm levels, and surfaces move-up recommendations. +When the department uses [Run Cards](../web-app/run-cards), the New Call screen shows the recommended units and personnel for the call's priority and type (or dispatches them automatically), lets the dispatcher escalate alarm levels, and surfaces move-up recommendations. The recommendation refreshes once the call has a location (from the address search, coordinates, what3words, Plus Code or the map picker); closest-unit selection needs that location, measures units in an **In Quarters** status from their station and adds the department's [turnout times](../web-app/run-cards#how-closest-unit-mode-measures-a-unit). + +**Adding resources to an active call** (**Dispatch additional resources** on the call, or the add button on a call in the console's Active Calls panel) shows the run card recommendation at the top of the recipient picker: what the call's run card still needs at its current alarm level, after counting the units and people already on the call, picked the same way as at creation (station-based or closest unit). **Apply recommendation** ticks them; nothing is sent until **Confirm**. When the call already covers its run card the picker says so, and anyone can still be added by hand. To dispatch the next level's resources in full, use **Strike Next Alarm**. ### Chat, moderation and the Assistant @@ -166,7 +183,13 @@ With `Records.Field.Dispatch` enabled, dispatchers can start the NERIS incident ### Deployments and pre-plans -Dispatchers see the department's **deployments** read-only (roster, window, identifiers, time-report status) so a call's crew and assignment are in view; time reports, usage and F-42 drafting are done from the Responder and Unit apps. A call's contact shows its **pre-plan** and **alert hazards** in the dispatch alert and on the Site Info tab. See [Deployment Finance](../web-app/business-ops/deployment-finance) and [Contacts](../web-app/contacts). +Dispatchers see the department's **deployments** read-only (roster, window, identifiers, time-report numbers and status) so a call's crew and assignment are in view; time reports, usage and F-42 drafting are done from the Responder and Unit apps. A call's contact shows its **pre-plan** and **alert hazards** in the dispatch alert and on the Site Info tab. See [Deployment Finance](../web-app/business-ops/deployment-finance) and [Contacts](../web-app/contacts). + +### Department terminology + +Names a department sets under [Terminology](../web-app/department-settings#terminology) replace the app's own labels: the side menu (Calls, Map, Personnel, Units, Contacts, Records), the console's **Units**, **Personnel**, **Notes** and **Map** panel titles, the **Calls** tab in a unit's or person's action panel, the Map and Records screen titles, and record types in Field Records. Labels that combine a module with other words, such as *Active Calls* or *Units on Call*, keep the app's wording. The names load when the app starts or a dispatcher signs in. + +![Dispatch with Units renamed Apparatus and Contacts renamed Pre-Plans](/img/apps/dispatch/terminology.png) ## Settings & Configuration diff --git a/docs/apps/relay.md b/docs/apps/relay.md index ab00254..c34ba60 100644 --- a/docs/apps/relay.md +++ b/docs/apps/relay.md @@ -16,6 +16,8 @@ Before you begin you will need the following: - A Windows 7 or newer computer with an Audio Line In connection or a usb audio sound card like StarTech.com 7.1 USB Sound Card - A scanner like WS1065 with an Audio Line Out connection + + ## Installing Resgrid Relay Download the latest release from Githib releases page. This will be a zip file that you need to unzip the file on your computer How to Unzip Files on Windows and we recommend putting the resulting folder in C:\ResgridRelay. diff --git a/docs/apps/responder.md b/docs/apps/responder.md index 0acfe0e..3fa6a13 100644 --- a/docs/apps/responder.md +++ b/docs/apps/responder.md @@ -6,6 +6,8 @@ sidebar_position: 2 Resgrid Responder is a cross-platform application designed for **individual first responder personnel**. It enables emergency responders to manage their status, view dispatch calls, communicate with team members, track their location in real-time, use push-to-talk voice channels, and coordinate through shifts and calendars — all from a single mobile interface. + + ## Ideal Use Cases - **On-Scene First Responders** — Volunteer firefighters, EMS personnel, or search & rescue team members who need to quickly update their status (responding, available, on-scene), view dispatch call details, and navigate to incident locations. @@ -29,6 +31,8 @@ Resgrid Responder is a cross-platform application designed for **individual firs - Set your **personnel status** from department-configured options (e.g., Available, Responding, On Scene, Not Responding) with optional destination (call or station) and notes - Set your **personnel staffing** level (e.g., On Shift, Available, Off Duty) with notes - GPS coordinates are automatically captured with each status change +- Your **current status** is outlined in red with a **Current** tag; when it has [next statuses](../configuration/custom-statuses#next-statuses) configured, the Home status buttons offer only those, with a **Show all statuses** link +- **Hold to set**: with the department's *Hold to Set Status* setting on, press and hold a status button for two seconds to set it (a fill and countdown show progress; letting go early cancels). Statuses that need a note or a destination open that step, and its Save button is held the same way - **Offline queue** persists status changes when offline and automatically retries when connectivity returns ### Home Dashboard @@ -37,7 +41,7 @@ Resgrid Responder is a cross-platform application designed for **individual firs - Quick-action status and staffing buttons ### Calls -- View all **active dispatch calls** with priority indicators and search +- View all **active dispatch calls** with priority indicators and search. Calls a dispatcher has saved as pending (not yet dispatched) never appear; they show up once they are sent - **Create new calls** with: - Name, nature/description, priority, and type - Contact name and information @@ -46,7 +50,7 @@ Resgrid Responder is a cross-platform application designed for **individual firs - **Call detail view** with tabbed content: info, contact, protocols, dispatched resources, and timeline - Add **notes**, **images**, and **file attachments** to calls - **Route to call** via native maps for turn-by-turn navigation -- Edit and close existing calls (permission-gated) +- Edit and close existing calls (permission-gated) — **Notify everyone on the call** (on by default) tells the dispatched personnel, groups, roles, units and command team it closed; a call under an active incident command is refused with the reason shown ### Personnel & Units - View all **department personnel** with status, staffing, group, and role information @@ -61,6 +65,9 @@ Resgrid Responder is a cross-platform application designed for **individual firs ### Map - Full **Mapbox GL** interactive map with pins for personnel, units, calls, stations, and POIs +- Pins use the department's [uploaded icons](../web-app/mapping#custom-map-icons) for unit types, call types, POI types and personnel roles (a person shows their first role, in role order, with an icon); personnel cards show that role icon beside the name +- Call pins take the color of the call's priority and unit and personnel pins the color of their status ([icons by status and priority](../web-app/mapping#icons-by-status-and-priority)) +- A **legend** button (top right of the map) opens the [map icon legend](../web-app/mapping#map-icon-legend) as a sheet: every icon the map can show, by call type and priority, unit type and status, and role and status, with the status and priority colors and stations and points of interest. The names and icons are the department's own (custom call types, priorities, statuses, unit types and status sets, and uploaded icons) and load fresh each time the legend opens. Members who can't see personal information don't see personnel pins, so their legend leaves out personnel too - **Real-time updates** via SignalR for live position tracking - **Heading-locked navigation mode** with tilted perspective for turn-by-turn orientation - Recenter button to snap camera to current GPS position @@ -118,12 +125,18 @@ When `Records.Field.Responder` is enabled, members author Records in the field ( With `Operations.Deployments` enabled the **Deployments** entry in the sidebar lists every deployment the member is rostered on (status, finance mode, window, incident and request numbers). Per deployment the member can: -- **Time** — start the day's **daily time report** and add their own entries (*Deployment / Standby / Travel*, from–to, unpaid break, notes); the app checks for overlaps and end-before-start before **Submit report**. Approval stays on the web. +- **Time** — start the day's **daily time report** and add their own entries (*Deployment / Standby / Travel*, from–to, unpaid break, notes); the app checks for overlaps and end-before-start before **Submit report**. Approval stays on the web. Reports are listed by the number the department issues them: `#3` with the built-in numbers, or its own format such as `DTR-2026-0003` when one is set under [Document numbering](../web-app/department-settings#document-numbering). - **Usage** — record **odometer, engine hours and fuel** readings for a unit by phase (*Mobilization, Standby, Incident, Return*); conflicting readings are marked *Needs review*. - **F-42** (Cal OES MARS, cost-recovery deployments) — draft the F-42 from the submitted time reports and **Validate** it against the portal rules; the handoff and every observation are web-only. Contacts attached to a call show the **pre-plan** (construction, shutoffs, water supply, access, hazards) and **site files** on the call's Site Info tab. See [Deployment Finance](../web-app/business-ops/deployment-finance), [Cal OES MARS](../web-app/business-ops/cal-oes-mars) and [Contacts](../web-app/contacts). +### Department terminology + +Names a department sets under [Terminology](../web-app/department-settings#terminology) replace the app's own labels for every member, in every language: the side menu (Contacts, Map, Notes, Calendar, Shifts, Checklists, Records, Work orders), the **People**, **Units** and **Calls** tabs on the home screen, those modules' screen titles, and record types in Field Records (the list, the new-record chooser and record headings). Anything not renamed keeps the app's own, translated label. The app loads the names when it starts or a member signs in and keeps the last ones it received while offline. + +![Responder with Contacts renamed Pre-Plans and Units renamed Apparatus](/img/apps/responder/terminology.png) + ## Settings & Configuration | Setting | Description | diff --git a/docs/apps/unit.md b/docs/apps/unit.md index 48311b3..0dba04a 100644 --- a/docs/apps/unit.md +++ b/docs/apps/unit.md @@ -6,6 +6,8 @@ sidebar_position: 3 Resgrid Unit is a cross-platform application designed for **vehicle and apparatus-level operations**. Where the Responder app is designed for individual personnel, the Unit app is designed to represent a **shared device mounted in or associated with a unit** (engine, ambulance, patrol car, etc.), providing crews with live dispatch data, voice channels, GPS tracking, and status reporting with minimal interaction required. + + ## Ideal Use Cases - **Apparatus-Mounted Tablets** — Mount a tablet in the cab of an engine, ambulance, or command vehicle as a dedicated dispatch terminal with live map, call details, and status controls. @@ -30,7 +32,9 @@ Resgrid Unit is a cross-platform application designed for **vehicle and apparatu ### Real-Time Map (Home Tab) - Full **Mapbox GL** interactive map as the primary home screen -- Renders map pins for personnel, units, stations, and calls with custom icons +- Renders map pins for personnel, units, stations, and calls with custom icons: the department's [uploaded icons](../web-app/mapping#custom-map-icons) for unit types, call types, POI types and personnel roles, on phones, tablets, the browser and the desktop app; the built-in pin when there is none or it cannot load +- Call pins take the color of the call's priority and unit and personnel pins the color of their status ([icons by status and priority](../web-app/mapping#icons-by-status-and-priority)) +- A **legend** button (bottom right of the map, above the recenter button) opens the [map icon legend](../web-app/mapping#map-icon-legend) as a sheet: every icon the map can show, by call type and priority, unit type and status, and role and status, with the status and priority colors and stations and points of interest. The names and icons are the department's own (custom call types, priorities, statuses, unit types and status sets, and uploaded icons) and load fresh each time the legend opens - **Dark/light theme** toggle for map style - **Camera follow modes**: normal tracking vs. locked navigation mode (heading-oriented, tilted perspective for turn-by-turn navigation) - **Recenter button** snaps camera back to current GPS position @@ -45,6 +49,9 @@ Resgrid Unit is a cross-platform application designed for **vehicle and apparatu - Status changes are sent to the API and propagated in real-time via SignalR - **Offline queue**: status changes made while offline are persisted and retried when connectivity returns - Colour-coded status card in the sidebar reflects the current state +- The unit's **current status** is outlined in red with a **Current** tag, in the sidebar buttons and in the status sheet +- **Next statuses**: when the current status has [next statuses](../configuration/custom-statuses#next-statuses) configured, only those are offered, with a **Show all statuses** link for anything out of sequence +- **Hold to set**: with the department's *Hold to Set Status* setting on, a status is set by pressing and holding its button for two seconds. A fill sweeps across the button with a countdown, and letting go early cancels. A status that needs nothing more saves straight away (a call destination is taken from the active or dispatched call); one that needs a note or a destination opens that step, whose submit button is held the same way ### Unit Role Assignments - Role management bottom sheet from the sidebar roles card @@ -58,7 +65,7 @@ Resgrid Unit is a cross-platform application designed for **vehicle and apparatu - Quick access to turn-by-turn navigation to the call location ### Calls -- **Call list** with search and pull-to-refresh +- **Call list** with search and pull-to-refresh. Pending calls (saved but not yet dispatched) never appear; they show up once a dispatcher sends them - **Create new calls** with: - Name, nature/description, priority, and type - Contact name and information @@ -67,7 +74,7 @@ Resgrid Unit is a cross-platform application designed for **vehicle and apparatu - **Call detail view** with tabs: Info, Contact, Protocols, Dispatched resources, and Timeline - Add **notes**, **images**, and **file attachments** to calls - **Route to call** in native Maps for turn-by-turn navigation -- Set as active call, edit, and close calls (permission-gated) +- Set as active call, edit, and close calls (permission-gated) — **Notify everyone on the call** (on by default) tells the dispatched personnel, groups, roles, units and command team it closed; a call under an active incident command is refused with the reason shown ### Push-to-Talk (PTT) Voice - **LiveKit WebRTC** integration for real-time voice channels @@ -153,12 +160,16 @@ With `Records.Field.Unit` enabled the crew authors **Unit activity** and run rec ### Deployments -With `Operations.Deployments` enabled the hidden **Deployments** tab lists the deployments the active unit is rostered on. The crew files the **daily time report** for the whole crew (every seat plus the unit itself: *Deployment / Standby / Travel*, from–to, unpaid break), records **usage readings** (odometer, engine hours, fuel) per phase, and — on Cal OES cost-recovery deployments — drafts and validates the **F-42**. Submitted reports are approved on the web and feed [Contractor Billing](../web-app/business-ops/contractor-billing) or [Cal OES MARS](../web-app/business-ops/cal-oes-mars). See [Deployment Finance](../web-app/business-ops/deployment-finance). +With `Operations.Deployments` enabled the hidden **Deployments** tab lists the deployments the active unit is rostered on. The crew files the **daily time report** for the whole crew (every seat plus the unit itself: *Deployment / Standby / Travel*, from–to, unpaid break), records **usage readings** (odometer, engine hours, fuel) per phase, and — on Cal OES cost-recovery deployments — drafts and validates the **F-42**. Submitted reports are approved on the web and feed [Contractor Billing](../web-app/business-ops/contractor-billing) or [Cal OES MARS](../web-app/business-ops/cal-oes-mars). Reports are listed by the number the department issues them: `#3` with the built-in numbers, or its own format such as `DTR-2026-0003` when one is set under [Document numbering](../web-app/department-settings#document-numbering). See [Deployment Finance](../web-app/business-ops/deployment-finance). ### Hardware GPS trackers Vehicles with a hardware tracker report position alongside (or instead of) the app; the web administrator sets the source priority. See [Hardware GPS Tracking](../web-app/unit-tracking). +### Department terminology + +Names a department sets under [Terminology](../web-app/department-settings#terminology) replace the app's own labels: the Map, Calls, Contacts and Notes tabs, the Checklists, Inventory and Records entries and their screen titles, and record types in Field Records (the list, the new-record chooser and record headings). The names load when the app starts or the crew signs in, and are cleared when someone signs out. + ## Settings & Configuration | Setting | Description | diff --git a/docs/configuration/adding-personnel.md b/docs/configuration/adding-personnel.md index fe3a0eb..232ace2 100644 --- a/docs/configuration/adding-personnel.md +++ b/docs/configuration/adding-personnel.md @@ -6,6 +6,8 @@ sidebar_position: 15 Adding Personnel is how you bring members of your department into the Resgrid system. Each person gets their own account with login credentials, allowing them to receive dispatch notifications, update their status and staffing, access the web and mobile applications, and participate in all department operations. Personnel can be added by creating new accounts or by inviting existing Resgrid users. + + ## Why Adding Personnel Matters Personnel are the foundation of your Resgrid department. Until members are added to the system, they cannot receive dispatch notifications, update their status, view calls, or interact with any department features. Properly onboarding personnel — including assigning them to groups and roles — ensures they receive the right notifications and have appropriate access to department resources. diff --git a/docs/configuration/adding-units.md b/docs/configuration/adding-units.md index 31d3d60..c1d659f 100644 --- a/docs/configuration/adding-units.md +++ b/docs/configuration/adding-units.md @@ -6,6 +6,8 @@ sidebar_position: 17 Units in Resgrid represent physical apparatus, vehicles, or teams that respond to calls. Examples include fire engines, ambulances, rescue trucks, command vehicles, or specialized teams. Each unit can have a type, be assigned to a station, have defined roles (positions), and maintain its own status independent of individual personnel. + + ## Why Adding Units Matters Units are a core component of dispatch operations. When a call comes in, dispatchers often dispatch units rather than (or in addition to) individual personnel. Each unit tracks its own state (Available, Responding, On Scene, etc.), can be staffed with personnel in specific roles, and appears on maps with location tracking. Without properly configured units, dispatch operations, unit tracking, and resource management will not function. diff --git a/docs/configuration/audio.md b/docs/configuration/audio.md index cb0b583..c457c63 100644 --- a/docs/configuration/audio.md +++ b/docs/configuration/audio.md @@ -6,6 +6,8 @@ sidebar_position: 12 Audio and Push To Talk (PTT) in Resgrid provides voice communication capabilities for your department. The feature includes **Voice Channels** for real-time push-to-talk communication between personnel and **Audio Streams** for broadcasting live audio feeds (such as scanner feeds or dispatch radio) within the Resgrid interface. + + ## Why Audio and PTT Matter During emergency operations, voice communication is often faster and more effective than text-based messaging. Push To Talk channels give your department a built-in voice communication system that works alongside your dispatch, mapping, and status features. Audio streams allow personnel to listen to relevant radio feeds directly from the Resgrid web application without needing separate equipment or apps. diff --git a/docs/configuration/call-import.md b/docs/configuration/call-import.md index b4b96d3..ab97317 100644 --- a/docs/configuration/call-import.md +++ b/docs/configuration/call-import.md @@ -4,98 +4,148 @@ sidebar_position: 4 # Call Import -Call Import allows your department to automatically create calls in Resgrid from incoming emails. This is commonly used to integrate with existing CAD (Computer-Aided Dispatch) systems, paging services, or alerting platforms that can send dispatch notifications via email. When an email arrives at your department's dispatch email address, Resgrid parses it according to the configured format and creates a new call automatically. +Call Import creates calls in Resgrid from dispatch emails. Your county or regional dispatch center, CAD system, paging service or alerting platform sends its dispatch email to your department's **dispatch import email** address. Resgrid reads each email with the format you choose, creates a call and dispatches it, the same as a call entered by hand. Calls can also come in by text message, set up separately under [Text messaging](text-messaging). + + ## Why Call Import Matters -Many departments receive dispatch alerts from a county or regional dispatch center via email or pager. Without Call Import, someone would need to manually enter each call into Resgrid. By configuring email-based call import, dispatches can flow automatically into the system, triggering notifications, mapping, and all other call-related features with no manual intervention. +Many departments receive dispatch alerts from a county or regional dispatch center via email or pager. Without Call Import, someone would need to enter each call into Resgrid by hand. With it, dispatches flow into Resgrid on their own and trigger notifications, mapping and every other call feature with no manual step. ## Scope -Call Import settings are department-wide and affect a single monitored email inbox. All calls imported from the email are created at the department level and are visible to all personnel (subject to normal permission rules). +Call Import settings are department-wide. Every email sent to the department's dispatch import email becomes a call for the whole department. Groups and stations can also have their own dispatch addresses; see [Group dispatch addresses](#group-dispatch-addresses). ## How It Works -1. Your department is assigned an internal dispatch email address (shown in the Call Settings page) -2. Alternatively, you configure an external email server (POP3) for Resgrid to monitor -3. When a new email arrives, Resgrid parses the email body using the selected format type -4. A new call is created in the system with the parsed data (name, nature, address, etc.) -5. Standard dispatch notifications are sent to the appropriate personnel +1. Your department has a **dispatch import email** address, shown at the top of **Call Settings**. +2. Your CAD, paging system or a mail rule sends or forwards dispatch emails to that address. Resgrid does not sign in to or check any other mailbox, so the email has to be sent to this address. +3. Resgrid reads the email with the **Email Type** selected on Call Settings (**Generic** until you choose one). +4. A new call is created from the parsed details (name, nature, address and so on). An address without coordinates is looked up on the map. An `.mp3` or `.amr` attachment is kept as the call's dispatch audio. +5. The call is dispatched to everyone in the department, and members with call notifications on are alerted. +6. A few email types recognise a follow-up email about a call that is still open and update that call instead of creating another. See [Email types](#email-types). + +An email the selected type cannot read is ignored: no call is created and the sender is not told. If a call has no nature or name after parsing, Resgrid uses the email's subject or body so the dispatch is not lost. ## Configuring Call Import -Navigate to **Department → Call Settings** to configure email-based call import. - -### Email Server Settings - -| Field | Required | Default | Description | -| --------------- | -------- | ------- | -------------------------------------------------------------------- | -| Hostname | Yes | — | The POP3 email server hostname (e.g., mail.yourdomain.com) | -| Username | Yes | — | The email account username | -| Password | Yes | — | The email account password | -| Port | No | 110 | The POP3 server port (typically 110 or 995 for SSL) | -| Use SSL | No | Off | Enable SSL/TLS for secure connection to the mail server | - -### Format Type - -The format type tells Resgrid how to parse the incoming email body into call fields. You must select the format that matches the system sending you dispatch emails. - -| Format Type | Description | -| ----------------------- | ---------------------------------------------------------- | -| Generic | Basic email parsing for simple email formats | -| Resgrid | Native Resgrid format | -| Generic Page | Standard paging format | -| Connect | Resgrid Connect integration format | -| Active911 | Active911 platform format | -| Four Part Pipe | Pipe-delimited four-part format | -| CAL FIRE ECC | California Fire ECC dispatch format | -| CAL FIRE SCU | California Fire SCU dispatch format | -| Carencro | Carencro Fire Department format | -| Grand Blanc | Grand Blanc Township format | -| Lowestoft | Lowestoft Coast Rescue format | -| Union Fire | Union Fire Company format | -| Parkland County | Parkland County format | -| Parkland County 2 | Parkland County alternate format | -| Brockport | Brockport Fire Department format | -| Hancock County | Hancock County format | -| Spotted Dog | Spotted Dog format | -| Port Jervis | Port Jervis Fire Department format | -| Yellowhead | Yellowhead County format | -| R&R | R&R format | -| Ottawa County | Ottawa County format | -| Ottawa Kingston Toronto | Ottawa/Kingston/Toronto regional format | +Navigate to **Department → Call Settings** (`/User/Department/CallSettings`). Only department administrators can open it. + +![Call import settings](/img/web-app/department/call-settings.png) + +| Setting | What it does | +|---|---| +| **Dispatch Import Email** | Your department's all-call address. Give it to your dispatch center or set your CAD or mail server to send dispatch emails to it. It cannot be changed on this page. | +| **Prune (Auto Close) Calls** | Closes imported calls automatically after the time below. See [Auto-close imported calls](#auto-close-imported-calls). | +| **Minutes to keep call open** | How long an imported call stays open before it is closed, 0 to 10080 minutes (7 days). Only used when **Prune** is ticked. | +| **Email Type** | The format of the emails you receive. Pick the one matching your dispatch center's email. See [Email types](#email-types). | +| **Call Numbering** | How every new call is numbered, imported or not. See [Call numbering](../web-app/department-settings#call-numbering). | + +Press **Update** to save. Saving keeps any other call settings you are not changing. + +### Email types + +Each type reads a specific email layout. Choose the one that matches what your dispatch center sends; if none does, try **Generic** first. + +| Email type | What it expects | Fills in | Updates an open call | +|---|---|---|---| +| **Generic** | Any email. | Name from the subject, nature from the body, both in the notes. Attached dispatch audio. | No | +| **Generic with AI enrichment** | Any email (only offered when your department has Enhanced AI). | The same call as Generic, then queued for AI enrichment. See [below](#generic-with-ai-enrichment). | No | +| **Resgrid** | A body of seven fields separated by `\|`. See [Resgrid format](#resgrid-format). | Incident number, type, priority, address, map page, nature, notes. | No | +| **Generic Page** | A subject containing `page`. | Name from the subject, nature from the subject and body. | No | +| **Connect** | The body's first two lines. | Name from the subject, nature from the first lines. | No | +| **Four Part Pipe** | A body of `\|`-separated parts, with `[LONGLAT:..]` coordinates in the third. | Name, coordinates, nature. | No | +| **Active911** | A subject containing `active` and a plain-text body of `KEY: value` lines (`CALL`, `ADDR1`, `ID`, `MAP`, `NARR` …; any case). | Name, address, incident number, coordinates, nature. | Yes, by incident number (`ID`); an email without an `ID` line always creates a new call | +| **R&R** | A plain-text body with `Address:`, `Call Type:` and `Incident Numbers:` lines. | Name, address, type, priority (matched by name), incident number. | Yes, by incident number | +| **OttawaCounty** | A subject containing `active` and a plain-text body with `CFS#`, `Address`, `CallType` and `Details` lines. | CFS number, address, type (when it matches one of your call types), nature. | No | +| **OttawaKingstonToronto** | A plain-text, one-line-space-separated page with an `ALPHA 512` marker. | Incident number, name, nature. | Yes, by incident number | +| **Parkland Cty** | A subject containing `Parkland County Incident` or `Incident Message`, with `Type:` and `Location:` lines. | Name, address, coordinates. | No | +| **Parkland Cty2** | As Parkland Cty, plus a `Date:` line and a priority letter (E, D, C, B, O or A). | Name, address, coordinates, logged time, priority. Also dispatches every unit. | Yes, a call with the same name and time; raises the priority and dispatches again on a second page | +| **CAL FIRE ECC** | A `;`-separated body starting with `Inc#`. | Incident number, type, address, coordinates, name, nature. | No | +| **CAL FIRE SCU** | A `;`-separated body with `Inc#`, `?q=` coordinates and `Map:` lines. Close notices are ignored. | Type, address, incident number, coordinates, map page, nature. | No | +| **Brockport** | `B:`, `L:`, `T:` and `X:` sections. | Incident number, address, type, name, nature. | No | +| **Hancock Cty** | A `,`-separated body: `(code), type, address or coordinates, // nature`. | Incident number, type, address, coordinates, nature. | No | +| **Carencro** | A subject containing `300` and `ALERT`. | Name from the subject, nature from the subject and body. | No | +| **Grand Blanc** | A subject containing `Page Received`. | Name from the subject, nature from the subject and body. | No | +| **Union Fire** | A subject containing `Perform Page`, with the address on the body's second and third lines. | Name, address, nature. | No | +| **Lowestoft** | A `,`-separated body: priority, nature, place, then any instructions, such as `3, Persons in water, Southwold, Muster at CRE`. | Priority (one of your priorities by name or number, else your default), nature, address (`, United Kingdom` is added when missing). | No | +| **Spotted Dog** | Any email with a subject. | Address from the subject, nature from the body. | No | +| **PortJervis** | Any email. A `La = … Lo = …` line becomes the call's coordinates. | Nature, coordinates. | No | +| **Yellowhead** | A `/`-separated body: name in the third part, address in the fourth. | Name, address. | No | + +"Updates an open call" means a later email about the same incident changes the call that is already open (among the department's ten most recent open calls) instead of creating another. Every other type creates a new call for each email. + +**Priority when the email names none.** A call gets your department's default call priority. With custom call priorities and none marked as the default, it gets your priority whose **Meaning** is *High* (see [Types](../web-app/types-configuration#classes-and-meanings)); with neither, it gets the built-in High priority. Text message and voice imports use the same rule. :::tip Choosing a Format -If your dispatch provider is not listed, try the **Generic** or **Generic Page** format first. These formats attempt to extract basic call information from standard email layouts. If the parsing does not produce accurate results, contact Resgrid support to request a custom format for your dispatch system. +If your dispatch provider is not listed, try **Generic** first: it accepts any email. If you control the email your system sends, use the **Resgrid** format for the most complete calls. If neither produces usable calls, contact Resgrid support to request a format for your dispatch system. ::: -### Email Pruning +### Resgrid format + +Use this format when you can control the email your CAD or alerting system sends. The body is seven values separated by the pipe (`|`) character: + +``` +ID | TYPE | PRIORITY | ADDRESS | MAPPAGE | NATURE | NOTES +``` + +| Value | Meaning | +|---|---| +| **ID** | The incident number from your CAD. Can be empty or `0000`. | +| **TYPE** | The incident type, such as `MEDICAL` or `FIRE`. When it matches one of your [call types](types), case aside, the call is tagged with that type; other text is kept as sent. Can be empty. | +| **PRIORITY** | With custom call priorities, the priority's name, such as `Structure Fire` (case does not matter). With the built-in priorities, the name or number: Low = 0, Medium = 1, High = 2, Emergency = 3. Anything else uses your department's default priority. Can be empty. | +| **ADDRESS** | The full address (street, city, state, zip). Required. | +| **MAPPAGE** | Your map book page. Can be empty. | +| **NATURE** | Why the call exists, such as `Fully involved 2 story residential structure`. Required. | +| **NOTES** | Anything else. Can be empty. | + +Leave a value empty with a space between the pipes: + +``` +| MEDICAL | 3 | 155 Main St. Carson City, NV 89701 | | 55 Y/O Male, Chest Pain, Diaphoretic, Conscious and abnormal breathing | +``` + +If fewer than six values arrive, the call is still created from the whole body, with a warning in its notes. Every Resgrid-format email creates a new call. -Email pruning automatically cleans up processed emails from the monitored inbox to prevent reprocessing. +### Generic with AI enrichment -| Field | Required | Description | -| -------------------- | -------- | ------------------------------------------------------------- | -| Prune Email Calls | No | Enable automatic deletion of processed emails | -| Minutes Till Prune | No | How many minutes after processing to delete the email | +Departments with the Enhanced AI add-on see this extra type and an **AI Dispatch settings** link under the list. The call is created exactly as with **Generic**, so dispatch is never delayed. The new call is then queued for AI enrichment, which can fill in details from the email according to your AI Dispatch settings. Follow-up emails are not enriched. A department that loses Enhanced AI keeps importing, because the call is built the same way as Generic. -## Internal Dispatch Email +### Auto-close imported calls -Each department is assigned an internal dispatch email address that can be used to forward emails to Resgrid. This address is displayed on the Call Settings page. You can configure your CAD or alerting system to send emails directly to this address as an alternative to configuring POP3 monitoring. +With **Prune (Auto Close) Calls** ticked, an open call that came in by email, text message or audio import is closed once it has been open longer than **Minutes to keep call open**. Calls entered by hand are never closed this way. + +- The check runs every hour, so a call can stay open up to an hour past its time. +- The closed call gets the note *Call automatically closed by the system.* and is recorded as closed by the department's managing user. +- Leave **Prune** unticked if your members close imported calls themselves. + +## Group dispatch addresses + +Each group or station can have its own **dispatch email** and **message email**, set on the group (see [Groups & stations](../web-app/groups-stations)): + +- Email to a group's **dispatch email** creates a call dispatched only to that group and its sub-groups. It is read with the department's **Email Type**, the same way as the department address, and a follow-up email updates an open call for the types that do so. +- Email to a group's **message email** sends a message, not a call, to that group and its sub-groups. + +## Mailbox (POP3) monitoring + +Resgrid does not sign in to an outside mailbox to collect dispatch emails. If your dispatch emails arrive in a mailbox you own, set a forwarding rule in that mailbox to send them to your dispatch import email. A mailbox your department configured with Resgrid in the past is kept on record but is not checked. ## How Imported Calls Are Used -Once a call is imported, it behaves identically to a manually created call: -- It appears on the dispatch dashboard and maps -- Notifications are sent to dispatched personnel -- It can be updated, closed, or deleted like any other call -- It shows up in reports and logs +Once a call is imported, it behaves like a call entered by hand: + +- It appears on the dispatch dashboard and maps. +- Notifications are sent to dispatched personnel. +- It gets the next call number from your department's [call numbering](../web-app/department-settings#call-numbering). +- It can be updated, closed or deleted like any other call, and closes on its own if auto-close is on. +- It shows up in reports and logs. ## Common Errors and Resolutions -| Error | Resolution | -| ------------------------------------------ | --------------------------------------------------------------------------------- | -| Calls not being imported | Verify the hostname, username, password, port, and SSL settings are correct | -| Calls imported with missing data | Check that the correct format type is selected for your dispatch email format | -| Duplicate calls being created | Enable email pruning to prevent the same email from being processed twice | -| Connection timeout | Verify the mail server is accessible and the port is not blocked by a firewall | -| SSL/TLS errors | Ensure the Use SSL setting matches your mail server requirements (port 995 for SSL) | +| Problem | Resolution | +|---|---| +| No calls are created | Check that the email is sent (or forwarded) to the exact dispatch import email shown on Call Settings, not to another mailbox. Then check the **Email Type**: an email the selected type cannot read is ignored. Switch to **Generic** to confirm emails are arriving. | +| Calls are created with missing or wrong details | Select the email type that matches your dispatch emails. For an address without coordinates, check that the address is complete enough to find on the map. | +| Every page creates a new call (duplicates) | Most email types create a call for each email. If your CAD sends updates, use a type that updates an open call (Active911, R&R, OttawaKingstonToronto, Parkland Cty2), or have your CAD send only the first page. **Prune (Auto Close) Calls** closes the extra calls after the set time. | +| Imported calls stay open | Tick **Prune (Auto Close) Calls** and set **Minutes to keep call open**. Calls close within an hour after that time. | +| The priority or type is not set | For the Resgrid format, send the name of one of your call priorities and call types. A priority number (0 to 3) only works with the built-in priorities. | diff --git a/docs/configuration/custom-statuses.md b/docs/configuration/custom-statuses.md index 7e644df..d896e2c 100644 --- a/docs/configuration/custom-statuses.md +++ b/docs/configuration/custom-statuses.md @@ -8,6 +8,8 @@ Custom Statuses and Staffing allow you have your own actions for personnel and u You can have Custom Statuses for Personnel Actions (Statuses), Personal Staffing Levels and for each Unit Type defined in the system. + + ## Default Statuses and Staffing Levels Resgrid default custom Statuses and Staffings are as follows @@ -53,7 +55,7 @@ Unit Statuses are actions your Units (Apparatuses or Teams) are currently or abo ### Base Status Types -When you are creating your own Custom Statuses for Both Personnel and Units you can select a 'base' type. This allows Resgrid to 'understand' the meaning of what the statuses are in your organization back to ones that Resgrid knows. For example if you have a Unit status that is "Lunch" Resgrid doesn't know what that means and this cannot perform automatic actions against or with that status. But if you assign the base status of "Lunch" to "Unavailable" Resgrid knows that the unit in the custom "Lunch" status is not available to respond to a call. +When you are creating your own Custom Statuses for Personnel, Units and Staffing Levels you can select a 'base' type (its meaning). This allows Resgrid to 'understand' the meaning of what the statuses are in your organization back to ones that Resgrid knows. For example if you have a Unit status that is "Lunch" Resgrid doesn't know what that means and this cannot perform automatic actions against or with that status. But if you assign the base status of "Lunch" to "Unavailable" Resgrid knows that the unit in the custom "Lunch" status is not available to respond to a call. Here are the current Base Statuses that you can assign to your own Custom Statuses. @@ -71,6 +73,61 @@ Here are the current Base Statuses that you can assign to your own Custom Status | Returning | Status equates to returning from a call to a station | | Staging | Status equates to being staged at a call location or station | | Unavailable | Status equates to being Out of Service; unable to take calls | +| En Route | Status equates to traveling to an assignment on a routine (non-emergency) basis | +| Transporting | Status equates to transporting a patient, subject or cargo | +| Delivering | Status equates to delivering goods or supplies | +| At Patient | Status equates to being with a patient or search subject | +| At Hospital | Status equates to being at a hospital or receiving facility | +| Searching | Status equates to actively searching an assigned area | +| Loading | Status equates to loading or picking up before transport | +| Standby | Status equates to being held in reserve or on standby | +| On Patrol | Status equates to patrolling while available for calls | +| Maintenance | Status equates to being out of service for maintenance | +| On Break | Status equates to a rest or meal break (delayed, still dispatchable) | +| Completed | Status equates to a finished task; becoming available | +| In Quarters | Status equates to Available **at the unit's station**: closest-unit dispatch measures the unit from its station instead of its GPS and adds the in-quarters turnout time | + +Cleared, On Patrol, Completed and In Quarters count as available like Available does. Returning counts as busy: for a unit that is heading back but can already take a call, use **Available** instead. + + + +#### Base types and call automation + +Resgrid reads a unit status by its base type when it closes calls, releases units and links statuses to calls, so set one on every unit status your crews use. A status left on **None** is ignored by the rules below (for linking it never counts as a clear). + +| What happens | Base types that count | +| --- | --- | +| **Release statuses leave the unit alone.** When a call is closed, or a unit is taken off it, the unit call release status is only set on units still working the call. A unit already back in service or taken out of service keeps its status. | Available, Cleared, Completed, On Patrol, In Quarters (back in service); Unavailable, Not Responding, Maintenance (out of service); On Break | +| **The unit has finished with the call.** With [Close call when last unit clears](../web-app/dispatch-calls#closing-a-call-automatically) on, the call closes when its last unit moves into one of these from a status that was working the call. | Available, Cleared, Completed, On Patrol, In Quarters; Unavailable, Not Responding, Maintenance | +| **The unit cleared, for linking statuses to calls.** A status set without choosing a call goes on the call the unit is working (see [Which call a status belongs to](../web-app/dispatch-calls#which-call-a-status-belongs-to)). After one of these the next status is not carried onto that call, and after one that names no call (back in quarters at the station) it is not put on any call the unit was sent to before it. Personnel statuses work the same way. | Available, In Quarters, Completed, On Patrol, Cleared, Returning; Unavailable, Not Responding, Maintenance | +| **Still working the call.** These never close a call and are released when the call closes. | Responding, Dispatched, En Route, On Scene, Made Contact, Investigating, At Patient, Transporting, At Hospital, Staging, Standby, Searching, Loading, Delivering, Returning | + +For an ambulance set, for example: *Out of Service* → **Unavailable** or **Maintenance**, *Radio Available* → **Available**, *At Station* → **In Quarters**, *On Scene* → **On Scene** or **At Patient**, *Departing to Hospital* → **Transporting**, *Arrived Hospital* → **At Hospital**. + + + +#### Meanings are what Resgrid reads + +The base type is the option's **meaning**, and Resgrid goes by the meaning, never by the button text. Availability for dispatch recommendations and closest-unit run cards, the status set on [dispatch and release](../web-app/department-settings#unit-status-on-dispatch-and-release), notification rules, check-in timers, staffing notification muting, reports, SMS replies and the apps all use it. An option left on **None** is unknown to all of them. The built-in statuses already have a meaning. + +The Custom Statuses list marks sets with options that have no meaning (**N without a meaning**), and the set's edit page shows a **Meaning** column, suggests meanings from the button names and has a **Use suggested meanings** button. Review the suggestions, then press **Update** to save them. See [Status meanings](../web-app/custom-statuses#status-meanings). + + + +#### Staffing level meanings + +Staffing levels have a meaning too, picked from their own list. The built-in staffing templates come with it filled in. + +| Staffing meaning | Description | Counts as | +| ---------------- | ----------- | --------- | +| None | No system meaning; the level is a label only | Unknown | +| Available | The person is available to respond | Available | +| Delayed | The person can respond but will be delayed | Delayed | +| Unavailable | The person is not available to respond | Unavailable | +| Committed | The person is committed to another assignment | Committed | +| On Shift | The person is on shift, at their station or post | Available | +| Off Duty | The person is off duty and not expected to respond | Unavailable | +| On Call | The person is off site but available when called | Available | ## Creating and Editing Custom Levels @@ -97,13 +154,31 @@ The Options Table in the page defines the buttons your users will see. You can a | Button Text | The Text of the Button and the Text shown in Reports | | Button Color | Color of the button also the Color of Text in Report | | Text Color | Color of the Button Text (choose something high contrast) | -| Base Type | Does this Custom Status equate to a Base Status Type above | +| Meaning | The option's meaning (base type): a Base Status Type above, or for staffing levels a [staffing meaning](#staffing-meanings) | | Require GPS | Does this status require GPS Coordinates (only for mobile) | | Detail Type | Can you select what Call and/or Station for this status | | Note Type | Do you want to allow an optional note or require one | Order Defines the order in which the buttons will appear on any page or list. They order for LOWEST to HIGHEST number and default to the order in which they were added originally. + + +### Next Statuses (status flow) + +Each option can name the statuses that logically follow it. Save the set first, then click **Edit** on an option and tick its **Next statuses**. For example, an ambulance set might use: + +| Current status | Next statuses | +| -------------- | --------------------------------------------- | +| Departed | On Scene | +| On Scene | To Hospital, To Station (In Quarters), Out of Service | +| To Hospital | At Hospital | + +While a status with next statuses is current, the Unit and Responder apps show only those buttons, in your set's order. The current status stays visible with a red outline and a **Current** tag. A **Show all statuses** link under the buttons brings back the rest for anything out of sequence, such as a breakdown on the way to a call. Leave every box unchecked on an option to offer all statuses after it. + +Next statuses only change what the apps offer. The server still accepts any status, so dispatchers can set any status from the website or the Dispatch app, and the apps fall back to the full list when the current status is not in the set. The set's edit page lists each option's next statuses in the **Next statuses** column. Staffing levels have no sequence, so they don't have this setting. + +To make crews confirm a status with a press and hold instead of a tap, turn on **Hold to Set Status** under [Dispatch Settings](department-settings#dispatch-settings). + :::warning Updating or Removing Statuses and Staffing When you update or remove a custom status this can impact the Reset To department setting where you can pick a time to reset Statuses and Staffings to a baseline. Also users who have custom Staffing level changes will also need to update theirs to ensure it's still correct. Make sure after you change your Personnel Statuses or Staffing Levels that you also update your Department Settings and let users know to check/update their own personal Staffing Level scheduled changes. ::: diff --git a/docs/configuration/department-settings.md b/docs/configuration/department-settings.md index c7637cd..7b98278 100644 --- a/docs/configuration/department-settings.md +++ b/docs/configuration/department-settings.md @@ -6,6 +6,8 @@ sidebar_position: 2 Department Settings is the central configuration hub for your Resgrid department. These settings control department-wide behavior including time display, personnel sorting, map configuration, status/staffing resets, dispatch behavior, module visibility, and more. Changes made here affect every user in your department. + + ## Why Department Settings Matter Department Settings define the global behavior and defaults for your entire organization. They control how data is displayed, how automated resets work, how dispatch interacts with shifts and groups, and which modules are available to your users. Misconfigured settings can lead to incorrect time displays, missed notifications, mapping issues, or features being unavailable to your team. @@ -78,10 +80,12 @@ The staffing reset feature automatically resets all personnel staffing levels to | --------------------- | ------------------ | ------------ | ---------------------------------------------------- | | Enable Staffing Reset | No | Off | Turns on the daily automatic staffing reset | | Time to Reset | Yes (if enabled) | — | The time of day (in department time zone) to reset | -| Reset Staffing To | Yes (if enabled) | Unavailable | The staffing level to set all personnel to | +| Reset Staffing To | Yes (if enabled) | Unavailable | A staffing [meaning](custom-statuses#staffing-meanings) or one of your staffing levels to set all personnel to | + +Pick a meaning (for example *Unavailable*) and the reset uses whichever of your levels has that meaning when it runs, so it keeps working after you rename or replace levels. :::warning Staffing Reset and Custom Staffing -When you update or remove custom staffing levels, make sure to also update the Reset Staffing To value here. If the configured reset staffing level no longer exists, the reset may not function as expected. Also notify your personnel to update any personal scheduled staffing changes they have configured. +A value saved before meanings existed, or a level you have since deleted, shows as *(saved earlier, no longer offered)* with a warning under it. The reset then uses, in order: your level with the same meaning; a level without a meaning whose name matches (for example *Unavailable*) or suggests the same meaning; otherwise the saved value as before. When nothing fits, the warning says the reset changes nobody. Pick a meaning or one of your levels and save to clear the warning. Also notify your personnel to update any personal scheduled staffing changes they have configured. ::: ## Status Reset @@ -92,7 +96,9 @@ Similar to staffing reset, the status reset automatically resets all personnel s | -------------------- | ------------------ | ----------- | ---------------------------------------------------- | | Enable Status Reset | No | Off | Turns on the daily automatic status reset | | Time to Reset | Yes (if enabled) | — | The time of day (in department time zone) to reset | -| Reset Status To | Yes (if enabled) | Standing By | The status to set all personnel to | +| Reset Status To | Yes (if enabled) | Available | A status [meaning](custom-statuses#status-meanings) or one of your statuses to set all personnel to | + +A status saved before meanings existed, or one since deleted, follows the same rules as the staffing reset above. ## Staffing Suppression @@ -101,7 +107,7 @@ Staffing suppression allows you to prevent notifications from going to personnel | Setting | Required | Description | | ----------------------------- | -------- | -------------------------------------------------------- | | Enable Staffing Suppress | No | Enables the suppression of notifications | -| Staffing Levels to Suppress | Yes (if enabled) | Select which staffing levels should be suppressed | +| Staffing Levels to Suppress | Yes (if enabled) | Select which staffing levels should be suppressed. Pick a meaning (*Any "Off Duty" status*) to suppress every staffing level with that [meaning](custom-statuses#staffing-meanings) | ## Dispatch Settings @@ -116,10 +122,16 @@ Dispatch settings control how the dispatch system interacts with shifts, groups, | Unit Dispatch Also Dispatch to Assigned Personnel | Off | When dispatching a unit, also notify personnel assigned to unit roles | | Unit Dispatch Also Dispatch to Group | Off | When dispatching a unit, also notify the unit's station group | | Personnel On Unit Set Unit Status | Off | When personnel on a unit change status, update the unit status accordingly | +| Hold to Set Status | Off | In the Unit and Responder apps, crews press and hold a status button for two seconds to set it instead of tapping it and then pressing Next or Submit. A status that needs a note, or a destination the app can't fill from the active call, still opens that step | +| Close Call When Last Unit Clears | Off | An active call closes on its own when the last unit dispatched to it reports back in service or out of service. See [Closing a call automatically](../web-app/dispatch-calls#closing-a-call-automatically) | + +The **unit call release status** (and its per-unit-type overrides) is set on the units still working a call when it is closed or they are taken off it. A unit already back in service, out of service, unavailable or on a break, or working another open call, keeps its status: closing a call never puts a unit that was taken out of service back in the dispatchable pool. Custom statuses are read by their [base type](custom-statuses), so give an *Out of Service* status the base type **Unavailable** or **Maintenance**. + +The **unit call dispatch status** and **unit call release status** are picked by meaning: **Default**, **Leave the unit's status unchanged**, or a status meaning such as *Dispatched* or *En Route*. Each unit then gets the first option of its own unit type's status set with that meaning, so one setting works for unit types with different custom statuses. Default is *Dispatched*, else *Responding*, else *En Route* on dispatch and *Cleared*, else *Available*, else *In Quarters* on release (the built-in *Responding* and *Released* for unit types without custom statuses). The page lists any unit type whose status set has no option with the meaning; its units keep their status. See [Unit status on dispatch and release](../web-app/department-settings#unit-status-on-dispatch-and-release). ## Mapping Settings -These settings control how long personnel and unit location data remains visible on maps. +These settings control how long personnel and unit location data remains visible on maps, and which Mapbox base map style every department map uses. | Setting | Default | Description | | ---------------------------------------- | ------- | ------------------------------------------------------------------------ | @@ -127,6 +139,8 @@ These settings control how long personnel and unit location data remains visible | Unit Location TTL | — | How long unit location pins remain on the map | | Personnel Allow No-Location Overwrite | Off | A status update without GPS can overwrite a previous status that had GPS | | Unit Allow No-Location Overwrite | Off | A unit state without GPS can overwrite a previous state that had GPS | +| Day Map Style | Automatic (Streets) | Mapbox base map for the website and for the apps in light mode: Streets, Outdoors, Light, Dark, Satellite, Satellite with Streets, Navigation Day, Navigation Night, or one of 20 Mapbox gallery community styles (Blueprint, Moonlight, North Star and others) | +| Night Map Style | Automatic | Base map the apps use in dark mode; Automatic follows the day style (Dark for road maps, Navigation Night for Navigation Day, unchanged for Outdoors, satellite and community styles) | ## Module Settings diff --git a/docs/configuration/distribution-lists.md b/docs/configuration/distribution-lists.md index 1a25366..0a4ab9a 100644 --- a/docs/configuration/distribution-lists.md +++ b/docs/configuration/distribution-lists.md @@ -6,6 +6,8 @@ sidebar_position: 10 Distribution Lists in Resgrid allow you to create email-based communication groups within your department. A distribution list has an email address that, when emailed, forwards the message to all members of the list. Lists can be configured as Internal (using Resgrid's messaging system) or External (connecting to an outside email server to monitor an inbox and distribute messages). + + ## Why Distribution Lists Matter Departments often need to communicate with subsets of their personnel — for example, all officers, all training staff, or all members of a particular committee. Distribution lists provide a simple way to email a group of people without needing to maintain separate email groups outside of Resgrid. They integrate directly with your department's personnel roster, so membership stays current as people join or leave. diff --git a/docs/configuration/inventory-types.md b/docs/configuration/inventory-types.md index 73d3c46..9c324e5 100644 --- a/docs/configuration/inventory-types.md +++ b/docs/configuration/inventory-types.md @@ -10,6 +10,8 @@ This page describes the original inventory *types* screen. Since the 2026 invent Inventory Types in Resgrid define the categories of items your department tracks in the inventory system. Each type represents a class of supply or equipment — such as "SCBA Bottles", "Medical Supplies", "Hose Sections", or "Batteries" — and includes configuration for units of measure and expiration tracking. + + ## Why Inventory Types Matter Before you can track inventory in Resgrid, you must define what kinds of items you want to track. Inventory Types provide the classification system that organizes your supplies and equipment. They enable consistent tracking across stations, allow for expiration monitoring on perishable items (like medical supplies), and provide the foundation for inventory adjustments and reporting. diff --git a/docs/configuration/mapping-layers.md b/docs/configuration/mapping-layers.md index 66228d6..3e4d2ae 100644 --- a/docs/configuration/mapping-layers.md +++ b/docs/configuration/mapping-layers.md @@ -10,6 +10,8 @@ Mapping Layers in Resgrid allow you to add custom geographic data overlays to yo If you need to upload a building floor plan, indoor map, or venue schematic — and draw named polygon zones (e.g., "Room 405a", "Staging Area B") on top of it — use **Custom Maps** instead of a standard layer. Custom Maps support multi-floor images geo-projected onto real-world coordinates, zone-based call locations, pre-plan attachments, and offline mobile caching. See the [Custom Maps](../web-app/custom-maps) documentation. ::: + + ## Why Mapping Layers Matter Standard maps show streets and terrain but lack the operational context your department needs. Mapping layers let you overlay your own geographic data — such as first-due response districts, hydrant locations, pre-plan locations, mutual aid boundaries, or flood zones — directly onto the maps your personnel use for dispatch and response. POIs mark important fixed locations that responders need to quickly find during operations. diff --git a/docs/configuration/notifications.md b/docs/configuration/notifications.md index e79dd67..04ceeba 100644 --- a/docs/configuration/notifications.md +++ b/docs/configuration/notifications.md @@ -6,6 +6,8 @@ sidebar_position: 14 Notifications in Resgrid allow you to configure automated alerts that are triggered by specific system events. When an event occurs (such as a personnel status change, a unit going out of service, or staffing levels dropping below a threshold), the system can automatically notify designated personnel, roles, groups, or the entire department. + + ## Why Notifications Matter In emergency operations, awareness of changing conditions is critical. A key responder going unavailable, a unit going out of service, or staffing dropping below safe levels are all situations that require immediate attention. Notification rules automate this awareness, ensuring the right people are informed when important events occur — without requiring someone to manually monitor the system. diff --git a/docs/configuration/permissions.md b/docs/configuration/permissions.md index 4bc4395..b9a03d8 100644 --- a/docs/configuration/permissions.md +++ b/docs/configuration/permissions.md @@ -6,6 +6,8 @@ sidebar_position: 11 Security and Permissions in Resgrid control who can perform specific actions within your department. The permissions system allows department administrators to restrict access to features like call creation, personnel management, document creation, and more. Each permission can be set to allow everyone, only department admins, department and group admins, or admins plus specific personnel roles. + + ## Why Permissions Matter As your department grows, not every member should have the same level of access. Dispatchers may need to create calls but not manage personnel. Group leaders may need to view their group's personnel but not all department personnel. The permissions system gives you fine-grained control over who can do what, ensuring operational security and preventing accidental changes to critical data. @@ -85,6 +87,15 @@ When **Department Admins and Select Roles** is selected, you can specify which p | Contact Edit | Everyone | Who can edit contact records | | Contact Delete | Everyone | Who can delete contact records | +### Import & Migration + +| Permission | Default | Description | +| ----------------------------- | ------------------- | --------------------------------------------------------------- | +| Manage Department Import (72) | Dept Admins (fixed) | Who can use [Import & Migration](../web-app/import-and-migration/overview): upload, match, fix, approve and run imports, roll back, activate and invite imported people, and grant support access | +| Manage Record Imports (73) | Dept Admins (fixed) | Reserved for importing third-party incident history into Records; not used by the current release | + +Both are fixed to department administrators and the managing user: they do not appear in the permissions list and cannot be granted to other members or roles. + ## Lock to Group Some visibility permissions support a **Lock to Group** option. When enabled, personnel can only see data (locations, users, units) that belongs to their own group. This is useful for large departments where groups operate independently and should only see their own members on maps and in personnel lists. diff --git a/docs/configuration/personnel-roles.md b/docs/configuration/personnel-roles.md index e2cc5da..1eac6c6 100644 --- a/docs/configuration/personnel-roles.md +++ b/docs/configuration/personnel-roles.md @@ -6,6 +6,8 @@ sidebar_position: 16 Personnel Roles allow you to define functional roles within your department and assign them to personnel. Roles represent capabilities, qualifications, or job functions (such as "Firefighter", "EMT", "Officer", "Driver/Engineer") rather than organizational positions. Roles are used throughout Resgrid for dispatch targeting, notification rules, permissions, and availability tracking. + + ## Why Personnel Roles Matter Roles provide a powerful way to organize your personnel by capability rather than just by group. When dispatching a call, you can dispatch to a role (e.g., "All EMTs") rather than selecting individuals. Notification rules can target roles to alert specific skill sets when conditions change. Permissions can be granted to roles, allowing you to give specific access without making someone a full administrator. @@ -29,6 +31,7 @@ Click **Add Role** to create a new personnel role. | Name | Yes | The name of the role (must be unique within the department) | | Description | No | A description of what the role represents | | Members | No | Department personnel assigned to this role | +| Custom icon | No | An image shown on the map pins of the role's members, by role order (see below) | When creating a role, you can assign members immediately, or create the role first and add members later by editing it. @@ -40,6 +43,22 @@ Each role name must be unique within your department. If you attempt to create a Click on a role to edit its name, description, or member list. You can add or remove members at any time. Changes take effect immediately. +## Role order and map icons + +Give a role a **custom icon** on **Add Role** or **Edit**. The picker shows the image rules and previews the icon on a light map, a dark map and in a list before you save. The rules and messages are the same as for [unit and call type icons](../web-app/mapping#choosing-an-image). + +![Role icon picker](/img/web-app/personnel/role-icon.png) + +A person can hold several roles, so their map pin uses the icon of **the first role they hold, in the role order, that has an icon**. Department administrators set the order on **Manage Roles**: drag the rows or use the arrows, then click **Save order**. Until you save an order, roles are listed by name. A role added later goes to the end of a saved order. + +![Roles with icons and order controls](/img/web-app/personnel/roles.png) + +Put the roles you most want to see on the map first. For example, order *Officer* above *Paramedic* above *Firefighter*: an officer who is also a paramedic shows the officer icon, and a firefighter-paramedic shows the paramedic icon. People whose roles have no icon keep the standard person pin. To remove a role's icon, tick **Remove the custom icon** on Edit and save. Deleting a role deletes its icon. + +A role can also have an icon for each personnel status: **Edit** the role and choose **Status map icons**. A member whose map icon comes from the role shows the status icon while they are in that status, and the role's own icon with a colored status badge otherwise. Members with no role icon show the person pin in the color of their status. See [Status and priority icons](../web-app/mapping#status-and-priority-icons) and the [Map icon legend](../web-app/mapping#map-icon-legend). + +The order and icons also reach the apps: the Unit, Responder, IC and Dispatch apps draw the icon on personnel map pins, and the Responder, IC and Dispatch personnel lists show it beside each person. + ## Deleting a Role Roles can be deleted from the role list. Before deleting a role, consider the impact on: @@ -62,6 +81,7 @@ Before deleting a role, check Notifications, Permissions, and any dispatch confi | Availability | Availability alerts can monitor specific roles (e.g., alert when fewer than 3 EMTs are available) | | Units | Unit roles define positions on a unit (e.g., Driver, Officer, Firefighter) that map to personnel roles | | Reports | Personnel roles appear in reports and personnel exports | +| Mapping | A person's map pin uses the icon of their first role, in role order, that has one | ## Roles vs Groups diff --git a/docs/configuration/protocols.md b/docs/configuration/protocols.md index 84cdf6b..422f84d 100644 --- a/docs/configuration/protocols.md +++ b/docs/configuration/protocols.md @@ -6,6 +6,8 @@ sidebar_position: 8 Protocols in Resgrid are structured decision-support guides that can be attached to calls during dispatch. They provide step-by-step instructions, questionnaires, and reference documents that help dispatchers and responders follow standardized procedures based on the type and priority of a call. Protocols can be automatically suggested based on call characteristics or manually attached during dispatch. + + ## Why Protocols Matter Emergency response organizations rely on standard operating procedures to ensure consistent, safe, and effective responses. Protocols in Resgrid digitize these procedures and make them available at the point of dispatch. When a call is created, relevant protocols are automatically identified based on triggers (such as call priority and type), ensuring that responders always have the right guidance for the situation. diff --git a/docs/configuration/setup.md b/docs/configuration/setup.md index dd0b748..db71b07 100644 --- a/docs/configuration/setup.md +++ b/docs/configuration/setup.md @@ -4,7 +4,11 @@ sidebar_position: 1 # Setup -The Setup Wizard guides you through the initial configuration of your Resgrid department after you first create your account. It walks you through the essential settings required to get your department operational, including basic department information, address, and initial preferences. Completing the setup wizard ensures your department is properly configured before you start adding personnel, units, and configuring advanced features. +New departments are set up with **Admin Assist**, which opens on its **Setup Wizard**: a nine-step journey from your goals and department profile through people, dispatch and your other modules to verification and handover. The wizard does not save settings itself. Each step links to the normal screen for each feature (Department Settings, Personnel, Units, Call Settings and so on); you make the change there, return to setup and verify it in the **Setup Report**. You can pause and resume at any time. + +**Department menu → Admin Assist.** Only department administrators see it, and only when setup is enabled for your Resgrid installation. An unfinished setup also shows a prompt on the dashboard. The full guide to every tab, step and check is [Help & Setup](../web-app/help-setup). + + ## Why Setup Matters @@ -12,42 +16,62 @@ Proper initial setup is critical because many other features in Resgrid depend o ## Running the Setup Wizard -When you first log in after creating a department, you will be directed to the Setup Wizard automatically. You can also access it later from the Department Settings area if you need to re-run it. +Open **Admin Assist** from the top of the Department menu, or choose **Start or resume setup** on the dashboard prompt. In step 1 choose how you are starting. The choice records your intent; it does not import or overwrite data. + +| Setup mode | Use it when | +| --- | --- | +| Fresh setup | The department is new to Resgrid | +| Review existing setup | The department already runs on Resgrid and you want to check or extend its setup | +| Import or migration | You are moving from another system. Import planning does not copy data: use the existing import tools, then verify the result in Setup Report | -### Step 1: Department Information +The nine steps are **Welcome and goals**, **Department profile**, **Choose your modules**, **People and access**, **Dispatch essentials**, **Your other modules**, **Plan and add-ons**, **Verify and practice** and **Review and hand over**. See [the nine-step journey](../web-app/help-setup#setup-journey) for what each one covers. -The first step collects your core department details. +### Department information + +Step 2 (**Department profile**) asks you to confirm your core department details. They are set on [Department Settings](department-settings.md) (**Department menu → Department Settings**). | Field | Required | Description | | ------------------ | -------- | ------------------------------------------------------------------ | | Department Name | Yes | The name of your department as it will appear across the system | -| Time Zone | Yes | Your department's operating time zone (defaults to US Pacific) | +| Time Zone | Yes | Your department's operating time zone | | Use 24-Hour Time | No | Toggle between 12-hour (AM/PM) and 24-hour time display | -| Managing User | Yes | The primary administrator account for the department | +| Managing User | Yes | The account owner: the only person who can change billing, purchase add-ons or delete the department | :::tip Department Name Choose your department name carefully as it appears in all notifications, emails, and reports sent from the system. You can change it later in Department Settings if needed. ::: -### Step 2: Department Address +### Department address -Setting your department address establishes the geographic center for mapping and dispatch operations. +The department address, also on Department Settings, establishes the geographic center for mapping and dispatch operations. -| Field | Required | Description | -| ------------- | -------- | ---------------------------------------------- | -| Address | Yes | Street address of your department headquarters | -| City | Yes | City name | -| State | Yes | State or province | -| Postal Code | Yes | ZIP or postal code | -| Country | Yes | Country | +| Field | Required | Description | +| -------------- | -------- | ---------------------------------------------- | +| Street Address | Yes | Street address of your department headquarters | +| City | Yes | City name | +| State/Province | Yes | State or province | +| Postal Code | No | ZIP or postal code | +| Country | Yes | Country | :::warning Address Accuracy -Ensure your department address is accurate. This address is used as the default center point for maps throughout the system including the Big Board, Dispatch Map, and Mapping modules. An incorrect address will cause maps to center on the wrong location. +Ensure your department address is accurate. Unless you set **Default map centre GPS coordinates** on Department Settings, this address is used as the default center point for maps throughout the system including the Big Board, Dispatch Map, and Mapping modules. An incorrect address will cause maps to center on the wrong location. ::: +### Operating profile and modules + +Also in step 2, the **Department operating profile** records your operating packs (fire, EMS, mental health, SAR, emergency response, Hazmat, industrial, security, mutual aid), workforce mix, dispatch model, operating hours, languages and links to your approved local policies. The packs suggest modules to review; they do not change your choices or set staffing, qualification or clinical requirements. In step 3 you mark each module **Use now**, **Learn later** or **Not applicable** (with a reason); security always applies. See [Department operating profile](../web-app/help-setup#operating-profile) and [Choose the modules your department uses](../web-app/help-setup#choose-areas). + +## Moving from another system + +If your department already has its people, stations and apparatus in spreadsheets or in another product, choose **Import or migration** in the first step of the Setup Wizard (see [Setup Wizard, Setup Report and Admin Assist](../web-app/help-setup#start-setup)). It offers **Open Import & Migration**, where you upload your files or the Resgrid starter workbook, check and fix every row, and approve the import; nothing is saved until you approve it, and imported people receive nothing until you invite them. The button appears for department administrators when Import & Migration is turned on for the department. See [Import & Migration](../web-app/import-and-migration/overview). + +## Checking Your Setup + +The **Setup Report** tab lists verified checks, checks needing attention and checks with unknown evidence for the modules you use, with a link to the screen that fixes each one. After saving on that screen, use **Return to setup and verify**, then **Verify again**. Missing or unavailable evidence is shown as unknown, never as a pass. Setup Report replaces the old numerical setup score; it is administrative guidance, not a certification of operational readiness. See [Configure and verify](../web-app/help-setup#configure-and-verify). + ## After Setup -Once the Setup Wizard is complete, you should proceed to configure the following areas in order: +Steps 4 to 6 of the wizard link to these screens. The configuration guides cover each in detail, in a sensible order: 1. **[Stations and Groups](stations-groups.md)** — Create your organizational structure 2. **[Adding Personnel](adding-personnel.md)** — Invite and add your team members @@ -55,16 +79,23 @@ Once the Setup Wizard is complete, you should proceed to configure the following 4. **[Department Settings](department-settings.md)** — Fine-tune department-wide settings 5. **[Custom Statuses](custom-statuses.md)** — Set up your status and staffing options 6. **[Types](types.md)** — Define call types, unit types, and other categories +7. **[Call Import](call-import.md)** — Have your CAD or dispatch center's emails create calls + +When everything is set up, mark the Setup Report reviewed in step 9 and, if you want, choose a date to review it again. + +Stations and groups, personnel and their certifications, units, statuses and types (call types, call priorities, unit types, roles, certification types and point of interest types) can also be set up in bulk from a spreadsheet with [Import & Migration](../web-app/import-and-migration/overview). Department settings, module choices and call import are not imported from a file. ## Clearing the Department Cache -If you experience stale data or settings not appearing to take effect after setup, you can clear the department cache from the Department Settings page. This forces all cached data to be refreshed from the database and can resolve display inconsistencies. +If you experience stale data or settings not appearing to take effect after setup, use **Force Department Update** on the Department Settings page. This clears your department's cached data so it is reloaded from the database and can resolve display inconsistencies. The request can take up to 15 minutes to process, and some operations may be slower while the cache rebuilds. ## Common Issues | Issue | Resolution | | ---------------------------------- | --------------------------------------------------------------------------------------- | -| Maps centered on wrong location | Update your department address in Department Settings → Address | +| Maps centered on wrong location | Update your department address, or the default map centre coordinates, in Department Settings | | Times showing in wrong time zone | Update Time Zone in Department Settings | -| Setup wizard not appearing | Navigate to Department Settings to access configuration manually | -| Settings not taking effect | Clear the department cache from Department Settings and have users log out and back in | +| Admin Assist not in the Department menu | Only department administrators see it, and only when setup is enabled for your installation. Every setting remains available from its own screen in the Department menu | +| Setup prompt gone from the dashboard | Dismissing it hides it for your account only; open **Department menu → Admin Assist** to resume | +| A check shows as unknown | The evidence was missing, restricted or unavailable. Fix the source on its own screen, then choose **Verify again** | +| Settings not taking effect | Use **Force Department Update** on Department Settings and have users log out and back in | diff --git a/docs/configuration/stations-groups.md b/docs/configuration/stations-groups.md index b973cbe..d063391 100644 --- a/docs/configuration/stations-groups.md +++ b/docs/configuration/stations-groups.md @@ -6,6 +6,8 @@ sidebar_position: 3 Stations and Groups define the organizational structure of your department in Resgrid. Groups represent logical groupings of personnel (such as divisions, platoons, or teams), while Stations are a special type of group that have a physical location. Personnel are assigned to groups, units are assigned to stations, and many features such as dispatch, shifts, and notifications rely on this organizational hierarchy. + + ## Why Stations and Groups Matter Your group structure is foundational to how Resgrid operates. Dispatch uses groups to determine who to notify, shifts are organized around groups, permissions can be scoped to groups, and mapping uses station locations for routing and display. Without properly configured groups and stations, dispatch targeting, shift management, and location-based features will not function correctly. diff --git a/docs/configuration/templates.md b/docs/configuration/templates.md index 88242e0..9c21e77 100644 --- a/docs/configuration/templates.md +++ b/docs/configuration/templates.md @@ -6,6 +6,8 @@ sidebar_position: 7 Templates in Resgrid provide two features that speed up call creation: **Call Quick Templates** and **Call Note Autofills**. Call Quick Templates pre-fill call creation fields with commonly used values, allowing dispatchers to create recurring call types with a single click. Call Note Autofills provide pre-written text snippets that can be quickly inserted into call notes during an active call. + + ## Why Templates Matter During an emergency, speed is critical. Dispatchers often create the same types of calls repeatedly (e.g., "Structure Fire", "Medical Emergency", "Traffic Accident") with similar details. Templates eliminate the need to type the same information every time, reducing call creation time and ensuring consistency across dispatches. Call Note Autofills similarly speed up documentation during active calls. diff --git a/docs/configuration/text-messaging.md b/docs/configuration/text-messaging.md index 543a4c8..4f88a79 100644 --- a/docs/configuration/text-messaging.md +++ b/docs/configuration/text-messaging.md @@ -6,6 +6,8 @@ sidebar_position: 6 Text Messaging configuration allows your department to enable two powerful SMS-based features: **Text-to-Call** and **Text Commands**. Text-to-Call lets authorized personnel create new calls by sending a text message, while Text Commands allow personnel to update their status or staffing level via SMS without needing the mobile app or web interface. + + ## Why Text Messaging Matters Not all personnel have reliable internet access or may not always have the Resgrid mobile app available. Text messaging provides a fallback communication channel that works on any mobile phone. It enables personnel to interact with Resgrid using basic SMS, ensuring critical dispatch and status functions remain accessible even in low-connectivity situations. @@ -57,6 +59,7 @@ Personnel can text commands to the department number to update their status with - Texts are matched against the registered mobile number of each person - The system parses the command and updates the person's status or staffing accordingly - Confirmation is typically sent back via the notification system +- Replying to a dispatch text to respond to the call (or to a station) sets the person's status to your department's own personnel status with the meaning **Responding** (the first by order). Without custom personnel statuses, or when none of them has that meaning, it sets the built-in *Responding to Scene* or *Responding to Station*. Give your responding status that [meaning](custom-statuses#status-meanings) so SMS replies set it ## Contact Verification and SMS diff --git a/docs/configuration/types.md b/docs/configuration/types.md index 736c1fc..4e86996 100644 --- a/docs/configuration/types.md +++ b/docs/configuration/types.md @@ -6,6 +6,8 @@ sidebar_position: 21 Under the Department Menu in the Types menu option allows you set a number a department wide and module specific types or selection options. + + ## Call Types By default there are no Call Types defined. A call type allows you organize calls into a category for example, "Structure Fire" or "Motor Vehicle Accident". @@ -19,9 +21,11 @@ Call Types are assignable on Call Creation and are also used in other systems to You cannot delete a Call Type once it's been used. If you wish to delete the Call Type you need to delete or update any systems where you used it, for example Protocols, Call Templates, Command Definitions, etc. Once those have been deleted or updated to another type you can then delete the Call Type. :::tip Call Types in Calls -Call Type names are used in the Call when stored in the Database, thus changes or deletion of the call type won't impact previously entered calls. +A call stores its type's name and remembers which call type it was logged with. Renaming a call type keeps its earlier calls linked to it, so check-in timer overrides, run cards and protocols set up for that type still apply to them, and protocol triggers and call templates that name the type are renamed with it. The calls themselves keep showing the name they were logged with. ::: +Each call type can have a **Class**: Fire, Medical, Rescue, Traffic Collision, Hazardous Materials, Alarm, Service Call, Law Enforcement, Disaster or Weather, Mutual Aid, Non-Emergency Activity or Other. Resgrid uses the class, not the name, for reports, defaults and integrations, so you can name call types however you like. The edit page suggests a class from the name (*Suggested from the name: Fire*), but never sets one for you. See [Classes and meanings](../web-app/types-configuration#classes-and-meanings). + ## Call Priorities By default there are 4 Call Priorities defined in Resgrid; Low, Medium, High and Emergency all with default sounds and options. @@ -35,6 +39,7 @@ Once you create one new Call Priority the default ones will be deactivated and y | Name | Description | | -------------------- | ------------------------------------------------------------ | | Priority Name | Name of the Call Priority that is selectable/shown | +| Meaning | Which standard priority it means (Low, Medium, High or Emergency), used to compare and sort priorities by urgency | | Priority Color | Color of the Priority also the Color of Text in Report | | Sort Order | Lower means first on the lists, default (0) is order created | | Is Default | Can only be ONE, is the default Priority for automation | @@ -57,6 +62,8 @@ When you create Custom Statuses (Actions) for Units, you need to assign that sta ![Add Unit Type](/img/configuration/types/NewUnitType.png) +Each unit type can also have a **Class** (Engine, Aerial, Rescue, Tanker, Ambulance, Medical Response, Wildland, Hazardous Materials, Command, Support, Watercraft, Aircraft, Patrol or Other) that tells Resgrid what kind of unit it is, whatever you call it. As with call types, the edit page suggests one from the name and you confirm it. + ## Certification Types Certifications allow you're users to add in Certifications and their information in their own profile. With the Certification Types you can add the certifications you want users to add and maintain in your Resgrid Department. diff --git a/docs/configuration/user-defined-fields.md b/docs/configuration/user-defined-fields.md index 515017c..08b0d72 100644 --- a/docs/configuration/user-defined-fields.md +++ b/docs/configuration/user-defined-fields.md @@ -6,6 +6,8 @@ sidebar_position: 23 User Defined Fields (UDFs) allow departments to extend the built-in data model with custom fields tailored to their specific operational, compliance, or reporting requirements. UDFs can be added to **Calls**, **Personnel**, **Units**, and **Contacts**, and are rendered automatically in web forms, mobile apps, and exports. + + ## Why User Defined Fields Matter Every department captures information that the standard system fields do not cover. A hazmat team may need a "Chemical Class" field on calls. A government agency may require a "Certification Level" field on personnel records. A fire department may track a "Service Date" on each unit. UDFs let department admins define these fields without any custom development, while preserving full audit trails and historical data integrity. diff --git a/docs/configuration/workflows.md b/docs/configuration/workflows.md index f8f7294..8c35e1c 100644 --- a/docs/configuration/workflows.md +++ b/docs/configuration/workflows.md @@ -6,6 +6,8 @@ sidebar_position: 22 Workflows in Resgrid provide an event-driven automation engine that connects system events to external actions. When something happens in the system — a call is created, a unit changes status, a personnel staffing level changes — workflows can automatically send emails, post messages to Slack or Teams, call external APIs, upload files to cloud storage, and more. Each workflow uses Scriban templates to transform event data into the exact output format your external systems require. + + ## Why Workflows Matter Departments increasingly need to integrate Resgrid with external systems — CAD platforms, records management systems, alerting services, analytics dashboards, communication channels, and cloud storage. Without workflows, these integrations require custom development or manual processes. Workflows let department admins create these integrations through the web interface without writing code, using a visual template editor with preview capabilities. @@ -160,8 +162,8 @@ The following system events can trigger workflows: | Event | Description | Key Variables | |-------|-------------|---------------| -| Call Added | New call/dispatch created | `call.*`, `user.*` (reporting user) | -| Call Updated | Existing call updated | `call.*`, `user.*` (reporting user) | +| Call Added | New call/dispatch created; for a [pending call](../web-app/dispatch-calls#pending-and-scheduled-calls), when it is dispatched | `call.*`, `user.*` (reporting user) | +| Call Updated | Existing call updated; also when a pending call is saved or edited | `call.*`, `user.*` (reporting user) | | Call Closed | Call closed | `call.*`, `user.*` (reporting user) | ### Personnel Events diff --git a/docs/enterprise/security-policies.md b/docs/enterprise/security-policies.md index 1339822..bd95e6b 100644 --- a/docs/enterprise/security-policies.md +++ b/docs/enterprise/security-policies.md @@ -6,6 +6,8 @@ sidebar_position: 4 The Department Security Policy feature allows administrators to enforce compliance-oriented controls across their entire department. These policies govern authentication requirements, session behavior, network restrictions, and password rules — designed to meet the needs of enterprise organizations and government agencies operating under frameworks like NIST, CJIS, or FedRAMP. + + ## Overview Security policies are stored per-department in the `DepartmentSecurityPolicies` table and enforced at login time by the Resgrid API. When a user attempts to authenticate (via password or SSO), the system checks the department's security policy and blocks access if any requirement is not met. diff --git a/docs/how-tos/setup-department.md b/docs/how-tos/setup-department.md index 187f7f0..ad41f94 100644 --- a/docs/how-tos/setup-department.md +++ b/docs/how-tos/setup-department.md @@ -10,6 +10,10 @@ This page is the generic, screen-by-screen walk-through. For concrete values — This guide walks you through every step needed to get your Resgrid department configured and ready for day-to-day use. Work through the sections in order — each one builds on the previous. + + + + ## Use Setup Wizard and Setup Report When enabled for your deployment, department administrators can open **Setup Wizard** from the Department or Help menu. Choose your operating profile and areas to use now, learn about every product area and optional add-on, then follow links to the existing setup screens. Use **Setup Report** to verify fresh evidence after saving. Personal learning choices and feature interest never purchase, enable or send anything. @@ -350,7 +354,7 @@ There are three types of custom statuses: | **Button Text** | The label shown on the status button (e.g. `Responding`). | | **Button Color** | Background colour for the button (use the colour picker). | | **Text Color** | Text colour for the button. | -| **Base Type** | Maps this custom status to a system-level behaviour so Resgrid knows its meaning. Options: *Available*, *Not Responding*, *Responding*, *On Scene*, *Dispatched*, *Cleared*, *Returning*, *Staging*, *Unavailable*, or *None*. | +| **Meaning** | The status's meaning (base type). Resgrid uses it, not the button text, for availability, the unit status on dispatch and release, notifications, reports and the apps; a status left on *None* is unknown to all of them. Options include *Available*, *In Quarters*, *Dispatched*, *Responding*, *En Route*, *On Scene*, *At Patient*, *Transporting*, *At Hospital*, *Returning*, *Cleared*, *Unavailable*, *Maintenance* and more; see [Status meanings](../web-app/custom-statuses#status-meanings). | | **Require GPS** | Check if selecting this status should require the user's GPS location. | | **Detail Type** | What additional picker appears when this status is selected: **None** (no picker), **Calls** (pick an active call), **Stations** (pick a station), or **Calls and Stations** (pick either). | | **Note Type** | Whether a free-text note is shown: **None**, **Optional**, or **Required**. | @@ -369,10 +373,11 @@ There are three types of custom statuses: | **Button Text** | The label (e.g. `Available`, `Light Duty`, `Off Duty`). | | **Button Color** | Background colour. | | **Text Color** | Text colour. | +| **Meaning** | The staffing level's meaning: *Available*, *Delayed*, *Unavailable*, *Committed*, *On Shift*, *Off Duty*, *On Call* or *None*. Dispatch recommendations, availability counts and notification muting use it. | | **Note Type** | **None**, **Optional**, or **Required**. | :::info -Personnel Staffing levels do **not** have Base Type, Require GPS, or Detail Type options — those fields only apply to Personnel Status and Unit Status types. +Personnel Staffing levels do **not** have Require GPS or Detail Type options — those fields only apply to Personnel Status and Unit Status types. Their Base Type uses the staffing meanings above, not the status ones. ::: 4. Click **Save**. @@ -390,7 +395,7 @@ You can create a different status set for each unit type. For example, your engi | **Button Text** | The label (e.g. `In Service`, `Responding`, `Out of Service`). | | **Button Color** | Background colour. | | **Text Color** | Text colour. | -| **Base Type** | Maps to system behaviour — same options as personnel statuses. | +| **Meaning** | Maps to system behaviour — same options as personnel statuses. | | **Require GPS** | Check if GPS location is required when selecting this status. | | **Detail Type** | **None**, **Calls**, **Stations**, or **Calls and Stations**. | | **Note Type** | **None**, **Optional**, or **Required**. | diff --git a/docs/intro.md b/docs/intro.md index 8e6369b..9844143 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -17,12 +17,15 @@ Resgrid is written in C# on .NET with SQL Server or PostgreSQL as the primary st - **Setting up a department?** Pick the recipe for your organisation under [Setup guides](setup-guides/overview). - **Hosting it yourself?** See [Self-hosted](self-hosted/quick-start). - **Integrating?** See the [API](api/authentication) and [Workflows](web-app/workflows). +- **Prefer video?** [Resgrid Academy](https://academy.resgrid.com/) has short narrated lessons, learning paths by role and step-by-step configuration walkthroughs. Pages here with a matching video show it near the top. ::: :::info Screenshots Screenshots in this documentation were taken from the current web application with sample data. The interface is updated over time; functionality stays the same even when a screen looks a little different. ::: + + ## What is in the box ### Operations diff --git a/docs/reference/feature-flags.md b/docs/reference/feature-flags.md index 3e92cc4..30c7a8a 100644 --- a/docs/reference/feature-flags.md +++ b/docs/reference/feature-flags.md @@ -42,20 +42,29 @@ Writes go through the feature-toggle service, so caches are invalidated and an a | `Records.Prevention.Inspections` | Inspection programs, code sets, inspections, violations. | `Records.Prevention.Occupancy` | M0186 | | `Records.Prevention.Hydrants` | Hydrants and water sources. | `Records.System` | M0186 | | `Records.Prevention.Permits` | Permits and plan review. | `Records.Prevention.Occupancy` | M0186 | -| `Records.Prevention.Crr` | Community risk reduction activities. | `Records.System` | M0186 | +| `Records.Prevention.Crr` | Community risk reduction activities, smoke / CO alarm counts and alarm requests (M0284). | `Records.System` | M0186 | | `Records.Investigations` | Investigation cases. | `Records.System` | M0186 | | `Records.QualityReview` | Quality review rubrics and sampling. | `Records.System` | M0186 | | `Records.Analytics` | Records analytics dashboards. | `Records.System` | M0187 | +| `Search.Unified` | [Search](../web-app/search): the Search page and search results in the top-bar box (the **Go to** shortcuts work without it). The installation must also run the search host (`SearchConfig.Enabled`). | — | M0208 (off) | | `Security.DepartmentProtectedDataEnrollment` | Platform-wide admission gate for **new** Advanced Data Protection enrollments (operator-managed; never affects departments already enrolled). | — | M0126 | | `Business.Operations` | Master switch for every paid [Business Ops](../web-app/business-ops/overview) surface; the purchase itself is the Business Ops add-on. | — | M0211 (off) | | `Invoicing.CustomerInvoicing` | Invoicing: billing profiles, rate cards, invoices, payments, aging. Also needs the Business Operations module switch and the add-on. | `Business.Operations` | M0211 (off) | | `Payments.StripeConnect` | Operator-only per-region kill switch for online payment collection (on in the US cluster, off in the EU cluster at launch). Departments cannot override it. | — | M0212 (off, permanent) | | `Invoicing.OnlinePayments` | Customers pay invoices through the department's own Stripe account. | `Invoicing.CustomerInvoicing`, `Payments.StripeConnect` | M0212 (off) | -| `Operations.Deployments` | Deployment Finance: deployments, rosters, daily time reports, expenses, files, external-order link. **Free** — no add-on. | — | M0219 (off) | +| `Operations.Deployments` | Deployment Finance (**Workforce & Business Ops → Deployments**): deployments, rosters, daily time reports, expenses, files, external orders (which also need `Records.System`). **Free** — no add-on. Read-only [deployment reports](../web-app/records/deployments) need only `Records.System`. | — | M0219 (off) | | `Invoicing.ContractorBilling` | Rate schedules, contracts, bids, the deployment wizard and invoice generation from time reports. | `Business.Operations` | M0219 (off) | | `CostRecovery.CalOesMars` | Cal OES MARS cost recovery. | `Business.Operations` | M0219 (off) | | `Workforce.InternalCosting` | Workforce compensation, work entries, resource costing and cost runs. | `Business.Operations` | M0224 (off) | | `Compliance.CaliforniaPayDataReporting` | California CRD pay data report wizard and demographic self-identification; the department's Advanced Data Protection state must also be *Enabled*. | `Business.Operations` | M0224 (off) | +| `Onboarding.MigrationWizard` | [Import & Migration](../web-app/import-and-migration/overview): the self-service import of configuration, people and apparatus. Master switch; department administrators only. | — | M0277 (off) | +| `Onboarding.OperationsData` | Import & Migration wave 2B: dispatch configuration, shifts, calendar, geography, contacts and Records prevention data. Not used by the current release. | `Onboarding.MigrationWizard` | M0277 (off) | +| `Onboarding.ReadinessData` | Import & Migration wave 2C: inventory, checklists, maintenance plans, open work orders and Business Ops profiles. Not used by the current release. | `Onboarding.MigrationWizard` | M0277 (off) | +| `Onboarding.OperationalHistory` | Import & Migration phase 3: closed calls, training results and certification history. Not used by the current release. | `Onboarding.MigrationWizard` | M0277 (off) | +| `Onboarding.HistoricalRecords` | Import & Migration phase 3R: third-party incident history into Records. Not used by the current release. | `Onboarding.MigrationWizard`, `Records.System` | M0277 (off) | +| `Onboarding.VendorPacks` | Import & Migration phase 3B: sample-validated vendor export packs. Not used by the current release. | `Onboarding.MigrationWizard` | M0277 (off) | +| `Onboarding.DepartmentPackage` | Import & Migration phase 4: Resgrid department package export, cluster moves and configuration cloning. Not used by the current release. | `Onboarding.MigrationWizard` | M0277 (off) | +| `Onboarding.ManagedMigration` | Operator-only: offers the **Operate** support access level (Resgrid staff run an import with two-person control) and the *Please do the migration for us* request, for a department with an agreed managed migration. Never enabled globally; set per department. | `Onboarding.MigrationWizard` | M0277 (off, permanent) | ## Other gates diff --git a/docs/self-hosted/installation.md b/docs/self-hosted/installation.md index 957f212..6fd5893 100644 --- a/docs/self-hosted/installation.md +++ b/docs/self-hosted/installation.md @@ -19,6 +19,8 @@ See [Windows laptop](./laptop), [RICK](./rick), or [Kubernetes/k3s](./multi) for The self-hosted version is provided without warranty or a guarantee of suitability. The supplied manifests are a starting point, not a substitute for capacity planning, security review, monitoring, tested backups, or a disaster-recovery plan. Do not use template credentials in a real deployment. ::: + + ## What the single-server stack runs The current stack includes the web application, API, events hub, background worker and database migrations, text-to-speech service, MCP server, PostgreSQL, Redis, RabbitMQ, RustFS object storage, and Caddy ingress. Hardware GPS tracking and inbound-email dispatch are optional Compose profiles. diff --git a/docs/self-hosted/quick-start.md b/docs/self-hosted/quick-start.md index 720552b..909b32a 100644 --- a/docs/self-hosted/quick-start.md +++ b/docs/self-hosted/quick-start.md @@ -10,6 +10,8 @@ This quick start runs the current Resgrid Core stack on one 64-bit Linux server The stack has single instances of its database, cache, message bus, and object store. Production use requires security review, monitoring, capacity planning, tested backups, and a recovery plan. Never deploy the committed template credentials. ::: + + ## 1. Prepare the host Install Docker Engine, Docker Compose v2, OpenSSL, and curl on a 64-bit Linux server. Ubuntu Server 24.04 LTS is a practical baseline. Start Docker and verify: diff --git a/docs/setup-guides/contract-services-provider.md b/docs/setup-guides/contract-services-provider.md index 34215cf..f65f5bc 100644 --- a/docs/setup-guides/contract-services-provider.md +++ b/docs/setup-guides/contract-services-provider.md @@ -56,7 +56,7 @@ One schedule per season or per agency rate agreement (**clone** last season's an 1. **Bid** per resource order or event: customer, contract, lines from the schedule (crew × hours/day × days, engine, mileage), valid until, requested window, delivery location; **Send bid** as PDF. 2. **Mark as accepted** → **Schedule deployment call**: the wizard sets the call, ticks the units, seats the crew (certification colours and overlapping deployments visible), equipment, rates & premiums, and creates the call + deployment + roster + calendar item. -3. Agency-ordered work without a bid: **Deployment Finance → New Deployment** (*Billable*, contact, contract, identifiers) or **Create from external order** when the order came through Records. +3. Agency-ordered work without a bid: **Deployments → New Deployment** (*Billable*, contact, contract, identifiers), or **Deployments → External orders → New external order** when the agency sent a resource order (IROC, VIPR, EMAC); the order creates the linked deployment. ## 6 — Time, expenses and approval diff --git a/docs/setup-guides/emergency-management.md b/docs/setup-guides/emergency-management.md index 07007f5..7d0c223 100644 --- a/docs/setup-guides/emergency-management.md +++ b/docs/setup-guides/emergency-management.md @@ -72,7 +72,7 @@ From the **EOC Coordination Pack**: *EOC Duty / Shift Log* (Quick entry, one per ## 9 — Workforce & Business Ops - **Certifications** (free): ICS-100/200/300/400, IS-700/800, CEM/AEM for staff and ESF partners in your department; role requirements on *EOC section chief* (ICS-300 + IS-800) in **Warn only**. -- **Deployment Finance** (free): every EMAC or state deployment your county sends or receives as a deployment (*Cost recovery*), created from the Records external order; daily time reports and expenses with receipts build the reimbursement package; the time CSV feeds the finance section. +- **Deployment Finance** (free): every EMAC or state deployment your county sends or receives as a deployment (*Cost recovery*), created by recording the external order under **Deployments → External orders**; daily time reports and expenses with receipts build the reimbursement package; the time CSV feeds the finance section. - **Cal OES MARS** (Business Ops, California operational areas): agency profile, agreements and F-42s for fire and rescue resources dispatched through the mutual-aid system; the readiness dashboard before fire season. - **Contacts**: shelter operators, ESF partners and vendors with pre-plans (occupant loads, shutoffs) and site files (floor plans of shelters). diff --git a/docs/setup-guides/ems-agency.md b/docs/setup-guides/ems-agency.md index 974be74..ff2d32c 100644 --- a/docs/setup-guides/ems-agency.md +++ b/docs/setup-guides/ems-agency.md @@ -19,7 +19,7 @@ Resgrid is not an ePCR. Keep patient care records in your ePCR system; use Resgr | Staffing reset | Off (crews are on shift, not on call). | | Require password reset via email | On. | | Modules | Shifts, Checklists, Inventory, Records on; Maintenance with Readiness Pro. | -| Dispatch settings | Default statuses dispatched → *Responding*, released → *Available*; rest period 10 min; unit status timers 2 min (dispatched without en route) and 20 min (at hospital). | +| Dispatch settings | Default statuses dispatched → *Responding*, released → *Available* (units already back in service or out of service keep their status); rest period 10 min; unit status timers 2 min (dispatched without en route) and 20 min (at hospital). Turn on **Close call when last unit clears** if crews report every status through to available, so a call closes when its last ambulance clears ([details](../web-app/dispatch-calls#closing-a-call-automatically)). | ## 2 — Types @@ -35,7 +35,7 @@ Resgrid is not an ePCR. Keep patient care records in your ePCR system; use Resgr - **Stations**: one per base/post with address and geofence (used for closest-unit selection). - **Roles**: EMT, AEMT, Paramedic, Supervisor, Dispatcher, Driver. -- **Custom statuses** (EMS template): units — Available · Responding · On scene · Transporting · At hospital · Returning · Out of service · Posting; personnel — On duty · Off duty · Responding · On scene. +- **Custom statuses** (EMS template): units — Available · Responding · On scene · Transporting · At hospital · Returning · Out of service · Posting; personnel — On duty · Off duty · Responding · On scene. Add an *At station* unit status with base type **In Quarters** so closest-unit selection measures those units from their base, and keep a status for units available on the road (base type **Available**, not Returning). Give *Out of service* the base type **Unavailable** or **Maintenance** so closing a call never puts it back in service, and give the transport statuses **Transporting** and **At Hospital** ([base types and call automation](../configuration/custom-statuses#base-types-and-call-automation)). ## 4 — Units and crews @@ -44,7 +44,8 @@ Create each ambulance with roles **Driver/EMT** and **Attendant/Paramedic** (bot ## 5 — Dispatch - Calls from your CAD by email import; or dispatchers use the **Dispatch app**. -- **Run cards**: *ALS emergency* (Echo/Delta): ALS ambulance ×1 + Paramedic role ×1; *BLS*: BLS ambulance ×1; *MCI* alarm level 2 adds ALS ×2 + Supervisor ×1. Closest-unit mode, *Order by driving ETA* on, minimum staffing *Fully staffed*, auto-dispatch on with a 10-minute rest period. +- **Run cards**: *ALS emergency* (Echo/Delta): ALS ambulance ×1 + Paramedic role ×1; *BLS*: BLS ambulance ×1; *MCI* alarm level 2 adds ALS ×2 + Supervisor ×1. Closest-unit mode, *Order by driving ETA* on, minimum staffing *Fully staffed*, auto-dispatch on with a 10-minute rest period. Set *In-quarters turnout* and *Mobile turnout* (for example 120 s and 30 s) so a crew already on the road can outrank a nearer crew that still has to leave the station. +- **Adding resources** to a call already out (the Dispatch app's *Dispatch additional resources*, or **Update** on the website) shows what the run card still needs after the units already on the call. A unit's status in the Dispatch app starts on the call the unit is working, so dispatchers don't pick the incident for each status. - **Destinations**: create hospital and ED POIs under Mapping so crews pick a destination on the call. - **Protocols**: pre-arrival instruction protocols by chief complaint if you dispatch in-house. @@ -97,6 +98,7 @@ See the [Workforce & Business Ops overview](../web-app/business-ops/overview) fo - [ ] Every ambulance created with two required roles and a Unit tablet - [ ] Crews set unit staffing at shift start - [ ] Hospital destination POIs created +- [ ] Every unit status has a base type (out of service → Unavailable or Maintenance; available → Available or In Quarters) - [ ] Narcotics checklist with witness runs each shift - [ ] Medication lots with expiry entered; expiration alert reviewed - [ ] ADP decision made and, if enrolled, verification prompt tested on the Dispatch console diff --git a/docs/setup-guides/fire-department.md b/docs/setup-guides/fire-department.md index b30e22c..eb1d890 100644 --- a/docs/setup-guides/fire-department.md +++ b/docs/setup-guides/fire-department.md @@ -116,7 +116,7 @@ Assign roles and stations; enter certifications with expiry dates. ## 13 — Workforce & Business Ops - **Certifications** (free): add FF1/FF2, Driver/Operator, Hazmat Ops, FO1, NREMT/state EMT and BLS from the template gallery plus NFPA 1911 pump and aerial tests for apparatus; role requirements *Firefighter* = FF1 + Hazmat Ops + (EMT **or** Paramedic), *Engineer* = DO-Pumper; start in **Warn only**, notify 60/30/14/7 days, move to **Enforce** after a year. -- **Deployment Finance** (free): every strike team or mutual-aid assignment as a deployment (*Cost recovery*), created from the Records external order; crews file daily time reports in the Responder / Unit apps, an officer approves them, the DTR PDFs and time CSV go into the reimbursement package. +- **Deployment Finance** (free): every strike team or mutual-aid assignment as a deployment (*Cost recovery*), created by recording the resource order under **Deployments → External orders** (accepted fills seat the roster); crews file daily time reports in the Responder / Unit apps, an officer approves them, the DTR PDFs and time CSV go into the reimbursement package. - **Cal OES MARS** (Business Ops, California): agency profile verified each January, F-5 drafted from units, Salary Survey and Administrative Rate submissions, agreements per classification, one F-42 per request after each assignment, expense claims for lodging and meals, reconcile every MARS invoice. - **Invoicing** (Business Ops): a rate card for cost recovery — *Hazmat response* (hourly unit, hazmat units, 2-hour minimum), *False alarm fee*, *Standby* — billing profiles for businesses and property managers; online payments if the treasury allows. - **Field costing** (Business Ops): resource cost profiles for apparatus, role-default compensation per rank; a cost run after each deployment to compare with the reimbursement. @@ -133,4 +133,4 @@ See the [Workforce & Business Ops overview](../web-app/business-ops/overview) fo - [ ] Records activated; one Run record finalized end-to-end - [ ] Security permissions reviewed; 2FA on for admins - [ ] Certification types added and role requirements set (Warn only) -- [ ] One deployment created from a Records external order with a test time report approved +- [ ] One external order recorded under Deployments → External orders, with a test time report approved on its deployment diff --git a/docs/setup-guides/incident-management-team.md b/docs/setup-guides/incident-management-team.md index 841528a..9046c3c 100644 --- a/docs/setup-guides/incident-management-team.md +++ b/docs/setup-guides/incident-management-team.md @@ -63,7 +63,7 @@ Use *Review required* for the IAP forms (planning section chief reviews), *Quick ## 8 — Workforce & Business Ops - **Certifications** (free): NWCG position qualifications (FFT1, CRWB, ENGB, DIVS), Red Card, RT-130, Work Capacity Test, ICS-300/400 and IS courses for every team member; role requirements per ICS position in **Warn only**; the compliance report before each season. -- **Deployment Finance** (free): every team deployment (IROC / EMAC order) as a deployment created from the Records external order, with the roster prefilled from accepted fills; members file daily time reports in the Responder app; the finance/admin unit leader approves them and exports the time CSV and DTR PDFs for the incident's cost package. +- **Deployment Finance** (free): every team deployment (IROC / EMAC order) as a deployment created by recording the order under **Deployments → External orders**, with the roster filled from accepted fills; members file daily time reports in the Responder app; the finance/admin unit leader approves them and exports the time CSV and DTR PDFs for the incident's cost package. - **Cal OES MARS** (Business Ops, California): F-42 per request from the deployment, expense claims for travel, portal handoff by the authorized representative. - **Field costing** (Business Ops): a cost run per deployment for the after-action financial summary. diff --git a/docs/setup-guides/multi-agency-dispatch-center.md b/docs/setup-guides/multi-agency-dispatch-center.md index 3eba1b7..253fd4a 100644 --- a/docs/setup-guides/multi-agency-dispatch-center.md +++ b/docs/setup-guides/multi-agency-dispatch-center.md @@ -47,7 +47,7 @@ Records stay per agency (each agency's NERIS identity and definitions). The cent ## 7 — Workforce & Business Ops - **Certifications** (free): dispatcher credentials (EMD, CPR, state telecommunicator certification as custom types) with role requirements on *Dispatcher* in **Warn only**; the compliance report for accreditation. -- **Deployment Finance** (free): if the centre coordinates mutual-aid strike teams for member agencies, the sending agency owns the deployment in its own department; the centre only links the Records external order. +- **Deployment Finance** (free): if the centre coordinates mutual-aid strike teams for member agencies, the sending agency records the external order under **Deployments → External orders** and owns the resulting deployment in its own department. - **Invoicing** (Business Ops): bill member agencies per call or per month with a rate card (*Dispatched call* flat per call, *Dispatcher hour*) and billing profiles per agency contact; aging for the board. See the [Workforce & Business Ops overview](../web-app/business-ops/overview) for what is free and what needs the add-on. diff --git a/docs/setup-guides/overview.md b/docs/setup-guides/overview.md index d875271..d0704e8 100644 --- a/docs/setup-guides/overview.md +++ b/docs/setup-guides/overview.md @@ -11,6 +11,8 @@ Every guide assumes you have already created your department (hosted at [resgrid ## Pick the guide closest to you +Nothing in Resgrid is locked to one kind of organization. The organization type you chose at sign-up (change it under [Department Settings](../web-app/department-settings#organization-types)) only describes you; every template pack, module and suggestion is open to every department. If you run several kinds of teams, combine the guides that match them and tick each sector in the [operating profile](../web-app/help-setup#operating-profile). + | Organization | Guide | Typical modules | |---|---|---| | Volunteer, combination or career fire department | [Fire department](fire-department) | Dispatch, run cards, personnel/units, shifts, checklists, work orders, inventory, Records + NERIS, prevention | diff --git a/docs/web-app/account-security.md b/docs/web-app/account-security.md index d1f19c5..d753931 100644 --- a/docs/web-app/account-security.md +++ b/docs/web-app/account-security.md @@ -7,6 +7,8 @@ title: Account Security Settings that belong to *you* rather than to the department: two-factor authentication, active sessions, username, password and account deletion. All of them live under your **profile dropdown** (your name, top-left). + + ## Two-factor authentication (2FA) **Profile dropdown → Two-Factor Authentication.** diff --git a/docs/web-app/business-ops/bids-and-deployment-wizard.md b/docs/web-app/business-ops/bids-and-deployment-wizard.md index d05de2a..bd66e9d 100644 --- a/docs/web-app/business-ops/bids-and-deployment-wizard.md +++ b/docs/web-app/business-ops/bids-and-deployment-wizard.md @@ -7,10 +7,12 @@ title: Bids & Deployment Wizard A **bid** is a priced estimate for a customer — an engine and crew for a 10-day fire assignment, four guards for a festival weekend, an ALS unit on standby for a race. Its lines snapshot rates from the customer's [rate schedule](rate-schedules), it goes out as a PDF, and when the customer accepts, **Schedule deployment call** runs the **deployment wizard** that creates the call, the [deployment](deployment-finance) and the roster in one step — seats checked against certifications and other deployments. -Business Ops add-on with `Invoicing.ContractorBilling`. Menu: **Workforce & Business Ops → Bids** (administrators and holders of *Manage bids*). +Business Ops add-on with `Invoicing.ContractorBilling`. Menu: **Workforce & Business Ops → Bids** (administrators and holders of *Manage bids*). The list filters by status and by bid number (part of it, in the department's own [format](../department-settings#document-numbering), however it is typed). ![Bids](/img/web-app/bids/index.png) + + ## Creating a bid **New bid**: pick the **customer** (the bid is addressed to its billing profile), an optional **contract** (supplies the rate schedule, discount and terms) and a title. **Create draft** allocates the next bid number. diff --git a/docs/web-app/business-ops/cal-oes-mars.md b/docs/web-app/business-ops/cal-oes-mars.md index b7ba1e0..603d563 100644 --- a/docs/web-app/business-ops/cal-oes-mars.md +++ b/docs/web-app/business-ops/cal-oes-mars.md @@ -15,6 +15,8 @@ Business Ops add-on with `CostRecovery.CalOesMars`. Menu: **Workforce & Business ![Readiness dashboard](/img/web-app/cal-oes-mars/index.png) + + ## Readiness dashboard Pick a **check date** (a dispatch date) and the dashboard lists **blockers** (stop new F-42s from reaching *Ready for portal*) and **warnings**, each with a **Fix** link: no agency profile or an unverified one, no annual submission covering the date, no agreement, F-5 mismatches, an authority profile that no longer covers the date. Below: the **annual submissions in effect**, the **agency** card (*Edit agency*, *Mark verified today*), **at-a-glance counts** (F-5 resources and mismatches, agreements, open work items, returned items, invoices awaiting local approval) and links to the **official sources** and the MARS portal. diff --git a/docs/web-app/business-ops/certifications.md b/docs/web-app/business-ops/certifications.md index 8605586..1241535 100644 --- a/docs/web-app/business-ops/certifications.md +++ b/docs/web-app/business-ops/certifications.md @@ -11,6 +11,8 @@ Free for every department. Menu: **Workforce & Business Ops → Certifications** ![Certification dashboard](/img/web-app/certifications/dashboard.png) + + ## The pages | Tab | What it is for | diff --git a/docs/web-app/business-ops/contractor-billing.md b/docs/web-app/business-ops/contractor-billing.md index ec067f7..bd948d8 100644 --- a/docs/web-app/business-ops/contractor-billing.md +++ b/docs/web-app/business-ops/contractor-billing.md @@ -11,6 +11,8 @@ Business Ops add-on with `Invoicing.ContractorBilling`. Lives on the deployment ![Billing tab](/img/web-app/deployment-finance/view-billing.png) + + ## The billing tab | Panel | What it shows | diff --git a/docs/web-app/business-ops/deployment-finance.md b/docs/web-app/business-ops/deployment-finance.md index 5fbedc1..f43684f 100644 --- a/docs/web-app/business-ops/deployment-finance.md +++ b/docs/web-app/business-ops/deployment-finance.md @@ -1,65 +1,171 @@ --- sidebar_position: 5 -title: Deployment Finance +title: Deployments --- -# Deployment Finance +# Deployments -A **deployment** is the money-and-time record of the units, personnel and equipment you sent somewhere: a strike team on a wildland assignment, an engine under contract at a film shoot, a crew loaned through EMAC, a medical team at a festival. It carries the **roster**, one **daily time report** (DTR) per day, **expenses** with receipts, **files** and a **manifest**, and it feeds — depending on its *finance mode* — nothing more than the record, a [Cal OES MARS](cal-oes-mars) claim, or a customer invoice through [Contractor Billing](contractor-billing). +A **deployment** records the units, personnel and equipment you sent somewhere: a strike team on a wildland assignment, an engine under contract at a film shoot, a crew loaned through EMAC, a medical team at a festival. It holds the **roster**, one **daily time report** (DTR) per day, **expenses** with receipts, **files** and a **manifest**. Depending on its *finance mode*, it feeds nothing beyond the record, a [Cal OES MARS](cal-oes-mars) claim, or a customer invoice through [Contractor Billing](contractor-billing). -Free for every department behind the `Operations.Deployments` flag. Menu: **Workforce & Business Ops → Deployment Finance**. Administrators and holders of *Manage deployments* see every deployment; everyone else sees **My Deployments** — the ones they are rostered on — and can file time on them. +This is also where you **create and run external resource orders** (IROC, EMAC, CIFFC or a local order). Creating an order creates its linked deployment and opens it. As the order's fills are accepted, mobilized and released, the deployment's roster and status follow. Plans and Admin Assist call this free capability **Deployment Finance**. + + + +## Where to find it + +Menu: **Workforce & Business Ops → Deployments**. Administrators and holders of *Manage deployments* see every deployment, along with the **External orders**, **Create from external order** and **New Deployment** buttons. Everyone else sees **My Deployments**: the deployments they are rostered on, where they can file time. ![Deployments](/img/web-app/deployment-finance/index.png) -:::note Two kinds of "deployment" -[Records → Deployments](../records/deployments) tracks the **external resource order** (IROC, EMAC, CIFFC) and its fills. Deployment Finance tracks what it **cost and earned**. Use **Create from external order** to link the two. +:::note Operations here, reports in Records +Create and change deployments and external orders on this page. [Records → Deployment reports](../records/deployments) shows the same deployments read-only, with printable reports, manifests, time reports, documents and CSV/JSON exports, and it keeps older external orders readable. The **Deployment reports** button on a deployment page opens its report. ::: -## Creating a deployment +## Turning it on + +| Switch | Needed for | +|---|---| +| `Operations.Deployments` flag (free, no add-on) | The **Deployments** menu and every operational screen. | +| `Records.System` flag and an activated Records module | **External orders**. The order, its fills, artifacts, record identity, audit history and retention stay in Records storage. Creating or changing an order also requires the *Create records* permission. Without Records, **Create from external order** says the Records system is not enabled. | +| Business Ops add-on | The **Billing** tab ([Contractor Billing](contractor-billing)) and [Cal OES MARS](cal-oes-mars). The **Internal cost** tab needs the Workforce entitlement ([Field Costing](field-costing)). | +| Installation config `RecordsConnectorConfig.Enabled` | [External connectors](#external-connectors) (off by default). | -Three ways: +## Creating a deployment | Start from | When | |---|---| | **New Deployment** | Anything you organize yourself. | -| **Create from external order** | A Records mutual-aid order is open: pick it, choose the finance mode and contact, optionally **prefill the roster from accepted fills** and **also create a call**. The order stays in Records. | -| **Bid → Schedule deployment call** | Contract work: the [deployment wizard](bids-and-deployment-wizard) creates the call, the deployment and the roster in one step. | +| **External orders → New external order** | A resource order arrives from IROC, EMAC, CIFFC or a local system. Record the order and its first fill. **Create deployment** then creates the linked deployment, prefills the roster from accepted fills and opens it. See [External orders](#external-orders). | +| **Create from external order** | An external order exists but has no deployment yet (for example, an order recorded before external orders moved to this page). Pick the order, choose the finance mode and contact, and optionally tick **Prefill the roster from accepted fills** and **Also create a call**. Orders that already have a deployment are not offered. | +| **Bid → Schedule deployment call** | Contract work. The [deployment wizard](bids-and-deployment-wizard) creates the call, the deployment and the roster in one step. | ![New deployment](/img/web-app/deployment-finance/new.png) | Field group | Fields | |---|---| -| **Deployment** | Name; **Finance mode** — *Operational only* (time and expenses for the record), *Cost recovery* (feeds a reimbursement claim such as Cal OES MARS), *Billable* (feeds a customer invoice); **Contact** (the customer or requesting agency); **Call #** (optional — one deployment per call); **Window** start/end and **Max days**; notes. | -| **Agency identifiers** | Incident number, service request number, **resource order #**, **request #**, **cost code**, **point of hire** — whatever the ordering agency (VIPR, FEMA, BCWS, Cal OES) assigns; printed on time reports and invoices. | -| **Jurisdiction** | Home and host country / state-province, **time zone** (incident-local time for time reports; blank uses the department's), currency, **Out of province / state** and **Travel via air** (drive per-diem and travel rules in the rate schedule). | +| **Deployment** | Name; **Finance mode**: *Operational only* (time and expenses for the record), *Cost recovery* (feeds a reimbursement claim such as Cal OES MARS) or *Billable* (feeds a customer invoice); **Contact** (the customer or requesting agency); **Call #** (optional, one deployment per call); **Window** start/end and **Max days**; notes. | +| **Agency identifiers** | Incident number, service request number, **resource order #**, **request #**, **cost code**, **point of hire**: whatever the ordering agency (VIPR, FEMA, BCWS, Cal OES) assigns. These print on time reports and invoices. A deployment created from an external order copies the order number, incident number, cost code, host country / subdivision, time zone and currency from the order. | +| **Jurisdiction** | Home and host country / state-province; **time zone** (incident-local time for time reports; blank uses the department's); currency; **Out of province / state** and **Travel via air**, which drive the per-diem and travel rules in the rate schedule. | + +Statuses: **Planned → Standby → Active → Demobilizing → Completed** (or **Cancelled**). Change them from the deployment page. A deployment linked to an external order also advances on its own as the fills move (see [How the order drives the deployment](#how-the-order-drives-the-deployment)). Workflows fire on *Deployment Created* and *Deployment Status Changed*. + +## External orders + +An external order is the request from the ordering system, plus the **fills**: the requests your department fills with people, units, crews or equipment. The ordering system stays authoritative. The order document is stored as an **immutable, checksummed snapshot**, and nothing is ever written back. + +### External orders list + +**Deployments → External orders** lists open orders. Use **Show closed-out deployments** to include closed ones. Columns: **Order number**, **Incident**, **Jurisdiction profile** (a plug icon means *Maintained by a connector*), **Source**, **Status** (*Open, Mobilized, Released, ClosedOut*) and **Created**. **New external order** needs *Create records*. **External connectors** is shown to department administrators. + +![External orders](/img/web-app/deployment-finance/external-orders.png) + +### New external order + +![New external order](/img/web-app/deployment-finance/external-order-new.png) + +| Field group | Contents | +|---|---| +| **Order** | **Jurisdiction profile** (required); **Source** scheme (`iroc / ciffc / emac / local`) and source system; **Order number** and **Incident** (required) with incident #; **Country / subdivision**; **Offices** (ordering and dispatch office). | +| **Agencies** | Requesting, receiving and sending agency; the **Department role**: *Filling the order*, *Requesting resources* or *Hosting incident*. | +| **Cost** | Cost code and agreement reference; **Currency / units / time zone**. | +| **Order artifact** | Upload the order document (PDF, JSON or CSV) from the source system, with a source version and an optional `https://` link back to the source. It is stored as an immutable, checksummed snapshot. | +| **First fill (optional)** | Request number and category; resource kind (person, unit, crew, equipment) and type; position and **Trainee**; **Assigned person**; home unit and host agency; **Needed on**; notes. | + +**Create deployment** records the order, creates the linked deployment and opens its page. If the order is saved but linking fails, submitting the same form again reuses that order instead of creating a duplicate. + +### The order page + +Open an order from the list, or from the **External order** row on its deployment page. -Statuses: **Planned → Standby → Active → Demobilizing → Completed** (or **Cancelled**); change them from the deployment page. Workflows fire on *Deployment Created* and *Deployment Status Changed*. +![External order](/img/web-app/deployment-finance/external-order.png) + +| Element | Meaning | +|---|---| +| **Open deployment workspace** | Opens the linked deployment. If the order has none yet (for example, an older order), this creates the deployment, brings the roster and status up to date with the fills, and opens it. | +| **Deployment record** | The order's read-only record in [Records → Deployment reports](../records/deployments). | +| **Order artifact** | Downloads the current order document. | +| **Order** panel | Profile, source, location, offices, agencies, department role, cost, currency, artifact checksum, created / mobilized / released (and closed-out) times. | +| **Record a new snapshot** | Upload the updated order document with its source version, then **Store snapshot**. The previous snapshot is kept and superseded. | +| **Fills** table | Request number (↳ parent request), resource, position (*(t)* for trainee), assigned person with home unit and host agency, and status with its time. Each row has buttons for the next allowed status. | +| **Add fill** | Request number, parent request, category, resource kind and type, position, assigned person, **Trainee**, **Needed on**, notes. | +| **Close out deployment** | Optional closeout notes, then confirm. The button stays disabled until the order has at least one fill and every fill that was not declined is *Returned*. Decline any request you will not fill. After closeout, fills can no longer change. | + +Fill statuses move forward one step at a time: + +| From | Next | +|---|---| +| Requested | **Accepted** or **Declined** (you are asked for a reason) | +| Accepted | Mobilized | +| Mobilized | CheckedIn | +| CheckedIn | Assigned or Released | +| Assigned | Released | +| Released | Demobilized | +| Demobilized | Returned | + +### How the order drives the deployment + +| On the order | On the deployment | +|---|---| +| A fill is accepted (through *Assigned*) with an assigned person or unit | The person or unit joins the roster (the fill's position becomes the certification code). Active roster entries are not duplicated, and removed entries stay in history. | +| Any fill *Accepted* | Status at least **Standby**. | +| Any fill *Mobilized* or later | **Active**. | +| Every fill that was not declined is *Released* or later | **Demobilizing**. | +| Order closed out | **Completed**. | + +![Deployment linked to an external order](/img/web-app/deployment-finance/view-linked.png) + +The deployment's status only moves forward. It is never set back to an earlier status, even if a fill is corrected. + +An agency **release** does not mean the resource has returned home. Setting a linked deployment to **Completed** on its page closes the external order through the same audited closeout. The same rule as **Close out deployment** applies: completion is refused (*Every resource must return home before the deployment can be completed.*) while any fill that was not declined is short of *Returned*, and it is refused for an order with no fills or only declined fills. It is also refused if you do not have Records permission to close the order. + +### External connectors + +**Deployments → External orders → External connectors** (department administrators) reads orders automatically from a source that serves the **Resgrid Mutual-Aid Order Feed v1** (JSON). Screen-scraping and inferred updates are not supported. + +![External connectors](/img/web-app/deployment-finance/connectors.png) + +| Setting | Notes | +|---|---| +| **Connector name / Feed provider / Source system / Feed root (https)** | Where to read. | +| **Credential kind / Header name / Credential** | Encrypted at rest and never shown again. Leave the credential blank to keep the stored one. | +| **Read authority granted** | Write authority is not granted in this release. Nothing is ever written back. | +| **Poll interval (minutes) / Requests per hour** | Request limits. | +| **Source terms** | **Acknowledge the source's terms** before the connector can be enabled. | +| **Inbound push endpoint / Inbound token** | For sources that push. The token is shown once; **Issue a new inbound token** replaces it. | + +Every read lands as a new snapshot. **Reconciliation** lists where the source and your record disagree (for example, *Source released the order, but a fill is not yet returned* or *Request exists in the source but not locally*). A coordinator decides what to do; nothing is applied automatically. **Read feed now** polls on demand, and the **Run log** shows each poll's outcome and counts. Deleting a connector keeps the orders it imported and their snapshots. Feed fixtures were built from published IROC, CIFFC and EMAC documentation, not from live integrations, so verify the feed against your ordering system. + +![New connector](/img/web-app/deployment-finance/connector-new.png) ## The deployment page ![Deployment roster](/img/web-app/deployment-finance/view-roster.png) -The header shows the identifiers, window, contact, call and external order; the **Summary** cards count units, personnel, time reports, personnel hours and expenses. Tabs: +The header shows **Edit**, **Deployment reports** (the read-only report in Records, shown when you can view records and Records is on) and **Export time CSV**. The detail panel shows the identifiers, window, contact, call and **External order**. For managers the order links to the order page; for others it links to the read-only order report. The **Summary** cards count units, personnel, time reports, personnel hours and expenses. Tabs: ### Roster -- **Units** — pick a unit and an optional call sign; the crew column shows how many seats are filled (this is the *crew size* that contract rates key on). -- **Equipment** — free-text items or inventory assets, issued to a unit or on their own, with **Return** when it comes back. -- **Personnel** — pick a member, a **seat** (a unit role; seats marked * require that personnel role and check its [certification requirements](certifications) — expiring certifications are flagged) and a **certification code** (which contract rate entry the person bills under). **Seat even when a requirement fails** overrides a failed check on purpose, audited. +- **Units**: pick a unit and an optional call sign. The crew column shows how many seats are filled; this is the *crew size* that contract rates key on. +- **Equipment**: free-text items or inventory assets, issued to a unit or on their own, with **Return** when they come back. +- **Personnel**: pick a member, a **seat** and a **certification code** (which contract rate entry the person bills under). A seat is a unit role; seats marked * require that personnel role and check its [certification requirements](certifications), and expiring certifications are flagged. **Seat even when a requirement fails** deliberately overrides a failed check and is audited. + +On a deployment linked to an external order, accepted fills seat their people and units automatically (see above). You can still add or remove roster entries by hand. ### Time reports -One **daily time report** per day (**New time report** with the report date). Entries are prefilled from the roster with a default window you adjust. +There is one **daily time report** per day (**New time report** with the report date). Entries are prefilled from the roster with a default window you adjust. + +Each report takes the department's next time report number: a plain count shown as `#3`, or the format set under [Document numbering](../department-settings#document-numbering) (for example `DTR-{YYYY}-{SEQ}`, `DTR-2026-0003`). The same number appears on the report, its PDF and file name, the time CSV, invoice line descriptions and in the Responder, Unit, IC and Dispatch apps. ![Time report](/img/web-app/deployment-finance/time-report.png) | Element | Meaning | |---|---| -| **Header** | Incident, resource order, request, cost code and point of hire copied from the deployment; **No clear 8** (overtime carries into the next shift) and **Unsafe conditions stand-down** flags for the billing policy. | -| **Time entries** | Subject (person, unit or equipment), **entry type** (*Deployment*, *Standby*, *Travel*), start and end (incident-local), paid and unpaid break minutes, km, notes. A subject cannot appear twice on the same report and only one report exists per day. | -| **Signatures** | **Sign as contractor** and the **customer signer name** — the agency representative who signed the paper DTR. | +| **Header** | Incident, resource order, request, cost code and point of hire, copied from the deployment. Two flags feed the billing policy: **No clear 8** (overtime carries into the next shift) and **Unsafe conditions stand-down**. | +| **Time entries** | Subject (person, unit or equipment), **entry type** (*Deployment*, *Standby*, *Travel*), start and end (incident-local), paid and unpaid break minutes, km, notes. A subject cannot appear twice on the same report, and only one report exists per day. | +| **Signatures** | **Sign as contractor**, and the **customer signer name**: the agency representative who signed the paper DTR. | | **Expenses** | Expenses attached to this day. | -| **Actions** | **Save**, **Save and submit** (entries lock once approved), **Approve** (needs *Approve time reports*), **Void** with a reason (kept for the record, dropped from billing), **PDF** and **File PDF on deployment** (stores the PDF under Files). | +| **Actions** | **Save**; **Save and submit** (entries lock once approved); **Approve** (needs *Approve time reports*); **Void** with a reason (kept for the record, dropped from billing); **PDF**; **File PDF on deployment** (stores the PDF under Files). | Report statuses: **Draft → Submitted → Approved → Billed** (set by the billing engine), or **Void**. Crews can create and submit their own DTRs from the [mobile apps](../../apps/responder#deployments); approval happens on the web. **Export time CSV** on the deployment page downloads every entry. @@ -67,48 +173,51 @@ Report statuses: **Draft → Submitted → Approved → Billed** (set by the bil ![Expenses](/img/web-app/deployment-finance/view-expenses.png) -Date, **type** (*Per-diem meal, Accommodation, Private accommodation, Ferry, Fuel, Supply restock, Other*), amount and currency, description, city, **meal code** (B/L/D for per-diem windows), **receipt** upload, **Pre-approved** and **Billable**. Billable expenses pass through to the invoice; receipts ride along in the invoice packet and the MARS evidence packet. +Each expense has a date; a **type** (*Per-diem meal, Accommodation, Private accommodation, Ferry, Fuel, Supply restock, Other*); amount and currency; description; city; a **meal code** (B/L/D for per-diem windows); a **receipt** upload; and **Pre-approved** and **Billable** checkboxes. Billable expenses pass through to the invoice. Receipts go into the invoice packet and the MARS evidence packet. ### Files -Uploads by type — receipts, signed service request, time-report PDFs, manifest, certifications, external order, signed or paper F-42, ICS-213 approvals, crew rotation approvals, loss/damage, MARS evidence and invoices. **Preview manifest** renders the roster manifest; **File manifest PDF** stores it. +Upload files by type: receipts, signed service request, time-report PDFs, manifest, certifications, external order, signed or paper F-42, ICS-213 approvals, crew rotation approvals, loss/damage, MARS evidence and invoices. **Preview manifest** renders the roster manifest; **File manifest PDF** stores it. ### Billing (billable deployments, Business Ops add-on) -Charge preview, compliance checklist, invoices and **Generate invoice** — see [Contractor Billing](contractor-billing). +Charge preview, compliance checklist, invoices and **Generate invoice**. See [Contractor Billing](contractor-billing). ![Billing tab](/img/web-app/deployment-finance/view-billing.png) ### Internal cost (Workforce entitlement) -Estimate versus actual internal cost and the cost runs for this deployment — see [Field Costing](field-costing). +Estimated versus actual internal cost, and the cost runs for this deployment. See [Field Costing](field-costing). ![Costs tab](/img/web-app/deployment-finance/view-costs.png) ## Reminders and workflows -The deployment-finance reminder worker sends department administrators one digest a day listing billable deployments whose approved time reports have been unbilled for more than 21 days (or completed deployments with any unbilled report). It never generates or sends an invoice. Workflow triggers: **Deployment Created / Status Changed / Roster Changed / Expense Added / Attachment Added**, **Time Report Created / Submitted / Approved / Voided**. +Once a day, the deployment-finance reminder worker sends department administrators a digest. It lists billable deployments whose approved time reports have gone unbilled for more than 21 days, and completed deployments with any unbilled report. It never generates or sends an invoice. Workflow triggers: **Deployment Created / Status Changed / Roster Changed / Expense Added / Attachment Added** and **Time Report Created / Submitted / Approved / Voided**. ## Setup examples | Organization | Finance mode | Notes | |---|---|---| -| **Municipal fire — strike team** | Cost recovery | Create from the Records external order; prefill roster; DTRs per day; Cal OES F-42 from the deployment (California) or the DTR PDFs for an EMAC / state reimbursement package. | +| **Municipal fire, strike team** | Cost recovery | **New external order** from the IROC or state order with one fill per crew member; the roster fills in as fills are accepted. DTRs per day. Cal OES F-42 from the deployment (California), or the DTR PDFs for an EMAC / state reimbursement package. Mark fills *Returned* when the crew is home, then complete the deployment. | | **Wildland contractor** | Billable | Wizard from an accepted bid; seats keyed on NWCG codes; DTRs signed by the agency rep each day; generate the invoice and packet weekly. | -| **Private ambulance — event medical** | Billable | Manual deployment linked to the standby call; crews file time in the Responder app; expenses for supplies. | +| **Private ambulance, event medical** | Billable | Manual deployment linked to the standby call; crews file time in the Responder app; expenses for supplies. | | **SAR / CERT** | Operational only | Mission deployments for after-action documentation; hours per volunteer for grant reporting via the time CSV export. | -| **Security company — event** | Billable | One deployment per event contract; guard hours per DTR; supervisor premium from the rate schedule. | -| **Industrial ERT — plant turnaround** | Operational only or Cost recovery | Internal chargeback: time CSV plus a cost run. | +| **State EMA** | Cost recovery | External orders with role *Requesting resources* for EMAC missions received, or *Hosting incident* for incoming teams; snapshots each time the mission order is amended. | +| **Security company, event** | Billable | One deployment per event contract; guard hours per DTR; supervisor premium from the rate schedule. | +| **Industrial ERT, plant turnaround** | Operational only or Cost recovery | Internal chargeback: time CSV plus a cost run. | ## Technical reference | Item | Value | |---|---| -| Routes | `/User/Deployments/{Index,New,Edit,View?tab=roster\|time\|expenses\|files\|billing\|costs,FromExternalOrder,TimeReport}`; POST `SetStatus`, `AddUnit/RemoveUnit`, `AddPersonnel/RemovePersonnel`, `AddEquipment/ReturnEquipment`, `NewTimeReport`, `SaveTimeReport`, `SignTimeReport`, `ApproveTimeReport`, `VoidTimeReport`, `SaveExpense`, `UploadAttachment`, `GenerateManifest`, `ExportTimeEntries`, `GenerateInvoice` | -| Model | `Deployment` (finance mode, status, identifiers, jurisdiction, `RmsExternalOrderId`), `DeploymentUnit`, `DeploymentPersonnel`, `DeploymentEquipment`, `DeploymentTimeReport` (pre-numbered per department), `DeploymentTimeEntry`, `DeploymentExpense`, `DeploymentAttachment` | -| Permissions | *Manage deployments* (118), *Approve time reports* (119) — default department administrators; rostered members see their own deployments and file DTRs without either | -| Flag | `Operations.Deployments` (free); `Records.System` needed for *Create from external order* | +| Routes (deployments) | `/User/Deployments/{Index,New,Edit,View?tab=roster\|time\|expenses\|files\|billing\|costs,FromExternalOrder,TimeReport}`; POST `SetStatus`, `AddUnit/RemoveUnit`, `AddPersonnel/RemovePersonnel`, `AddEquipment/ReturnEquipment`, `NewTimeReport`, `SaveTimeReport`, `SignTimeReport`, `ApproveTimeReport`, `VoidTimeReport`, `SaveExpense`, `UploadAttachment`, `GenerateManifest`, `ExportTimeEntries`, `GenerateInvoice` | +| Routes (external orders) | `/User/DeploymentOrders/{Index,New,Details,Artifact,ForRecord}`; POST `New`, `Link` (open deployment workspace), `AddFill`, `Transition`, `Snapshot`, `Closeout`. Connectors: `/User/RecordDeploymentConnectors/{Index,New,Edit}` | +| Model | `Deployment` (finance mode, status, identifiers, jurisdiction, `RmsExternalOrderId`), `DeploymentUnit`, `DeploymentPersonnel` (`RmsExternalOrderFillId`), `DeploymentEquipment`, `DeploymentTimeReport` (pre-numbered per department), `DeploymentTimeEntry`, `DeploymentExpense`, `DeploymentAttachment`; external orders `RmsExternalOrder`, `RmsExternalOrderFill`, `RmsExternalOrderSnapshot`, `RmsExternalOrderConnector` | +| Permissions | *Manage deployments* (118), *Approve time reports* (119), both defaulting to department administrators. Rostered members see their own deployments and file DTRs without either. External orders also need *Create records* to create or change them. Connectors are for department administrators only. | +| Flags | `Operations.Deployments` (free); `Records.System` plus Records activation for external orders and *Create from external order*; installation config `RecordsConnectorConfig.Enabled` for connectors | | Worker | 32 `DeploymentFinanceReminderLogic`, daily | -| Time zones | DTR times are incident-local (`Deployment.LocalTimeZoneId`, else the department zone) and stored UTC | -| Data protection | `Deployment.Notes` is the only ADP-protected field (reveal on view/edit); DTRs, expenses and attachments are not protected because customers read them | -| API | `api/v4/Deployments/*`, `api/v4/TimeReports/*` (mobile DTR capture) | +| Time zones | DTR times are incident-local (`Deployment.LocalTimeZoneId`, otherwise the department zone) and stored in UTC | +| Data protection | `Deployment.Notes` is the only ADP-protected field (revealed on view/edit). DTRs, expenses and attachments are not protected because customers read them. | +| API | `api/v4/Deployments/*`, `api/v4/TimeReports/*` (mobile DTR capture). External-order commands: `POST api/v4/DeploymentOrders/{Create,AddFill,TransitionFill,Snapshot,Closeout}`. These require *Manage deployments* and *Create records*; `Create` also creates the linked deployment, and `TransitionFill` / `Closeout` bring it up to date. Request and response shapes match the former Records command URLs, which are no longer accepted. Reads stay at `GET api/v4/RecordDeployments/{List,Get,GetForRecord,Artifact}`. | +| Feed contract | `docs/architecture/rms-mutual-aid-order-feed-v1.md` (Core repository) | diff --git a/docs/web-app/business-ops/invoicing.md b/docs/web-app/business-ops/invoicing.md index dfae375..7acd1c4 100644 --- a/docs/web-app/business-ops/invoicing.md +++ b/docs/web-app/business-ops/invoicing.md @@ -11,11 +11,13 @@ Needs the **Business Ops** add-on, the *Business Operations* module switch and t ![Invoicing](/img/web-app/invoicing/index.png) + + ## The pages | Tab | What it is for | |---|---| -| **Invoices** | Outstanding and overdue balances, the invoice list with a status filter, **New invoice**. | +| **Invoices** | Outstanding and overdue balances, the invoice list with number and status filters, **New invoice**. The number filter finds part of an invoice number in the department's own [format](../department-settings#document-numbering), however it is typed. | | **Rate Cards** | What you charge per call: hourly unit or personnel time, flat fees, mileage, materials. | | **Aging** | Open balances grouped by how far past due they are. | | **Billing settings** | Your legal name, remit-to address, registrations, invoice footer and the **Online payments** tab. | diff --git a/docs/web-app/business-ops/overview.md b/docs/web-app/business-ops/overview.md index 92bb21e..4bc0d0b 100644 --- a/docs/web-app/business-ops/overview.md +++ b/docs/web-app/business-ops/overview.md @@ -9,12 +9,14 @@ title: Overview ![Workforce & Business Ops in the sidebar](/img/web-app/business-ops/navigation.png) + + ## The modules | Module | What it does | Free or add-on | |---|---|---| | [Certifications](certifications) | Catalog of certifications, licences, inspections and permits for **people and units**, expiry dashboard, role requirements with optional enforcement, continuing-education credits, compliance report. | Free | -| [Deployment Finance](deployment-finance) | A **deployment** wraps the units, personnel and equipment sent to an incident with daily time reports (DTRs), expenses, files and a manifest — for an operational record, a cost-recovery claim or a customer invoice. | Free | +| [Deployments](deployment-finance) (Deployment Finance) | A **deployment** wraps the units, personnel and equipment sent to an incident with daily time reports (DTRs), expenses, files and a manifest — for an operational record, a cost-recovery claim or a customer invoice. External resource orders (IROC, EMAC, CIFFC) are recorded and worked here too; each order creates its linked deployment. | Free | | [Invoicing](invoicing) | Customer billing profiles, rate cards, invoices with line items generated from calls, PDF and e-mail delivery, payments, accounts-receivable aging. | **Business Ops** add-on | | [Online Payments](online-payments) | Customers pay invoices online through the department's **own Stripe account**; Resgrid never holds the money. | Business Ops add-on | | [Rate Schedules](rate-schedules), [Contracts & Compliance](contracts-and-compliance), [Bids & Deployment Wizard](bids-and-deployment-wizard), [Contractor Billing](contractor-billing) | Explicit per-band contractor rate tables, service contracts with document requirements, priced bids that become a scheduled deployment call, and the billing engine that turns approved DTRs into an invoice and packet. | Business Ops add-on | @@ -33,11 +35,11 @@ The left sidebar has a collapsible **Workforce & Business Ops** group. Inside it | **Workforce** | Business Operations module on, Workforce or Pay Data entitlement, and you are an administrator or hold a workforce permission. Members who only need to answer their own demographic questionnaire see **My demographic response** instead. | | **Certifications** | You are an administrator or hold *View certifications*. | | **Invoicing** | *View invoicing* permission, the **Business Operations module switch** on and the `Invoicing.CustomerInvoicing` flag. A lapsed add-on still shows the pages, read-only. | -| **Deployment Finance** | The `Operations.Deployments` flag. Members see only deployments they are rostered on. | +| **Deployments** | The `Operations.Deployments` flag. Members see only deployments they are rostered on. **External orders** also need `Records.System`, an activated Records module and *Create records*. | | **Bids** / **Contracts** | Administrator or *Manage bids* / *Manage contracts*, module switch on and an active add-on with the `Invoicing.ContractorBilling` flag. | | **Cal OES MARS** | Module switch on and an active add-on with the `CostRecovery.CalOesMars` flag. Managers open the readiness dashboard; rostered members open their own action queue. | -Deployment Finance is deliberately **not** the same page as [Records → Deployments](../records/deployments): the Records page tracks the *external resource order* (IROC, EMAC, CIFFC); Deployment Finance tracks the *money and time* of the crew you sent. A Deployment Finance deployment can be created **from** a Records external order so the two stay linked. +**Deployments** is where deployments and external resource orders are created and run: recording an order (**Deployments → External orders → New external order**) creates its linked deployment, and the order's fills keep the roster and status up to date. [Records → Deployment reports](../records/deployments) is the read-only side: printable reports, manifests, time reports, documents and CSV/JSON exports, plus older orders that were never linked. ## Turning it on @@ -94,11 +96,11 @@ The add-on entitlement is read from the Billing API. On a self-hosted installati | Item | Value | |---|---| -| Controllers | `Invoicing`, `Certifications`, `Deployments`, `DeploymentWizard`, `RateSchedules`, `Contracts`, `Bids`, `CalOesMars`, `Workforce`, `BusinessOperationsBilling` (all `/User/...`); public `PayController` (`/pay/{token}`) | +| Controllers | `Invoicing`, `Certifications`, `Deployments`, `DeploymentOrders`, `DeploymentWizard`, `RateSchedules`, `Contracts`, `Bids`, `CalOesMars`, `Workforce`, `BusinessOperationsBilling` (all `/User/...`); public `PayController` (`/pay/{token}`) | | Entitlement | `IBusinessOperationsAccessService.CanUse{Invoicing,ContractorBilling,CostRecovery,Workforce,PayDataReporting}Async` — master flag `Business.Operations` + capability flag + module switch (`DepartmentModuleSettings.BusinessOperationsDisabled`) + an active `PaymentAddons` row of type `BusinessOperations` (4); fails closed, no grace | | Flags | `Business.Operations`, `Invoicing.CustomerInvoicing`, `Invoicing.OnlinePayments`, `Payments.StripeConnect` (operator only), `Operations.Deployments`, `Invoicing.ContractorBilling`, `CostRecovery.CalOesMars`, `Workforce.InternalCosting`, `Compliance.CaliforniaPayDataReporting` | | Permissions | 40–41 invoicing, 42–44 certifications, 74–78 workforce, 79 Cal OES MARS, 116–119 deployments / bids / contracts / time reports | | Workers | 29 invoice maintenance (every 15 min), 31 bid expiration, 32 deployment-finance + MARS reminders, 33 compliance expiry (all daily, early morning), 34 certification expiry (hourly tick, one sweep per department-local day), 49 pay-data readiness (daily) | | Workflow triggers | Invoices 52–57 and 94–95, contractor 74–86, certifications 23 and 87–93, 180–187 | -| API | `api/v4/Invoices`, `Certifications`, `Deployments`, `TimeReports`, `RateSchedules`, `ServiceContracts`, `Bids`, `CalOesMars`, `FieldCost` | +| API | `api/v4/Invoices`, `Certifications`, `Deployments`, `DeploymentOrders` (external-order commands), `TimeReports`, `RateSchedules`, `ServiceContracts`, `Bids`, `CalOesMars`, `FieldCost` | | Search | Invoices, rate cards, bids, contracts, deployments and certification types are indexed in [unified search](../search); MARS, workforce and time-report data are not | diff --git a/docs/web-app/business-ops/workforce.md b/docs/web-app/business-ops/workforce.md index 4b49cd5..f5a12ba 100644 --- a/docs/web-app/business-ops/workforce.md +++ b/docs/web-app/business-ops/workforce.md @@ -15,6 +15,8 @@ Identifiers, addresses, pay rates, earnings, demographic responses and export fi ![Workforce](/img/web-app/workforce/index.png) + + ## The pages The workforce home shows three panels — **Employer**, **Field costing** and **Pay data reporting** — with counts and links. diff --git a/docs/web-app/call-checkin-timers.md b/docs/web-app/call-checkin-timers.md index 1b0649e..802ce30 100644 --- a/docs/web-app/call-checkin-timers.md +++ b/docs/web-app/call-checkin-timers.md @@ -13,6 +13,8 @@ The Call Check-In Timer system is an accountability and safety feature that trac --- + + ## Overview When check-in timers are enabled on a call, a **Check-In Timers** panel appears on the View Call page. The panel shows a table with: @@ -77,7 +79,7 @@ Department admins configure default timers that apply to all calls (unless overr | **Duration (minutes)** | How often a check-in is required (e.g., 30 minutes) | | **Warning Threshold (minutes)** | Additional minutes after the duration before the timer goes Critical | | **Enabled** | Whether this config is active | -| **Active For States** | Optional; comma-separated list of personnel/unit state IDs — if set, the timer only activates when a dispatched entity is in one of these states | +| **Active For States** | Optional; comma-separated list of personnel/unit state IDs or status meanings (`b` + base type, e.g. `b3` for On Scene) — if set, the timer only activates when a dispatched entity is in one of these states | Admins can add and delete default timer configs from the **Dispatch Settings** section of **Department Settings**. @@ -108,6 +110,7 @@ The **Active For States** setting restricts when a timer is active based on the - **Personnel-based timers** (Personnel, IC, PAR, HazmatExposure, SectorRotation, Rehab): The timer activates if any dispatched person's current action type matches one of the allowed state IDs. - **UnitType timers**: The timer activates if any dispatched unit of the specified type is currently in one of the allowed states. - If **Active For States** is empty, the timer is always active regardless of entity states. +- The list also offers each status **meaning**, shown as *Any "On Scene" status*. A meaning matches every status with that [meaning](custom-statuses#status-meanings), built-in or custom, in any status set, so one timer covers unit types with different custom statuses. A status with no meaning never matches a meaning entry. --- diff --git a/docs/web-app/chat.md b/docs/web-app/chat.md index c842b6a..0113c60 100644 --- a/docs/web-app/chat.md +++ b/docs/web-app/chat.md @@ -11,6 +11,10 @@ Feature flag: `Chat.System` (free for all plans; used for staged rollout). If ch ![Chat](/img/web-app/chat/index.png) + + + + ## Where to find it - **Chat bubble** at the bottom-right of every web page opens a floating chat panel. @@ -43,7 +47,7 @@ Identities: people, **units** ("Engine 6" — the human sender is always recorde ## The Assistant -The Assistant is a conversational helper inside chat (and, when configured, over SMS and other messaging platforms). It understands commands such as *"set me responding"*, *"who is on shift tonight?"*, *"what calls are active?"*, *"page Station 2"*, and — when allowed — *"dispatch Engine 1 to the structure fire on Pine Ridge"*. Anything it does not recognise as a command is answered by a guard-railed language model that only has access to your department's data through Resgrid's own permissions. +The Assistant is a conversational helper inside chat (and, when configured, over SMS and other messaging platforms). It understands commands such as *"set me responding"*, *"who is on shift tonight?"*, *"what calls are active?"*, *"page Station 2"*, and — when allowed — *"dispatch Engine 1 to the structure fire on Pine Ridge"*. *"Close call C1445"* asks you to confirm first, and is refused while the call has an active incident command (close the command first). Anything it does not recognise as a command is answered by a guard-railed language model that only has access to your department's data through Resgrid's own permissions. The Assistant conversation is **text only**: attachments, reactions, pins and threads are disabled there. diff --git a/docs/web-app/checklists.md b/docs/web-app/checklists.md index b15a9ed..d203af6 100644 --- a/docs/web-app/checklists.md +++ b/docs/web-app/checklists.md @@ -13,6 +13,8 @@ Checklists are included with every Resgrid plan. The optional **Work Orders / Ma ![Checklists home](/img/web-app/checklists/index.png) + + ## Where to find it **Left menu → Checklists.** The module has five tabs across the top: diff --git a/docs/web-app/communication-tests.md b/docs/web-app/communication-tests.md index 7c079dd..0acb826 100644 --- a/docs/web-app/communication-tests.md +++ b/docs/web-app/communication-tests.md @@ -17,6 +17,8 @@ Admins define tests, run them on-demand or on a schedule, and then review per-us --- + + ## Overview A Communication Test consists of three components: diff --git a/docs/web-app/contacts.md b/docs/web-app/contacts.md index 44a2093..9c153bf 100644 --- a/docs/web-app/contacts.md +++ b/docs/web-app/contacts.md @@ -11,6 +11,8 @@ title: Contacts ![Contacts](/img/web-app/contacts/index.png) + + ## The contact list The list is a tree: **All Contacts**, **No Category** and one node per **category**. Categories carry a colour, a map icon and *Display on map* so key premises show on the [map](mapping). A category with contacts cannot be deleted — reassign them first. diff --git a/docs/web-app/custom-maps.md b/docs/web-app/custom-maps.md index 394d01f..838e1b3 100644 --- a/docs/web-app/custom-maps.md +++ b/docs/web-app/custom-maps.md @@ -19,6 +19,8 @@ Custom Maps are designed for: --- + + ## Overview A Custom Map consists of three nested layers: diff --git a/docs/web-app/custom-statuses.md b/docs/web-app/custom-statuses.md index 343335c..2a23cc0 100644 --- a/docs/web-app/custom-statuses.md +++ b/docs/web-app/custom-statuses.md @@ -11,6 +11,8 @@ title: Custom Statuses ![Custom statuses](/img/web-app/custom-statuses/index.png) + + ## Overview **Authorization:** `CustomStates_View` policy @@ -55,10 +57,10 @@ Each state set contains multiple detail options. At least one is required. | Button Color | Background color (hex) | | Text Color | Foreground color (hex, default #000000) | | Order | Display order | -| Base Type | Mapping to a standard status for system behavior | +| Meaning | The option's [meaning](#status-meanings) (its base type): a status meaning for personnel and unit statuses, a staffing meaning for staffing levels | | GPS Required | Whether GPS location is required when setting this status | -| Note Type | Type of note required (None, Optional, Required) | -| Detail Type | Destination type (None, Calls, Stations, CallsAndStations) | +| Note Type | Whether a note is asked for (No Note, Optional, Required) | +| Detail Type | Destination type (No Detail, Stations, Calls, POIs, or a combination) | ### Detail Type Behavior @@ -66,10 +68,107 @@ The Detail Type determines what destination options appear when a user selects t | Detail Type | Behavior | |-------------|----------| -| **None** | No destination selection | +| **No Detail** | No destination selection | | **Calls** | Dropdown of active calls | | **Stations** | Dropdown of station groups | -| **CallsAndStations** | Dropdown of both calls and stations | +| **Calls and Stations** | Dropdown of both calls and stations | +| **POIs** | Dropdown of points of interest | +| **Calls and POIs**, **Stations and POIs**, **Calls, Stations and POIs** | Dropdown of the listed destinations together | + +### Base types + +The **Meaning** (base type) tells Resgrid what a status *means*, whatever you call it. It decides whether a unit or person counts as available to run cards, the nearest-units board, availability alerts and reports, and how calls track the status. + +| Counts as | Base types | +|---|---| +| **Available** | Available, Cleared, On Patrol, Completed, **In Quarters** | +| **Delayed** (still dispatchable) | On Break | +| **Committed** (busy on a call or task) | Responding, En Route, Dispatched, On Scene, Made Contact, Investigating, At Patient, Searching, Staging, Transporting, Delivering, At Hospital, Loading, Standby, Returning | +| **Unavailable** | Not Responding, Unavailable, Maintenance | +| No meaning | None — the status is a label only | + +![Editing a status option with the In Quarters base type](/img/web-app/custom-statuses/edit-option-in-quarters.png) + +**In Quarters** is *Available* plus one extra fact: the unit is at its station. Closest-unit run cards and the New Call nearest-units board then measure the unit from its **station's location** instead of its GPS position, and add the department's **in-quarters turnout time** (see [Run Cards](run-cards#how-closest-unit-mode-measures-a-unit)). Use it for statuses such as *In quarters* or *At station*; keep **Available** for units that are available but out on the road. + +:::tip +A status for a unit that is heading back but can already take a new call (for example *radiofonisch* in Belgian EMS, or *Available returning*) should use **Available**, not **Returning**. Returning counts as committed, so run cards and the nearest-units board treat the unit as busy. +::: + + + +## Status meanings + +An option's **Meaning** (stored as its base type) is what the option is, whatever its button says. Resgrid reads the meaning, never the button text, when it: + +- decides whether a person or unit is available, for dispatch recommendations, closest-unit [run cards](run-cards) and the New Call nearest-units board; +- sets a unit's status when it is dispatched to a call and when it is released (see [Unit status on dispatch and release](department-settings#unit-status-on-dispatch-and-release)); +- checks [notification](notifications#matching-statuses-by-meaning) rules on status and staffing changes, and the active states of [check-in timers](call-checkin-timers#active-for-states-filtering); +- times units against the [unit status timers](department-settings) and flags them on the Big Board. A unit in a status with no meaning is never timed, so give the status your units get on dispatch a meaning such as *Dispatched*; +- mutes dispatch notifications for the staffing levels you suppress, and counts statuses in reports and rollups; +- handles SMS replies to a dispatch, and shows and sets statuses in the Dispatch, Responder, Unit, Big Board and Incident Commander apps; +- colors unit and personnel pins on the map and in the apps ([icons by status and priority](mapping#icons-by-status-and-priority)). A status with no meaning set takes the color its name suggests, or shows a gray pin when the name suggests none. The [Map Icon Legend](mapping#map-icon-legend) lists each of your statuses under the color it takes, so a status listed under gray still needs a meaning. + +The built-in statuses and staffing levels already have a meaning. An option you add has none until you pick one. Resgrid treats an option with no meaning as **unknown**: it is neither available nor busy, dispatch and release never pick it, and a rule that targets a meaning doesn't match it. + +Personnel and unit statuses use the base types in the table above. Staffing levels have their own meanings: + +| Staffing meaning | Use it for | Counts as | +|---|---|---| +| **Available** | Can respond now. | Available | +| **Delayed** | Can respond, but later than usual (a break, a longer drive). | Delayed | +| **Unavailable** | Can't respond. | Unavailable | +| **Committed** | Busy with another assignment. | Committed | +| **On Shift** | Working at the station or post. | Available | +| **Off Duty** | Off duty and not expected to respond. | Unavailable | +| **On Call** | Away from the station but available when called. | Available | + +The built-in staffing templates come with their meanings filled in. The *On / Off Duty* template, for example, gives *On Duty* **On Shift**, *On Call* **On Call**, *On Break* **Delayed** and *Off Duty* **Off Duty**. + +### Finding options without a meaning + +The **Custom Statuses** list flags every set that has options without a meaning, for example **7 without a meaning**. The [Admin Assist](help-setup) setup report raises the same problem as **Status options have no meaning** and names the sets, counting only sets something reads (the personnel status and staffing sets, and unit sets assigned to a unit type). + +![Custom Statuses list with a "1 without a meaning" badge on Engine Statuses and "7 without a meaning" on Rescue Statuses](/img/web-app/custom-statuses/index-missing-meanings.png) + +Open the set with **Edit**. A warning above the options says how many have no meaning, and the **Meaning** column shows each option's meaning, in red when it is *None*. Where the button text gives a clear hint, the column also suggests a meaning, for example *None (suggested: En Route)* for *Enroute*. + +![Editing a unit status set: the missing-meanings warning and the Meaning column with suggestions](/img/web-app/custom-statuses/edit-meanings.png) + +**Use suggested meanings** puts every suggestion into the form and shows *Suggestions applied. Review them, then save.* The warning then counts only the options still without a meaning, and disappears when none are left. Nothing is saved yet. Check each one (here *At Location* was suggested as **On Scene**, like *On Scene* itself), then press **Update**. Resgrid never sets a meaning on its own. + +![The same set after Use suggested meanings, before Update](/img/web-app/custom-statuses/edit-meanings-suggested.png) + +To set or change a single option, press **Edit** on its row and pick its **Meaning**. The text under the picker explains the chosen meaning; *None* reads "No system meaning". + +![Editing one option: the Meaning picker set to None](/img/web-app/custom-statuses/option-meaning.png) + +Staffing levels have the same picker in the **New Option** dialog (on the New and Edit pages) and on each option's own page. + +![New Option dialog on a staffing set, with the staffing meanings listed](/img/web-app/custom-statuses/staffing-meaning.png) + +:::note Why it matters +One department's unit statuses had no meanings. Units in its *Dispatched* status showed as available, and units on a closed call were set to *Returning*. Giving each option a meaning, and setting the unit dispatch and release statuses to **Default** or a meaning, fixed both. +::: + +### Choosing meanings + +| Button text (examples) | Meaning | +|---|---| +| *Dispatched*, *Alerted*, *Toned* | Dispatched | +| *Responding*, *Code 3* | Responding | +| *Enroute*, *Mobile* | En Route | +| *On Scene*, *At Location*, *Arrived* | On Scene | +| *Patient Contact* | At Patient | +| *Transporting*, *To Hospital* | Transporting | +| *At Hospital* | At Hospital | +| *Back in Service*, *Radio Available* | Available (or Cleared) | +| *At Station*, *In Quarters* | In Quarters | +| *Out of Service*, *Mechanical* | Unavailable or Maintenance | +| Staffing: *Pager Only* | On Call | +| Staffing: *Holiday*, *Sick* | Off Duty or Unavailable | + +When several options share a meaning, Resgrid uses the first one by **Order** wherever it has to pick one (for example the dispatch status). Notification rules and reports count them all. ## Editing Custom States @@ -120,8 +219,8 @@ When no custom states are defined, the system provides built-in defaults: | Department type | How to set it up | |---|---| -| **Volunteer fire** | Personnel: Standing by, Responding to station, Responding to scene, On scene, Available at station, Not responding. Staffing: Available, Unavailable, On call. Units (Engine/Ladder/Rescue): In quarters, En route, On scene, Available, Out of service. | -| **EMS** | Units (Medic): Available, En route, On scene, Transporting, At hospital, Returning, Out of service; personnel: On duty / Off duty. | +| **Volunteer fire** | Personnel: Standing by, Responding to station, Responding to scene, On scene, Available at station, Not responding. Staffing: Available, Unavailable, On call. Units (Engine/Ladder/Rescue): In quarters (base type In Quarters), En route, On scene, Available, Out of service. | +| **EMS** | Units (Medic): At station (base type In Quarters), Available on the road (Available), En route, On scene, Transporting, At hospital, Returning, Out of service; personnel: On duty / Off duty. | | **SAR** | Personnel: Available, Responding to CP, At CP, Deployed in field, Returned; units (Team): Staging, Searching, Found, Returning. | | **Emergency management** | Personnel: EOC activated, Remote, Off; units minimal. | | **Security** | Personnel: On patrol, At post, Responding, Break, Off duty; units (Patrol): Available, Responding, On site, Out of service. | @@ -129,7 +228,7 @@ When no custom states are defined, the system provides built-in defaults: ## Technical reference -`CustomStatusesController`; routes `/User/CustomStatuses/{Index,Templates,New,Edit,EditDetail,Delete}?type=1|2|3`; model `CustomState` / `CustomStateDetail` (`DetailType`: none / station / call destination); JSON endpoints `GetPersonnelStatusesForDepartment`, `GetPersonnelStaffingLevelsForDepartment`, `GetUnitStatusesLevelsForDepartment?unitTypeId=`. +`CustomStatusesController`; routes `/User/CustomStatuses/{Index,Templates,New,Edit,EditDetail,Delete}?type=1|2|3`; model `CustomState` / `CustomStateDetail` (`DetailType`: none / station / call destination; `BaseType`: an `ActionBaseTypes` value, -1 None to 23 In Quarters, classified by `AvailabilityMatrix`); JSON endpoints `GetPersonnelStatusesForDepartment`, `GetPersonnelStaffingLevelsForDepartment`, `GetUnitStatusesLevelsForDepartment?unitTypeId=`. ### JSON API Endpoints These endpoints are **consumed by views throughout the application** for building dynamic status dropdowns: @@ -141,7 +240,18 @@ These endpoints are **consumed by views throughout the application** for buildin | `GetUnitStatusesLevelsForDepartment` | Unit statuses for a specific unit type | | `GetUnitStatusesLevelsForDepartmentCombined` | All unit statuses combined across types | -All endpoints support an `includeAny` parameter to add an "Any" option to the list. +All endpoints support an `includeAny` parameter to add an "Any" option to the list. With `includeMeanings=true` they also add one *Any "On Scene" status* entry per meaning, with the id `b` + the base type (for example `b3`); the notification editor uses these. `GetUnitStatusesLevelsForDepartmentCombined` also lists the built-in unit statuses (prefixed *Built-in:*) when some unit types have no custom set. + +### Meanings + +| Item | Value | +|---|---| +| Field | `CustomStateDetail.BaseType`: an `ActionBaseTypes` value for personnel and unit statuses, a `StaffingBaseTypes` value for staffing levels (-1 None, 0 Available, 1 Delayed, 2 Unavailable, 3 Committed, 4 On Shift, 5 Off Duty, 6 On Call; 0–4 equal the built-in staffing levels). Built-in options get theirs from `BuiltInStatusBaseTypes`. | +| Option page | `EditDetail` posts `BaseType` for personnel and unit options and `StaffingBaseType` for staffing options | +| Suggestions | `BaseTypeSuggestions.SuggestStatus(buttonText, type)`; shown on `Edit` for options with no meaning and written to the form only by **Use suggested meanings** (`#applySuggestedMeanings`). Saving is the normal **Update** | +| Templates | `CustomStateTemplateCatalog` (`/User/CustomStatuses/Templates`); every template option, staffing included, carries a meaning | +| Matching | Settings that match statuses store tokens (`StatusMatch`): a status value matches that status only, `b` + base type matches every status with that meaning, built-in or custom, in any set; `-1` is any. Integer lists (staffing suppression) store a meaning as -100 minus the base type | +| Availability | `AvailabilityMatrix` classifies a base type as available, delayed, committed or unavailable; -1 is unknown | ### Interactions with Other Modules | Module | Interaction | diff --git a/docs/web-app/data-protection.md b/docs/web-app/data-protection.md index 03f5544..f526df0 100644 --- a/docs/web-app/data-protection.md +++ b/docs/web-app/data-protection.md @@ -15,6 +15,8 @@ ADP is one control inside a HIPAA / privacy / ePCR compliance program that your ![Data protection](/img/web-app/security/data-protection.png) + + ## What is protected — and what is not | Protected (encrypted) | Stays plaintext | @@ -27,6 +29,7 @@ ADP is one control inside a HIPAA / privacy / ePCR compliance program that your - **Big Board** shows a reduced *protected incident* shell instead of call details. - **Workflows** receive redacted payloads by default. Administrators can approve a specific [Protected Workflow](protected-workflows) to send selected fields to one pinned HTTPS destination; every such disclosure is recorded in a hash-chained audit log. - **Text, email, push and voice notifications** send generic content by default (*"A protected dispatch is available — sign in to Resgrid"*). Relaxing a channel is a separate, acknowledged policy change. +- **If encryption is briefly unavailable** when a unit status is saved (the protection service cannot be reached), the status is still recorded and every dashboard, Big Board and Dispatch console still updates, but the app that sent it is told the save failed. The live update carries only the status itself — no note or position — so workflows and integrations never receive the unencrypted values. - Resgrid support cannot read protected values without an explicit, audited, department-approved support grant. Key loss is recoverable only through the documented recovery process. ## How members see protected data @@ -62,6 +65,10 @@ The **Protected Workflows** section of this page turns on the one deliberate exc The Data Protection page also hosts the member's **emergency contacts** for this department (name, relationship, phone, alternate phone, email, notes, primary flag), stored under the department's protection settings. +## Imports and ADP + +[Import & Migration](import-and-migration/overview) works in an enrolled department. Protected fields in an import — a person's ID number, department notes and home address, and a certification's number, area and issuer — are written through the same protection layer as the Resgrid screens, so they are encrypted from the moment they are saved, never stored in plaintext first. Uploaded files are always stored encrypted, and with ADP they are kept only **72 hours** after a successful import by default (instead of 7 days). Resgrid support never sees protected values through Import & Migration, whatever support access you grant. An import and an ADP migration window never run at the same time: each waits for the other to finish. + ## Setup examples | Department | Recommendation | diff --git a/docs/web-app/department-settings.md b/docs/web-app/department-settings.md index 992d3ee..c176d10 100644 --- a/docs/web-app/department-settings.md +++ b/docs/web-app/department-settings.md @@ -11,6 +11,12 @@ Only **department administrators** see these pages. Every change is audited. ![Department settings](/img/web-app/department/settings.png) + + + + + + ## General settings `/User/Department/Settings` @@ -18,17 +24,36 @@ Only **department administrators** see these pages. Every change is audited. | Setting | What it does | |---|---| | **Department name** | Shown everywhere, including notifications and prints. | +| **Organization type** | What kind of organization you are (volunteer fire, community paramedicine, security and patrol, multi-discipline response …), first chosen at sign-up. Change it here at any time. It is a description only: every template, Records pack, checklist and module stays available whatever you pick. If you do several kinds of work, pick the closest match and tick every sector in the [operating profile](help-setup#operating-profile), which drives setup suggestions. See [Organization types](#organization-types). | | **Time zone** | All times in the web site, apps, reports and schedules are shown in this zone. | | **Use 24-hour time** | Clock format. | | **Managing user** | The account owner — the only person who can change billing, purchase add-ons, enrol in data protection or delete the department. | | **Disable auto-available** | By default a member's status returns to *Available* an hour after they set something else; tick to stop that. | | **Personnel / unit / call sorting** | Default, first name, last name or group ordering on lists and the dashboard. | -| **Suppress (mute) for these staffing levels** | Members in the ticked staffing levels (e.g. *Unavailable*, *Off duty*) receive no dispatch notifications. | +| **Suppress (mute) for these staffing levels** | Members in the ticked staffing levels (e.g. *Unavailable*, *Off duty*) receive no dispatch notifications. The list also offers each staffing [meaning](custom-statuses#status-meanings), such as *Any "Off Duty" status*, which mutes every level with that meaning, built-in or your own. | | **Enable modern notification sounds** | Use the newer alert tones in the apps for everyone. | | **Require security PIN** | Force every member to confirm dangerous assistant / text actions with their 4-digit PIN. | | **Require password reset via email** | Administrators can no longer set a member's password; reset sends the member a single-use link. | | **TTS language** | Voice / dialect for voice dispatch prompts. | +### Organization types + +The list is grouped: + +| Group | Types | +|---|---| +| Fire and rescue | Volunteer Fire · Career Fire · Combination Fire · Wildland Fire · Search and Rescue · HAZMAT | +| EMS and health care | EMS · Private Ambulance and Interfacility Transport · Hospital and Health System · Community Paramedicine and Mobile Integrated Health · Crisis and Mental Health Response | +| Emergency management and community response | Emergency Management · Public Safety · CERT · Disaster Response · Relief Organization · Multi-Discipline Response | +| Security and events | Security · Event and Venue Operations | +| Industrial and utilities | Industrial Emergency Response · Oil and Gas · Power · Chemical · Nuclear · Other Industrial | +| Contractors and field services | Emergency Response Contractor · Drone and Aerial Survey · Repair Services · Delivery Services · Bus and Shuttle | +| Other | Other Public · Other Private · Other | + +What the type does **not** do: it never hides or limits Records template packs, checklist, command board, status or certification templates, modules, the dashboard or Admin Assist suggestions. Every department can use all of them. What it is used for: the workflow variable `{{ department.type }}` and, for Resgrid operators, feature-flag targeting. + +A department whose type came from an older sign-up list keeps it; the page shows it as the first option until you choose another. + ### Personnel staffing reset / status reset Automatically reset everyone's **staffing** (e.g. to *Available*) or **status** (e.g. to *Standing By*) at a time of day on chosen weekdays — typical for volunteer departments where people forget to clear *Unavailable*. @@ -49,6 +74,17 @@ The department's own address (a station or district office) is used to locate th ![Module settings](/img/web-app/department/module-settings.png) +## Terminology + +`/User/Department/Terminology` (**Department settings → Terminology**, also **Rename modules and record types** on Module settings) — use your department's own words. A name set here replaces Resgrid's name for that module or record type in the navigation, on page titles, wherever record types are listed and in the Responder, Unit, IC and Dispatch apps, for every member and in every language. Only the label changes: permissions, links and integrations are not affected. Leave a box empty to keep Resgrid's name. + +| Section | Names | +|---|---| +| **Modules** | Calls, Personnel, Units, Contacts, Mapping, Shifts, Records, Logs, Reports, Documents, Calendar, Notes, Trainings, Inventory, Readiness, Work Orders, Checklists, Workforce & Business. Shown in the navigation, as the title of the module's main page and in the apps' menus; sentences elsewhere that mention a module keep Resgrid's wording. | +| **Record types** | Run, Training, Work, Meeting, Coroner, Callback, Unit activity, NERIS incident report — the built-in Records and Logs types, wherever a type is chosen, listed, printed or exported. To add a type of your own, such as Public Education, create a [record definition](records/settings). | + +A name is up to 50 characters; invisible characters are removed and runs of spaces become one. A longer name is not saved and stays in its box for correcting (*Your other names were saved.*). Department administrators only. The apps read the names through `GET /api/v4/Config/GetTerminology`. [Import & Migration](import-and-migration/configure#names) can set them too, together with the rest of a migration's configuration. + ## Call & dispatch settings `/User/Department/DispatchSettings` @@ -59,13 +95,48 @@ The department's own address (a station or district office) is used to locate th |---|---| | **Group dispatch** | **Use shift for group dispatch** — dispatching a group sends only to the people signed up for today's shift. **Set status for shift personnel on dispatch** — automatically set them to a chosen status (default *Responding to scene*). | | **Unit dispatch** | **Also dispatch to assigned personnel** (the crew staffed on the unit) and/or **Also dispatch to entire group** (the unit's station). **Personnel on unit set unit status** — when a unit reports a status, its crew are set to *On unit*. | -| **Default call statuses** | The status personnel / units are set to when **dispatched** and when **released** from a call; per-unit-type overrides for types with custom statuses. | +| **Default call statuses** | The status personnel / units are set to when **dispatched** and when **released** from a call; per-unit-type overrides for types with custom statuses. The release status only moves units still working the call: a unit already back in service, out of service, unavailable or on a break (by its status's [base type](../configuration/custom-statuses)), or working another open call, keeps its status. **Close call when last unit clears** closes an active call on its own when its last dispatched unit reports back in service or out of service; see [Closing a call automatically](dispatch-calls#closing-a-call-automatically). The unit statuses are chosen by meaning; see [Unit status on dispatch and release](#unit-status-on-dispatch-and-release). | | **Rest period** | Deprioritise a unit or person for N minutes after a dispatch so the same resources are not sent back-to-back. | -| **New call form fields** | Which built-in fields appear on the New Call form and which are required (name, nature, priority and type are always shown and required). | -| **Unit status timers** | Highlight a unit on the Big Board when it has sat in a status too long (e.g. dispatched > 4 min without departing). | -| **Run cards & automatic dispatch** | Selection mode, auto-dispatch, minimum staffing, move-ups, closest-unit tuning (maximum location age, radius, include stale, order by driving ETA, shortlist size), station coverage minimums — see [Run Cards](run-cards). | +| **New call form fields** | Which built-in fields appear on the call forms and which are required (name, nature, priority and type are always shown and required). The same rules apply to the New Call, Edit Call and Add Archived Call pages and to the Dispatch, Responder, Unit and IC apps. A hidden field is left off the form, and editing a call keeps whatever it already holds for that field. A call saved as [pending](dispatch-calls#pending-and-scheduled-calls) skips the *dispatch list* and *dispatch on* requirements — the dispatcher picks recipients when sending it — and *dispatch on* is never required when editing a call or adding an archived one. *Plus Code* can be hidden but not required: it only finds the location and is not saved on the call, so require *GPS Coordinates* instead. | +| **Unit status timers** | Highlight a unit on the Big Board when it has sat in a status too long (e.g. dispatched > 4 min without departing). Dispatchers can acknowledge, mute or annotate the alert from the Big Board's Unit Alerts widget — see [Big Board](../apps/big-board). **Reason when acknowledging** makes that note required: *Optional* (default), *Required for alerts*, or *Required for warnings and alerts*. Timers key on a status's [meaning](custom-statuses#status-meanings): a status with no meaning is never timed, so the page warns when units are dispatched to one, or when a status set in use has options without a meaning. | +| **Run cards & automatic dispatch** | Selection mode, auto-dispatch, minimum staffing, move-ups, closest-unit tuning (maximum location age, radius, include stale, order by driving ETA, shortlist size, **in-quarters turnout** and **mobile turnout** in seconds), station coverage minimums — see [Run Cards](run-cards#how-closest-unit-mode-measures-a-unit). Turnout is added to travel time when units are ranked: in-quarters turnout for units in an *In Quarters* status or with no GPS position, mobile turnout for units ranked from their GPS. Both default to 0 (rank by distance only). | | **Check-in timers** | Auto-enable on new calls, default timer configs and per-type/priority overrides — see [Call Check-in Timers](call-checkin-timers). | + + +### Unit status on dispatch and release + +**Unit Call Dispatch Status** is set on every unit dispatched to a call. **Unit Call Release Status** is set on the units still working a call when it is closed or they are taken off it. Both are chosen by **meaning**, not by a status name, so one setting works for every unit type: each unit gets the first active option (by order) of its own status set with that meaning. Its own set is the custom status set of its unit type, or the built-in unit statuses when the type has none. + +![Unit dispatch settings: dispatch and release status set to Default, a warning listing Engine and Rescue, and the unit type overrides](/img/web-app/department/dispatch-settings-unit-status-meanings.png) + +| Choice | Dispatch | Release | +|---|---|---| +| **Default** (the setting until you change it) | Units with custom statuses get their *Dispatched* option, else *Responding*, else *En Route*. Units on the built-in statuses get *Responding*. | Units with custom statuses get their *Cleared* option, else *Available*, else *In Quarters*. Units on the built-in statuses get *Released*. | +| **Leave the unit's status unchanged** | Dispatch never changes the unit's status. | Release never changes the unit's status. | +| A **status meaning**, such as *Dispatched* or *En Route* | Each unit with custom statuses gets its own option with that meaning. Units on the built-in statuses get the matching built-in status (*Dispatched* sets *Committed*, *Cleared* sets *Released*, *In Quarters* sets *Available*); a meaning with no built-in match, such as *Transporting*, leaves them unchanged. | Same. | +| **Built-in status: … (saved before status meanings)** | Only shown when the department saved a built-in status before meanings existed. It keeps working: on the built-in statuses it is that status, and on a custom set it is read by its meaning (a saved *Responding* finds the set's Responding option). Pick a meaning to replace it. | Same. | + +![The dispatch choices: Default, Leave the unit's status unchanged and every status meaning](/img/web-app/department/dispatch-settings-unit-dispatch-choices.png) + +When a unit type's status set has **no option with the meaning**, its units keep their status and the page lists that unit type under **Check these unit types**, for example *Engine: its status set "Engine Statuses" has no status meaning Dispatched / Responding / En Route, so its units keep their status on dispatch.* Fix it by giving one of the set's options that meaning on [Custom Statuses](custom-statuses#status-meanings), or by picking a status for that unit type in the overrides. The list also names a set with **several options** with the meaning; the first by order is used, so check that it is the one you want. [Admin Assist](help-setup) raises unit types with no matching option as **Unit types cannot take the dispatch or release status** and names them. + +**Unit Type Status Overrides** still win: a unit type with its own dispatch or release status there gets that status, and isn't checked against the department-wide choice. Only unit types with custom statuses appear there. + +The release status still skips units that are already back in service, out of service, unavailable or on a break, or working another open call (see [Closing a call automatically](dispatch-calls#closing-a-call-automatically)). + +| Department | Dispatch | Release | +|---|---|---| +| Fire, one unit status set per apparatus type | **Default**, with a *Dispatched* or *Responding* option in every set | **Default**, with a *Cleared*, *Available* or *In Quarters* option in every set | +| Volunteer fire whose released units go back to the station | **Default** | **In Quarters**, so release sets *In Quarters* even when the set also has an *Available* option | +| EMS whose set has *Alerted* (Dispatched) and *Mobile* (En Route), where crews never press *Alerted* | **En Route**, so dispatch sets *Mobile* | **Available** (*Radio Available*) | +| Crews set every status themselves | **Leave the unit's status unchanged** | **Leave the unit's status unchanged** | +| Mixed: engines on a custom set, utility vehicles on the built-in statuses | **Default**, or **Responding** when the engines' set has a Responding option | **Default** | + +:::note Example +One department's unit status set had no meanings. Its units showed as *Available* while they were in its *Dispatched* status, and closing a call set them to *Returning*. Giving the options meanings and choosing **Default** (or a meaning) for dispatch and release fixed both. +::: + ## Call import settings `/User/Department/CallSettings` @@ -74,10 +145,141 @@ The department's own address (a station or district office) is used to locate th | Setting | What it does | |---|---| -| **Dispatch import email** | Your department's *all-call* address (`xxxx@dispatch.resgrid.com` on the hosted service). Anything mailed to it becomes a call dispatched to everyone with call notifications on. Forward your CAD pages here. | -| **Email format type** | The parser for your CAD's page format: Generic, Active911, IAmResponding, CalFire, Caliber, Dispatch Pro, Frontier Page, Hilton Head, IaFCDS, Oshkosh, Parkland County, Yellowhead County, Coast Guard, Brann Norge, Facility, Four Rivers, Ranch Kiowa, SpottedDog, County Fire, Carl EMS … Generic parses subject and body into name and nature. | -| **Prune calls / minutes to keep open** | Auto-close email/text/audio-imported calls after N minutes. | -| **Mail server (self-hosted)** | Hostname, port, SSL, username and password of a mailbox to poll. | +| **Dispatch import email** | Your department's *all-call* address, shown on the page. Anything mailed to it becomes a call dispatched to everyone with call notifications on. Forward your CAD pages here. See [Call import](../configuration/call-import). | +| **Email type** | The parser for your dispatch center's email: Generic, Resgrid, Generic Page, Connect, Four Part Pipe, Active911, R&R, OttawaCounty, OttawaKingstonToronto, Parkland Cty / Cty2, CAL FIRE ECC / SCU, Brockport, Hancock Cty, Carencro, Grand Blanc, Union Fire, Lowestoft, Spotted Dog, PortJervis, Yellowhead, plus Generic with AI enrichment for departments with Enhanced AI. Generic reads any email: subject as name, body as nature. See [Email types](../configuration/call-import#email-types). | +| **Prune calls / minutes to keep open** | Auto-close email/text/audio-imported calls after N minutes (checked hourly). | +| **Mail server** | Not on this page. Resgrid does not poll an outside mailbox; have your CAD or mail server forward dispatches to the dispatch import email instead. See [Call import](../configuration/call-import). | +| **Call numbering** | How new calls are numbered, and the next number. See [Call numbering](#call-numbering). | + +### Call numbering + +Every new call gets a number, shown in front of its name on the call list, the call, dispatches and reports. Out of the box the numbers are the two-digit year and a count that starts again each year: `26-1`, `26-2` … `26-153`. Set your own format to match your CAD or your state reporting, and carry on numbering you started before Resgrid. + +![Call numbering settings](/img/web-app/department/call-settings-numbering.png) + +| Setting | Meaning | +|---|---| +| **Call number pattern** | Fixed text around tokens, up to 40 characters. Letters, digits, `-`, `_`, `.` and `/` are kept as written. The example next to the box shows a sample number as you type. Default `{YY}-{SEQ}`. | +| **Sequence digits** | Pads the sequence with leading zeros, 1 to 8. `4` writes `0153`; `1` writes it without zeros, as the default numbers are. | +| **Numbering year starts** | The month and day your numbering year starts, and which year names it. January 1 (the default) is the calendar year. See [Fiscal year numbering](#fiscal-year-numbering). | +| **Next call number** | The number the next call logged now receives, and when the sequence starts again. | +| **Raise next sequence to** | Optional. The sequence the next call receives. See [Raising the next number](#raising-the-next-number). | + +The numbers are saved with the other Call Settings when you press **Update**. + +#### Pattern tokens + +| Token | Writes | +|---|---| +| `{YYYY}` or `{YY}` | The year, `2026` or `26`. With a fiscal year start, the fiscal year's name. | +| `{MM}` | The month, `01` to `12`. Needs a year token. | +| `{DD}` | The day of the month, `01` to `31`. Needs `{MM}`. | +| `{SEQ}` | The sequence number. Required, exactly once. | + +Dates are the date the call was logged, in your department's time zone. The sequence **starts again at 1 whenever the date in the number changes**: every year with a year token, every month with `{MM}`, every day with `{DD}`. A pattern with no date never starts again. + +| Pattern | Digits | Example | Starts again | +|---|---|---|---| +| `{YY}-{SEQ}` (default) | 1 | `26-153` | Each year | +| `FD-{YYYY}-{SEQ}` | 4 | `FD-2026-0153` | Each year | +| `{YYYY}{MM}{DD}-{SEQ}` | 3 | `20261006-012` | Each day | +| `{SEQ}/{YY}` | 5 | `00153/26` | Each year | +| `E{SEQ}` | 6 | `E000153` | Never | + +- Changing the pattern **never renumbers** calls that already have a number. +- A new pattern **starts its own sequence** at 1. To carry on from earlier numbers, raise its next number in the same or a later save. +- Going back to an earlier pattern carries on after the highest number already issued with it. +- A pattern that is not valid is not saved, and its message says why. The pattern stays in the box for correcting; the rest of the page still saves. +- Two calls logged at the same moment never share a number. A number that was issued is not issued again, even if its call is deleted. + +#### Fiscal year numbering + +Some departments number calls by a fiscal year, their own or a county's or state's they report to, instead of the calendar year. Set **Numbering year starts** to the month and day that year begins. A yearly pattern then starts again at 1 on that day, at midnight in your department's time zone, and `{YYYY}` and `{YY}` write the fiscal year's name. + +Choose which year names it: + +- **Named by the year it ends in** (the default, and the usual fiscal-year convention). A year starting November 1, 2026 is 2027, so with `{YY}-{SEQ}` the first call on November 1, 2026 is `27-1`. +- **Named by the year it starts in.** The same year is 2026, so that call is `26-1`. + +| Year starts | Named by | Call logged | `{YY}-{SEQ}` | +|---|---|---|---| +| January 1 (default) | Calendar year | January 1, 2027 | `27-1` | +| November 1 | Year it ends in | October 31, 2026 | `26-…` (FY2026 continues) | +| November 1 | Year it ends in | November 1, 2026 | `27-1` | +| November 1 | Year it ends in | January 15, 2027 | `27-…` (no restart on January 1) | +| July 1 | Year it starts in | July 1, 2026 | `26-1` | + +- The year start only applies to patterns that start again each year. A pattern with `{MM}` or `{DD}` always writes the calendar date and starts again each month or day. +- Call numbering and [record numbering](records/settings#numbering) each have their own year start, so dispatch can follow the calendar year while incident reports follow a fiscal year. +- February 29 can't be used as a start day, since not every year has one. +- Changing the year start never renumbers calls. If the new year's name matches numbers already issued (for example, moving to a November year named by the year it starts in, part way through the same calendar year), the sequence continues from the highest of those numbers instead of starting again, so no number is issued twice. +- A raised next number typed before the year start changes in the same save is not applied. Save the year start first, then raise the number for the new sequence. + +#### Raising the next number + +A department moving to Resgrid part way through a year can carry on its numbering. After issuing `FD-2026-0001` through `FD-2026-0153` in your old system, enter `154` in **Raise next sequence to** and press **Update**. The next call is `FD-2026-0154`. + +- The next number can only be **raised**, never lowered, so a number is never issued twice. Saving asks for confirmation first. +- A number below the one the next call already receives is refused, with a message naming that number. The pattern and the other settings still save. +- The raise applies to the sequence shown on the page. If you change the pattern in the same save, the raise is not applied; raise it again against the new pattern. +- A raise applies to the current period only. A yearly pattern starts again at 1 next year; a daily pattern starts again tomorrow. +- **Regenerate Call Numbers** on [Add archived call](dispatch-calls) renumbers the calls of the archived call's year in logged order with your pattern, starting each sequence at its raised number. With a fiscal year start that is the fiscal year the call falls in. It does nothing when the pattern has no year. + +## Document numbering + +`/User/Department/DocumentNumbering` (department menu **Document Numbering**) sets how Resgrid numbers **work orders**, **invoices**, **bids** and **daily time reports**, and when their numbering year starts. Call numbers are set under [Call numbering](#call-numbering), and Records numbers (including records requests, occupancies, inspections, permits, investigations and evidence) on [Records Settings](records/settings#numbering). + +![Document numbering settings](/img/web-app/department/document-numbering.png) + +| Document | Built-in numbers | Example | +|---|---|---| +| Work orders | `WO-{YYYY}-{SEQ}`, 6 digits, starting again each numbering year | `WO-2026-000019` | +| Invoices | A plain count that never restarts | `#1042` | +| Bids | A plain count that never restarts | `#7` | +| Daily time reports | A plain count that never restarts | `#3` | + +| Setting | Meaning | +|---|---| +| **Numbering year starts** | The month and day the numbering year starts, and whether it is named by the year it ends in (the default) or starts in. January 1 is the calendar year. Work order numbers, and any pattern with a year, start again at 1 that day. | +| **Pattern** | Leave it blank to keep the built-in numbers. Otherwise fixed text around `{YYYY}` or `{YY}`, `{MM}`, `{DD}` and `{SEQ}`, the same tokens as [call numbers](#pattern-tokens). The example under the box shows a sample as you type. | +| **Digits** | Pads the sequence with leading zeros, 1 to 8. | +| **Next number** | For a custom pattern, the number the next document receives and when the sequence starts again; for the built-in numbers, a sample. | +| **Raise next to** | For a custom pattern, carry on numbering from another system. It can only be raised. | + +| Goal | Pattern | Digits | First number | +|---|---|---|---| +| Invoices restart each fiscal year (year starts July 1) | `INV-{YYYY}-{SEQ}` | 4 | `INV-2027-0001` on July 1, 2026 | +| Maintenance numbers with the short year | `MNT-{YY}-{SEQ}` | 5 | `MNT-26-00001` | +| Bids numbered by month | `B{YYYY}{MM}-{SEQ}` | 3 | `B202611-001` | +| Keep invoice numbers, but padded | `{SEQ}` | 5 | `01043` after `#1042` | + +- Changing a pattern **never renumbers** documents that already have a number. +- A new pattern carries on after any number it would otherwise repeat: a padded `{SEQ}` continues after `#1042`, and `WO-{YYYY}-{SEQ}` with 4 digits continues after `WO-2026-000019`. +- A number of digits alone is shown with `#` in front, as invoice, bid and time report numbers always were; any other number is shown as issued. +- Work order numbers follow the numbering year even with the built-in pattern, so a July fiscal year writes `WO-2027-000001` on July 1, 2026. +- A pattern that is not valid, or could write a number longer than 50 characters, is not saved; that document keeps its numbering and the message names it. February 29 can't be a year start. +- Invoice, bid and time report records keep their plain number for ordering and the API (`InvoiceNumber`, `BidNumber`, `ReportNumber`); the number as issued is `DisplayNumber` in the API, workflow templates (`invoice.display_number`, `bid.display_number`, `deployment.report_display_number`), PDFs, emails, file names and search. + +## Terminology + +`/User/Department/Terminology` (department menu **Terminology**, also linked from Module settings and Records Settings) lets you use your department's own words. Type a name next to anything you want to rename; leave the box empty to keep Resgrid's name (shown greyed in the box). Names can be up to 50 characters. + +![Terminology settings with Run renamed Incident, Work renamed Shift On Duty and Units renamed Apparatus](/img/web-app/department/terminology.png) + +| Section | What you can rename | Where the name shows | +|---|---|---| +| **Modules** | Calls, Personnel, Units, Contacts, Mapping, Shifts, Records, Logs, Reports, Documents, Calendar, Notes, Trainings, Inventory, Readiness, Work Orders, Checklists, Workforce & Business | The left menu and the title of the module's main page | +| **Record types** | Run, Training, Work, Meeting, Coroner, Callback, Unit activity, NERIS incident report | Everywhere a record or log type is chosen, listed, printed or exported: the Records queue and **New** menu, record pages and prints, Records Settings, analytics, list exports, legacy Logs and log reports, the **Reports** menu on a call, record reminders and notifications, and Field Records in the apps | + +![Records list and type filter after the rename](/img/web-app/department/terminology-records.png) + +For example, a department can call Run **Incident**, Work **Shift On Duty** and Meeting **Officers Meeting**. To add a type of your own, such as **Public Education** or **Equipment / PPE Inspections**, create a [record definition](records/definitions) instead. + +- The name you set shows for every member, in every language. +- Only the label changes. Permissions, links, API values, workflow template keys such as `record.type_key`, and export template codes stay the same, so integrations keep working. +- Sentences elsewhere that mention a module in passing keep Resgrid's wording. +- The [Responder](../apps/responder#department-terminology), [Unit](../apps/unit#department-terminology), IC and [Dispatch](../apps/dispatch#department-terminology) apps use the same names in their menus, tabs, screen titles and Field Records. They load them when the app starts or someone signs in and keep the last names they received while offline, so a change made here shows the next time the app starts. The apps read them from `GET /api/v4/Config/GetTerminology`. +- An empty box always means Resgrid's own name in the member's language; the department's word is the same in every language. ## Text messaging @@ -97,6 +299,26 @@ The department's own address (a station or district office) is used to locate th `/User/Department/MappingSettings` — for personnel and units: **TTL in minutes** for locations shown on maps (0 = show forever) and **allow a status with no location to hide the previous location**. See [Mapping](mapping). +**Map Style** picks the Mapbox base map every map in your department shows — the website and the Dispatch, Responder, Unit, IC and Big Board apps on iOS, Android and web: + +| Setting | Choices | Notes | +|---|---|---| +| **Day map style** | Automatic (Streets); **Mapbox styles:** Streets, Outdoors (terrain), Light, Dark, Satellite, Satellite with Streets, Navigation Day, Navigation Night; **Community styles:** see below | Used on the website, and in the apps when the device is in light mode. | +| **Night map style** | Automatic, or any of the styles above | Used by the apps when the device is in dark mode. **Automatic** follows the day style: road maps go Dark, Navigation Day goes Navigation Night, and Outdoors, the satellite styles and every community style stay as they are. The website always shows the day style. | + +**Community styles** are the designer maps from the [Mapbox gallery](https://www.mapbox.com/gallery)'s community templates: American Memory, Basic, Basic Overcast, Blueprint, Bubble, Cali Terrain, Decimal, Finland Topo, Frank, Ice Cream, Lè Shine, Mineral, Minimo, Moonlight, Neon Glow, North Star, Pencil, Standard Oil Company, Mapbox Streets Japan and Unicorn. Several are artistic and show little street detail (Bubble, Neon Glow and Unicorn especially), so check the preview before using one for dispatch. Two gallery styles that Mapbox does not publish for use by other accounts (NASA's Black Marble, Water World) are not offered. + +Previews of both styles centred on your department appear under each picker. Apps pick up a change the next time they load their configuration (sign-in or app restart). If your Resgrid installation has no Mapbox token for the website, website maps keep the standard map and the style applies in the apps only; the page says so. The **Department Mapbox Override** (your own Mapbox style and public `pk.` token) takes precedence everywhere: the website and all the apps then render your custom style (in light and dark mode) on your token. + +The apps also receive the Mapbox token to use from the server when they load their configuration: your department's override token, or else the token your Resgrid installation configures for that app. Each app checks the token with Mapbox once, stores it on the device, and falls back to the token built into the app when none is sent or the token is invalid, expired or revoked — so a token can be rotated without an app update. + +| Department type | Suggested style | +|---|---| +| Wildland fire, SAR | Outdoors (terrain contours), or Satellite with Streets | +| Structure fire, EMS, transport | Navigation Day / Navigation Night for driving, or Streets | +| Dispatch centre wall displays | Light or Dark to keep pins and polygons high-contrast; Moonlight or Decimal for a minimal backdrop | +| Marine / coastal rescue | North Star (nautical chart look) | + ## API settings `/User/Department/Api` — view or **provision** the department **API key** (used by integrations and the apps' department login), and the **RSS active-call feed key**. Regenerating a key invalidates the old one immediately. @@ -111,9 +333,9 @@ The department's own address (a station or district office) is used to locate th ## Setup wizard -`/User/Department/SetupWizard` — for new departments: time zone → address → stations → units → email import → text messaging, saved in one step. Also reachable from the dashboard on first login. +Setup is no longer a pop-up on this page. **Department menu → Admin Assist** (the first item in the menu) opens the **Setup Wizard**, a nine-step journey, with **Setup Report**, **Explore Resgrid & Addons** and **Admin AI** beside it; an unfinished setup also shows a prompt on the dashboard. The wizard does not save settings itself. Its steps link to the pages above and the other setup screens: make the change there, use **Return to setup and verify**, then **Verify again**. `/User/Department/SetupWizard` now redirects to Admin Assist. See [Help & Setup](help-setup). -![Setup wizard](/img/web-app/department/setup-wizard.png) +Step 2 of the journey asks you to confirm the address and time zone on [General settings](#general-settings) and to fill in the **Department operating profile** (`/User/Department/OperatingProfile`): operating packs, workforce mix, dispatch model, operating hours, languages and accessibility, and links to approved local policies. The profile only suggests modules to review; see [Department operating profile](help-setup#operating-profile). ## Delete department @@ -124,8 +346,8 @@ The department's own address (a station or district office) is used to locate th | Department | Settings worth changing from the defaults | |---|---| | **Volunteer fire** | Staffing reset daily 06:00 → Available; email import from county CAD (pick the matching format); *Also dispatch to entire group* on unit dispatch; modern sounds on. | -| **Career fire** | Use shift for group dispatch; set status on shift dispatch; unit status timers 4/8 minutes; run cards auto-dispatch. | -| **EMS** | Default call statuses: dispatched → *Responding*, released → *Available*; rest period 10 min; require password reset via email. | +| **Career fire** | Use shift for group dispatch; set status on shift dispatch; unit status timers 4/8 minutes; run cards auto-dispatch; call numbers in the department's incident format, e.g. `FD-{YYYY}-{SEQ}` with 4 digits, raised to continue the year's numbers when moving to Resgrid. | +| **EMS** | Default call statuses: dispatched → *Responding*, released → *Available*; rest period 10 min; where turnout times are regulated (e.g. Belgian ambulances), in-quarters turnout 120 s and mobile turnout 30 s; require password reset via email; daily call numbers such as `{YYYY}{MM}{DD}-{SEQ}` where run sheets are filed by day. | | **SAR** | Disable auto-available; New Call form: make *what3words* / coordinates visible; longer location TTL (240 min). | | **Emergency management** | Modules: turn off Shifts and Inventory if unused; 24-hour time; text commands off. | | **Security / business** | Branding in emails; text-to-call from client alarm centres; suppress notifications for *Off duty*. | @@ -135,8 +357,9 @@ The department's own address (a station or district office) is used to locate th | Item | Value | |---|---| | Controller | `DepartmentController` | -| Routes | `/User/Department/{Settings,Profile,ModuleSettings,DispatchSettings,CallSettings,TextSettings,UnitSettings,ShiftSettings,MappingSettings,Api,Invites,SetupWizard,DeleteDepartment,ClearDepartmentCache}` | +| Routes | `/User/Department/{Settings,Profile,ModuleSettings,DispatchSettings,CallSettings,TextSettings,UnitSettings,ShiftSettings,MappingSettings,Api,Invites,OperatingProfile,DeleteDepartment,ClearDepartmentCache}`; `/User/Department/SetupWizard` redirects to `/User/AdminAssist/SetupWizard` (see [Help & Setup](help-setup#technical-reference)) | | Policy | `Department_Update` (administrators); managing-user checks for billing, ADP and deletion | -| Storage | `Department` row + `DepartmentSettings` rows keyed by `DepartmentSettingTypes` (e.g. 32 = ModuleSettings, 58–60 = run-card dispatch, 70–77 = Records settings) | +| Storage | `Department` row (organization type in `Department.DepartmentType`, text from `DepartmentTypeCatalog`) + `DepartmentSettings` rows keyed by `DepartmentSettingTypes` (e.g. 32 = ModuleSettings, 58–60 = run-card dispatch, 70–77 = Records settings, 115 = CallNumberingConfig: `Pattern`, `SequenceWidth` and the numbering year start `YearStartMonth` / `YearStartDay` / `YearLabel`, 117 = DocumentNumberingConfig: numbering year start and one pattern per document kind, 118 = DepartmentTerminology: the department's own names as `{Key, Text}` pairs, e.g. `module.units` / `record-type.run`). Custom document sequences live in `DocumentNumberSequences` (M0268). Call number sequences live in `CallNumberSequences`: one row per department and sequence (the text the pattern writes around `{SEQ}`), holding the last number issued and any raised next number | +| Unit dispatch / release status | Settings 50 (`UnitCallDispatchStatusToSet`) and 51 (`UnitCallReleaseStatusToSet`), read as a `StatusTarget`: -1 or unset = Default, -2 = leave unchanged, 1000 + an `ActionBaseTypes` value = that meaning (e.g. 1006 Dispatched, 1023 In Quarters), 0–999 = a built-in `UnitStateTypes` value saved before meanings (read by its meaning on custom sets). Resolved per unit by `StatusTargetResolver.ResolveUnit` (first active option by order; default chains Dispatched → Responding → En Route and Cleared → Available → In Quarters). Per-unit-type overrides are a separate setting and take precedence | | Cache | Settings cached up to a day; **Clear department cache** enqueues a cache-clear event | -| Data endpoints | `GetStationsForGrid`, `GetRecipientsForGrid`, `GetDepartmentTypes`, `GetCallEmailTypes`, `GetCallTextTypes`, `GetAvailableNumbers?country=&areaCode=`, `ProvisionNumber`, `GetSubscriptionLimitWarning`, `GetPrinterNetPrinters?key=` | +| Data endpoints | `GetStationsForGrid`, `GetRecipientsForGrid`, `GetDepartmentTypes` (organization type values), `GetCallEmailTypes`, `GetCallTextTypes`, `GetAvailableNumbers?country=&areaCode=`, `ProvisionNumber`, `GetSubscriptionLimitWarning`, `GetPrinterNetPrinters?key=` | diff --git a/docs/web-app/dispatch-calls.md b/docs/web-app/dispatch-calls.md index 1159bfb..6538348 100644 --- a/docs/web-app/dispatch-calls.md +++ b/docs/web-app/dispatch-calls.md @@ -9,6 +9,10 @@ title: Dispatch & Calls ![Calls dashboard](/img/web-app/dispatch/calls-dashboard.png) + + + + ## Where to find it **Left menu → Calls.** The Calls page shows: @@ -16,7 +20,8 @@ title: Dispatch & Calls - **Unit statuses** — every unit with its current state and when it changed. - **Active calls** — open calls with number, name, priority and time, plus **View**, **Update** and **Close** buttons. - A **map** of active calls and units. -- Buttons for **Routes**, **Archived calls**, **Scheduled calls** and **New Call**. +- **Pending calls** — a panel above Active calls, shown while any call is waiting for a dispatcher (see [Pending and scheduled calls](#pending-and-scheduled-calls)). +- Buttons for **Routes**, **Archived calls**, **Pending calls** and **Scheduled calls** (each with a count badge while calls are waiting) and **New Call**. ## Creating a call @@ -35,7 +40,7 @@ title: Dispatch & Calls | **Nature of the call** | The dispatch text; rich text supported. | | **Notes** | Additional notes. | | **Map page** | Map-book reference. | -| **Location** | Type an address and **Find Address**, enter a **what3words** address, enter latitude/longitude, or **Set pin on map**. Reverse geocoding fills the address from a pin. | +| **Location** | Type an address and **Find Address**, enter a **what3words** address, enter latitude/longitude, or **Set pin on map**. Reverse geocoding fills the address from a pin. A call saved with an address but no pin is geocoded when it is created, so run cards and maps still get a location. | | **Destination** | A point of interest such as a hospital, shelter, transfer centre or staging area (from [Mapping → POIs](mapping#points-of-interest)). | | **Indoor location** | A zone from an [indoor map](indoor-maps). | | **Protocols** | Matching [dispatch protocols](protocols) are listed; answer their questions to attach guidance. | @@ -43,9 +48,12 @@ title: Dispatch & Calls | **Personnel / Groups / Roles / Units tabs** | Who to dispatch (see below). | | **Call template** | Load a [quick template](templates) to pre-fill the form. | | **Check-in timers** | Enable [accountability timers](call-checkin-timers) for this call. | -| **Schedule dispatch** | Delay the dispatch to a future time (at least 15 minutes ahead) — the call appears under *Scheduled calls* until then. | +| **Schedule dispatch** | Delay the dispatch to a future time (at least 15 minutes ahead) — the call appears under *Scheduled calls* until then and is sent automatically at that time. | +| **Save as pending** | Save the call without dispatching it: nobody is notified and it waits under *Pending calls* until a dispatcher sends it. Any recipients you tick are kept as the proposed dispatch. Overrides *Schedule dispatch*. | | **Custom fields** | Any [User Defined Fields](user-defined-fields) configured for calls. | +![Schedule dispatch and Save as pending on New Call](/img/web-app/dispatch/new-call-save-as-pending.png) + ### Who gets dispatched Tick any combination of: @@ -57,9 +65,29 @@ Tick any combination of: | **Roles** | Every member holding a role (e.g. *Driver*, *Paramedic*). | | **Units** | Apparatus and their crews. | -If [Run Cards](run-cards) are enabled, the recommendation for the call's priority/type is pre-filled here (or dispatched automatically). +If [Run Cards](run-cards) are enabled, the recommendation for the call's priority/type is pre-filled here (or dispatched automatically). The recommendation panel refreshes when you change the priority or type and again as soon as the call is placed (Find Address, what3words, a map click or dragging the pin), so you can pick the type first and the location second. Units it recommends show their distance and, in closest-unit mode, their response time in minutes. + +### Nearest units + +Once the call has a location, the **Nearest Units** table lists every unit you may see (a unit can be a team, an apparatus or an individual): + +![Run card recommendation and Nearest Units for a placed call](/img/web-app/dispatch/new-call-nearest-units.png) -Press **Create Call**. Notifications go out immediately through the queue: push to the apps, SMS, email and voice according to each member's [notification preferences](profile-account#notifications) and [contact verification](../configuration/contact-verification) status. Notification text is generic when the department is enrolled in [Advanced Data Protection](data-protection). +| Column | Shows | +|---|---| +| **Unit** | Name, unit type, station and service area, and a badge when the call is inside the unit's own (or parent) boundary. | +| **Status** | Current status, green when available. | +| **ETA** | Time to the call. When the department sets [turnout times](run-cards#how-closest-unit-mode-measures-a-unit) it is the full response time, with *incl. N s turnout* underneath. *est.* marks a straight-line estimate; without the mark it is a routed drive time (Dispatch Settings → *Order by driving ETA*). Distance in km below. | +| **Position** | *Live GPS* or *Station location*. A unit in an **In Quarters** status, or with no GPS position, is placed at its station. A GPS position older than the maximum location age is marked **stale**. | +| **Shift / Role mix** | Crew on shift and the roles they hold. | + +Available units come first, ordered by response time — the fastest unit is at the top. A stale position is flagged on the row but does not push the unit down the list. Units with no position at all, and unavailable units, come last. + +![The New Call map drawing only available units](/img/web-app/dispatch/new-call-map-available.png) + +The call map draws only the **available** units and personnel, colored by their status, so it shows who can be sent. Busy and unavailable resources are left off the map but stay in the dispatch lists with their status, so a dispatcher can still pick one to reassign. **Update Call** and the [Dispatch app's](../apps/dispatch) New Call and Edit Call maps work the same way. + +Press **Create Call**. Notifications go out immediately through the queue: push to the apps, SMS, email and voice according to each member's [notification preferences](profile-account#notifications) and [contact verification](../configuration/contact-verification) status. Notification text is generic when the department is enrolled in [Advanced Data Protection](data-protection). A call saved as pending or scheduled for later sends nothing until it is dispatched, and opens on the *Pending calls* page instead of the Calls dashboard. ## Working an active call @@ -78,14 +106,98 @@ Press **Create Call**. Notifications go out immediately through the queue: push | **Incident report** | Start the [NERIS incident report](records/incident-reports) or a [Run record](records/authoring). | | **Export** | Printable call export, PDF, and a shareable anonymous export link. | -**Update** changes any field, adds or removes dispatch targets (only the differences are applied) and can **rebroadcast** the notification. **Close** asks for a **close state** (Completed, Cancelled, Unfounded, False alarm …) and closing notes. Closed calls move to **Archived calls** and can be **re-opened**. +**Update** changes any field, adds or removes dispatch targets (only the differences are applied) and can **rebroadcast** the notification. When the department uses [Run Cards](run-cards), a **Run card** panel above the dispatch lists shows what the call's run card still needs at its current alarm level, after the units and people already on the call; it follows the priority, type and location on the form, so changing them before saving updates it. **Select recommended** ticks those units and people in the lists; nothing is ticked on its own, so saving another change never adds resources, and nothing is sent until you save. **Close** asks for a **close state** (Completed, Cancelled, Unfounded, False alarm …) and closing notes. Tick **Send notification** to tell everyone on the call that it is closed: the personnel, groups and roles it was dispatched to (Responder app, text and email per their notification settings), its units (Unit app) and the incident command team — commander, people holding incident roles, and the people and units on the command board (Incident Command app). The notice names the call and how it was closed; the closing notes are not sent. Closed calls move to **Archived calls** and can be **re-opened**. + +![Close call](/img/web-app/dispatch/close-call.png) + +A call that is being run under an **active incident command** cannot be closed from here, the API, the chatbot or the auto-close job: close the command first. In the Incident Command app, **End Command** has an **Also close the call** option (with its own *Notify everyone on the call* switch) that closes the call right after the command; offline, both are queued and the call closes only once the command has. + +![Close call refused while an incident command is active](/img/web-app/dispatch/close-call-incident-command.png) + +### Closing a call automatically + +With **Close call when last unit clears** on ([Dispatch Settings](department-settings#call--dispatch-settings), off by default), an active call closes on its own when the last unit dispatched to it goes from working the call to back in service or out of service: a status whose [base type](../configuration/custom-statuses) is Available, In Quarters, Cleared, Completed or On Patrol, or Unavailable, Not Responding or Maintenance. An ambulance going *On Scene, Departing to Hospital, Arrived Hospital, Radio Available* closes the call when it reports *Radio Available*, as long as every other unit on the call has also cleared. + +The call stays open for the dispatcher to close when: + +- another unit on the call is still working it (returning, transporting, at the hospital), or has not reported a status since it was dispatched; +- the call has an active incident command, or no unit was dispatched to it (only units count, not personnel, groups or roles); +- the status has no base type, or the unit was not working the call (an available unit going out of service closes nothing); +- the status was set by Resgrid itself (dispatch and release statuses), or is an offline status replayed later. + +The call is closed as **Closed** with a note naming the last unit, by the member who set that status. Release statuses are applied as on any close (units that cleared keep their statuses), the **Call Closed** workflow trigger fires, and nobody is notified. Calls where units skip statuses (no patient found, false alarm, patient deceased on scene) are still closed by the dispatcher. + +Closing a call, by hand or automatically, never overrides a unit someone took out of service: the [release status](department-settings#call--dispatch-settings) only moves units still working the call. **Delete** soft-deletes a call with a reason (it can be restored by support). -## Archived and scheduled calls +### Which call a status belongs to + +Crews often set a status without choosing a call: they tap *On Scene* and carry on. Resgrid then puts the status on the call the unit or person is working, so it shows on that call's record and counts toward its times. In order: + +1. **A call they chose** is kept. +2. **The call of their previous status**, while that call is open and the previous status did not clear it. *On Scene* after *Responding* to call 26-153 goes on 26-153, and so does the *Available* that ends it (that records when the unit cleared). +3. **The one open call they are dispatched to**, for a status that is not itself a clear. Calls their last clear already ended are left out: + - a clear that named a call ended that call; + - a clear that named no call (back in quarters, available at a station, or no destination at all) ended every call they had been sent to before it. Only a dispatch, or a re-dispatch, after that clear is new work. + + With more than one call left, the status is not linked to any. + +A *clear* is a status whose [base type](../configuration/custom-statuses) is Available, In Quarters, Completed, On Patrol, Cleared, Returning, Unavailable, Not Responding or Maintenance, plus the built-in unit statuses Available, Unavailable, Out of Service, Returning, Cancelled and Released and the built-in personnel statuses Available, Not Responding and Available Station. + +For example, Medic 12 is dispatched to 26-153, clears *In Quarters* at its station while 26-153 stays open for the engine, then reports *Responding* without picking a call. That status is not put on 26-153. If Medic 12 has been dispatched to 26-160 since it cleared, the status goes on 26-160. + +Some statuses are placed differently: + +- A person put on a unit by a unit status goes on that unit status's call. +- A [scheduled call](#pending-and-scheduled-calls) counts only once it has gone out or its dispatch time has passed, and a pending call only once it is dispatched. Statuses set before then are not linked to it. +- A status replayed from an app's offline queue skips steps 2 and 3 when it arrives. The call record still shows statuses without a call that a dispatched unit or person set while working it, placed by their own time. + +The same rules pick the call a unit's next status starts on in the [Dispatch app](../apps/dispatch#personnel--unit-action-panels). + +## Pending and scheduled calls + +Two kinds of call can wait before anyone is notified: + +- **Pending calls** have no dispatch time. They wait until a dispatcher picks one up, chooses who to send it to and dispatches it — the typical use is follow-up work fed in from another system (a case-management or scheduling system, a referral line) or calls taken now for a team to pick up later. +- **Scheduled calls** have a dispatch time and are sent automatically when it arrives. + +Both show as count badges on the **Pending calls** and **Scheduled calls** buttons of the Calls dashboard, and pending calls also get a panel above Active calls (see the screenshot at the top of this page). + +**How a call becomes pending:** tick **Save as pending** on New Call (web or the [Dispatch app](../apps/dispatch)), or create it through the API with `"IsPending": true` (see [Technical reference](#technical-reference)). A pending call is numbered and saved like any other call, but: + +- nobody is notified, and dispatch statuses are not applied; +- it does not appear in the active calls lists, on maps, the Big Board or the Responder and Unit apps; +- it does not count as active or archived; it is listed only under **Pending calls**; +- the New Call form's dispatch-list and dispatch-time requirements (Department Settings → *New call form fields*) do not apply to it — the dispatcher chooses recipients when sending it; every other required field still does. + +**Pending calls page** (the **Pending Calls** button on the Calls page, or **View all** on the dashboard panel) lists waiting calls oldest first with **View**, **Update**, **Dispatch Now**, **Close** and **Delete**. + +![Pending calls](/img/web-app/dispatch/pending-calls.png) + +**Working a pending call** + +| Action | What happens | +|---|---| +| **View** | The call page shows a *Pending* banner and a **Dispatch Now** button; Re-Open and Strike Alarm are not offered. | +| **Update** | Edit any field and pick who to send it to. Saving keeps it pending and notifies nobody; **Save and Dispatch Now** saves and sends it in one step. | +| **Dispatch Now** | Sends the call to everyone on its dispatch list. If the list is empty you are taken to *Update* to choose recipients first. | +| **Schedule** | Give it a *Schedule dispatch* time on *Update*: it becomes a scheduled call. | +| **Close** | Cancel it (or close it with any close state) without notifying anyone. | + +![A pending call: banner and Dispatch Now](/img/web-app/dispatch/view-call-pending.png) + +**When a waiting call is dispatched** it becomes an active call, its dispatch time is recorded separately from the time it was received, run card auto-dispatch is applied, notifications go out, and dispatch statuses are set. For a pending call this is also when the **Call Added** [workflow](workflows) trigger fires and the call's incident chat channel is created (when chat is on), not when it was saved. + +**Scheduled calls page** (the **Scheduled Calls** button on the Calls page) lists calls waiting for their time, with **View**, **Update**, **Dispatch Now** (send early), **Close** and **Delete**. A scheduled call is sent within five minutes of its time by the scheduled-calls job. Adding or removing recipients before then notifies nobody — the updated list is used when it goes out. Until then the units and people on its list are not on the call: a status they set is not [linked to it](#which-call-a-status-belongs-to), and it is not the call a unit's next status starts on in the Dispatch app. A scheduled call closed before its time is never sent. + +![Scheduled calls](/img/web-app/dispatch/scheduled-calls.png) + +The [Dispatch app](../apps/dispatch) has the same two lists, with tiles on its console. + +## Archived calls -- **Archived calls** — closed calls by year, with view and export. **Add archived call** creates a historical call with a custom date and pre-set closed state (optionally recalculating the year's call numbers) — useful when importing history or logging a call that happened outside Resgrid. -- **Scheduled calls** — calls waiting for their scheduled dispatch time. +**Archived calls** — closed calls by year, with view and export. **Add archived call** creates a historical call with a custom date and pre-set closed state (optionally recalculating the year's call numbers with your department's [call number pattern](department-settings#call-numbering); not available for a pattern with no year) — useful when importing history or logging a call that happened outside Resgrid. New calls are numbered with that pattern too. Pending calls are never listed here. ![Archived calls](/img/web-app/dispatch/archived-calls.png) @@ -96,7 +208,7 @@ Press **Create Call**. Notifications go out immediately through the queue: push | **Email** | Send or forward CAD pages to your department's dispatch import address ([Call import settings](department-settings#call-import-settings)); choose the parser format for your CAD. | | **SMS / text** | Text to the department number ([Text messaging](department-settings#text-messaging)). | | **Dispatch app** | Same form on tablet or desktop. | -| **API** | `api/v4/Calls/SaveCall` with an API key or OAuth token. | +| **API** | `api/v4/Calls/SaveCall` with an API key or OAuth token. Add `"IsPending": true` to queue it under *Pending calls* for a dispatcher instead of dispatching it. | | **Workflows / Assistant** | Workflow actions and the chat Assistant can create calls when allowed. | | **Voice** | Automated voice dispatch reads the call out over the phone or radio TTS. | @@ -110,6 +222,7 @@ Press **Create Call**. Notifications go out immediately through the queue: push | **SAR** | Types Search, Rescue, Recovery, Training; dispatch to Roles (Team leader, K9, Technical rescue); what3words locations; long check-in timers for field teams. | | **Emergency management** | Types Activation, Weather, Shelter, Resource request; dispatch to Roles (ESF leads) and Groups (EOC sections); scheduled calls for planned activations. | | **Security / facilities** | Types Alarm, Patrol request, Escort, Medical, Incident; contacts for client sites with alert notes and gate codes; indoor locations. | +| **Behavioral health / crisis teams** | Types Crisis evaluation, Welfare check, Follow-up, Referral; follow-ups pushed from the case-management system as **pending calls** through the API, dispatched by a dispatcher to the closest team; teams as Units with Clinician and Peer seats; check-in timers on field visits; [Advanced Data Protection](data-protection) and the *42 CFR Part 2* consent flag. | | **Delivery / transit** | Types Delivery, Pickup, Breakdown, Route deviation; dispatch to Units (vehicles); destination POIs; link calls to [Routes](routes). | ## Technical reference @@ -117,12 +230,16 @@ Press **Create Call**. Notifications go out immediately through the queue: push | Item | Value | |---|---| | Controller | `DispatchController` | -| Routes | `/User/Dispatch/{Dashboard,NewCall,ViewCall,UpdateCall,CloseCall,DeleteCall,ReOpenCall,ArchivedCalls,AddArchivedCall,ScheduledCalls,CallData,CallExport,CallExportEx,CallExportPdf,GetCallDispatchAudio}` (`?callId=`) | +| Routes | `/User/Dispatch/{Dashboard,NewCall,ViewCall,UpdateCall,CloseCall,DeleteCall,ReOpenCall,ArchivedCalls,AddArchivedCall,ScheduledCalls,PendingCalls,CallData,CallExport,CallExportEx,CallExportPdf,GetCallDispatchAudio}` (`?callId=`); `DispatchCallNow` (POST, antiforgery, `callId`) | +| Call states | `CallStates`: 0 Active, 1 Closed, 2 Cancelled, 3 Unfounded, 4 Founded, 5 Minor, 6 Transferred, 7 False alarm, **8 Pending**. A scheduled call is Active with `DispatchOn` in the future and `HasBeenDispatched = false`. | +| Pending / scheduled | `IPendingCallsService` (`IsWaitingForDispatch`, `DispatchNowAsync`); scheduled calls sent by the worker `DispatchScheduledCallsTask` every 5 minutes (calls due in the last 15 minutes, active only) | +| Status linking | `ICallStatusAttributionService`: `AttributeUnitStateAsync` / `AttributeActionLogAsync` on save (rules 2 and 3 only for statuses at most five minutes old, `CallStatusAttribution.IsLiveStatus`), stored as `DestinationSource` (`StatusDestinationSources` Explicit, CarryForward, Dispatch, Unit); read-time `Inferred` statuses are never stored. Rules in `CallStatusAttribution` (`CanCarryForward`, `ClearedByPrevious`, `PickDispatchCall`); clears per `CallStatusLinkage.IsClearingUnitState` / `IsClearingPersonnelStatus`. Open dispatches from `ICallDispatchUnitRepository.GetOpenCallUnitDispatchesForUnitAsync` and `ICallDispatchesRepository.GetOpenCallDispatchesForUserAsync` (direct, group and role rows; time = `LastDispatchedOn` else `DispatchedOn`; active calls only, a scheduled call once `HasBeenDispatched` or `DispatchOn` ≤ now). The Dispatch app's starting call is v4 `UnitsInfoResultData.ActiveCallId` (`GetWorkingCallIdsForUnitsAsync` → `UnitCallInvolvement.ResolveWorkingCallId`); null means no single working call, not that the unit is unassigned. | | Policies | `Call_View`, `Call_Create`, `Call_Update`, `Call_Delete` + `IAuthorizationService.CanUser{Create,Edit,Close,Delete}CallAsync` | | Permissions | `CreateCall`, `DeleteCall`, `CloseCall`, `AddCallData` | | Events | `CallAddedEvent`, `CallUpdatedEvent`, `CallClosedEvent`; broadcast via `IQueueService.EnqueueCallBroadcastAsync` (push/SMS/email/voice) | -| Data endpoints | `GetActiveCallsList`, `GetArchivedCallsList?year=`, `GetScheduledCallsList`, `GetCallNotes`, `GetPersonnelForCall`, `GetAllDispatchesForCall`, `GetMapDataForCall`, `GetCallTypes`, `GetCallPriorities`, `GetCallsForSelectList`, `GetCoordinatesFromW3W`, `GetAlertNotesForContact`, `GetDispatchRecommendation`, `CallsYTD`, `CallsTypesInRange`, `CallsStatesInRange` | +| Closing | `ICallAutoCloseService` (setting 116 `CloseCallWhenUnitsClear`, run from `UnitsService.SetUnitStateAsync` for unit reports only; `UnitCallInvolvement.HasFinishedCall` = Available or Unavailable availability class). Release statuses skip units per `UnitCallInvolvement.KeepsStatusOnRelease` or on another open call. `ICallClosureService`: `GetBlockingIncidentCommandAsync` (an active `IncidentCommand` on the call blocks every close path: web, v4 `CloseCall`, chatbot, auto-close), `NotifyCallClosedAsync` (Send notification; push event code `NC:{callId}` — leads with `N` so it is sent as an ordinary notification, not a critical call alert — opens the call in the apps; Unit app gets the notification sound, never the dispatch tone; IC-app push for the command team) | +| Data endpoints | `GetActiveCallsList`, `GetArchivedCallsList?year=`, `GetScheduledCallsList`, `GetPendingCallsList`, `GetWaitingCallCounts`, `GetCallNotes`, `GetPersonnelForCall`, `GetAllDispatchesForCall`, `GetMapDataForCall`, `GetCallTypes`, `GetCallPriorities`, `GetCallsForSelectList`, `GetCoordinatesFromW3W`, `GetAlertNotesForContact`, `GetDispatchRecommendation`, `GetNearestUnits?latitude=&longitude=`, `CallsYTD`, `CallsTypesInRange`, `CallsStatesInRange` | | Attachments | 10 MB; images jpg/jpeg/png/gif/bmp; documents pdf/doc/docx/ppt/pptx/xls/xlsx/txt; audio mp3/m4a/ogg/wav; video mp4/m4v/mov/wmv/avi/mpg | | Soft delete | `IsDeleted`, `DeletedOn`, `DeletedByUserId`, `DeletedReason` | | Protected data | Name, nature, notes, address and attachments are ADP-protected fields | -| API | `api/v4/Calls/*` | +| API | `api/v4/Calls/*`. Pending and scheduled: `POST SaveCall` with `IsPending` (empty `DispatchList` = no proposed recipients; `"0"` = everyone; `DispatchOn` ignored), `GET GetPendingCalls`, `PUT DispatchCallNow` `{ "CallId", "DispatchList"? }` (pending or not-yet-sent scheduled call; 400 when it is not waiting or has nobody to send to), `GET GetAllPendingScheduledCalls`, `PUT UpdateScheduledDispatchTime`. Scheduled: `DispatchOn` (department local time) or `DispatchOnUtc` (UTC; wins when both are sent). `EditCall` accepts a pending call and notifies nobody; `CloseCall` takes close states 1–7 and `SendNotification`, and returns 400 while an incident command is active. Integrations can use a [department API key](../api/authentication#department-api-keys) instead of a member's login. | diff --git a/docs/web-app/distribution-lists.md b/docs/web-app/distribution-lists.md index 998cedf..1aefd5d 100644 --- a/docs/web-app/distribution-lists.md +++ b/docs/web-app/distribution-lists.md @@ -9,6 +9,8 @@ Distribution Lists manage email distribution groups for the department. The modu ![Distribution lists](/img/web-app/distribution-lists/index.png) + + ## Distribution List Management **Authorization:** `Department_Update` policy diff --git a/docs/web-app/documents.md b/docs/web-app/documents.md index e671847..7d8aaad 100644 --- a/docs/web-app/documents.md +++ b/docs/web-app/documents.md @@ -11,6 +11,8 @@ title: Documents ![Documents](/img/web-app/documents/index.png) + + ## Document List **Authorization:** `Documents_View` policy diff --git a/docs/web-app/groups-stations.md b/docs/web-app/groups-stations.md index b786d6b..8629363 100644 --- a/docs/web-app/groups-stations.md +++ b/docs/web-app/groups-stations.md @@ -9,6 +9,8 @@ title: Groups & Stations ![Groups](/img/web-app/groups/index.png) + + ## Where to find it **Department dropdown → Stations and Groups** (`/User/Groups`). The list shows every group with type, parent, members and **Edit** / **Geofence** / **Delete** buttons. @@ -27,6 +29,10 @@ title: Groups & Stations | **PrintNode printer / Print calls to printer** | With a PrintNode account, calls dispatched to this group's members or units are printed on the station printer. | | **Group admins / Group users** | Assign members. A person can be in **one group only**. | +:::tip Have a spreadsheet? +To create all your stations and groups at once — with addresses and parent groups — use [Import & Migration](import-and-migration/overview) (**Department menu → Import & Migration**, department administrators, where it is turned on). Every row is checked and previewed before anything is saved. See the [Stations and groups field reference](import-and-migration/stations-and-groups). +::: + ## Geofence (response area) **Geofence** on a station opens a map; click to draw the boundary of the station's first-due area and pick a **district colour**. Geofences are used by: diff --git a/docs/web-app/help-setup.md b/docs/web-app/help-setup.md index 13fd404..f0a5ba6 100644 --- a/docs/web-app/help-setup.md +++ b/docs/web-app/help-setup.md @@ -5,40 +5,137 @@ title: Help & Setup # Setup Wizard, Setup Report and Admin Assist +**Admin Assist** is where department administrators set Resgrid up and check that the setup is working. It walks you through a nine-step setup journey, shows a report of what is verified, what needs attention and what could not be checked, and explains every module and paid add-on. Nothing on these pages changes your configuration by itself: each change is made on its normal screen, and you come back to Admin Assist to check it. + +**Department menu → Admin Assist** (the first item in the menu). Department administrators only, when setup is enabled for your Resgrid installation. + + + + + + + + ## Start or resume setup -Department administrators can open **Setup Wizard** from the Department or Help menu when setup is enabled for the deployment. An unfinished setup also appears on the dashboard. Dismissing that prompt affects only your account; the menu remains available. Setup Wizard and Setup Report are available independently of Admin Assist and do not require an AI add-on. +Department administrators can open **Admin Assist** from the top of the Department menu when setup is enabled for the deployment. It opens on **Setup Wizard**, with **Setup Report**, **Explore Resgrid & Addons** and **Admin AI** beside it. An unfinished setup also appears on the dashboard. Dismissing that prompt affects only your account; the menu remains available. Setup Wizard, Setup Report and Explore do not require Admin AI or an AI add-on; the Admin AI tab stays disabled until Admin AI is enabled for the department. + +| Tab | What it is for | +|---|---| +| **Setup Wizard** | The [nine-step setup journey](#setup-journey). Your choices are saved as you go; pause and come back at any time. | +| **Setup Report** | Verified checks, checks needing attention and checks with unknown evidence for the modules you use, your next setup actions, a setup checklist per module, and the administrative review. See [Configure and verify](#configure-and-verify). | +| **Explore Resgrid & Addons** | Browse every Resgrid module, including ones your plan or menu does not show yet. Each module lists its key features and what to do first. Search, or tick **Show paid add-ons only**. | +| **Admin AI** | Disabled until Admin AI is enabled for the department. It then holds Overview, Health checks, the [Admin worklist](#follow-up), [Settings reference and Change history](#reference-and-history), and, where available for your department, Ask Admin Assist, Plans and Troubleshoot. | + +The dashboard prompt reads **Setup Wizard** with **Start or resume setup**, **Setup Report** and **Dismiss for me; setup stays available in the menu**. Besides dismissing it, the prompt goes away once a current administrative review is recorded (it comes back when the chosen review date arrives) or once you have marked every key feature as understood. + +The old setup pop-up, which saved the time zone, address, stations, units and call import in one step, has been removed; its old addresses (`/User/Department/SetupWizard`, `/User/Help/SetupReport`) now open Admin Assist. Setup Report also replaces the old numerical setup score. + +### Setup mode + +Step 1 asks how you are starting. Choose **Fresh setup**, **Review existing setup**, or **Import or migration**. The choice records your intent; it does not import or overwrite data. + +| Mode | Use it when | +|---|---| +| **Fresh setup** | The department is new to Resgrid. | +| **Review existing setup** | The department already runs on Resgrid and you want to check or extend its setup. | +| **Import or migration** | You are moving from another system. Import planning does not copy data: use the existing reviewed import tools, then verify the resulting configuration here. | + +**Import or migration** offers **Open Import & Migration** — *Bring data from your current systems with Import & Migration. Admin Assist then verifies the result.* — where you bring people, stations, apparatus and settings from spreadsheets or the system you are leaving; nothing is saved until you review and approve it (see [Import & Migration](import-and-migration/overview)). The button appears when Import & Migration is turned on for your department and you are a department administrator. + +Import & Migration is also one click away whatever you chose: Admin Assist shows an **Import & Migration** button in its toolbar on every tab, and an **Import & Migration** card (with **Open Import & Migration**) beside the review on **Setup Report** and **Admin AI → Overview**. Both appear only when Import & Migration is turned on for your department and you are a department administrator. + + + +## The nine-step journey + +The nine-step journey covers goals and applications, the department profile, all-area orientation, people and access, operational essentials, selected workflows, add-ons, verification and practice, and review and handover. Pause and resume without creating sample incidents or overwriting existing configuration. The step list shows each step's status (for example *Not set up yet*, *In progress*, *Needs attention*, *No open items found*), and **Previous step** / **Next step** move through it in order. + +| Step | Shown as | What you do | +|---|---|---| +| 1 | **Welcome and goals** | Choose the [setup mode](#setup-mode) and see how Resgrid's modules are grouped into Core modules, Recommended, Optional modules and Paid add-ons. | +| 2 | **Department profile** | Confirm the department address and time zone on [Department Settings](department-settings), then fill in the [department operating profile](#operating-profile) so Resgrid can suggest the modules that fit. | +| 3 | **Choose your modules** | Mark each module **Use now**, **Learn later** or **Not applicable**. See [Choose the modules your department uses](#choose-areas). | +| 4 | **People and access** | Personnel and groups, and department administration and security: add your members, stations, groups and roles, and make sure at least two administrators use two-factor sign-in. Invitations are sent only when you send them. | +| 5 | **Dispatch essentials** | The other core modules (dispatch and calls, units, notifications and messaging, apps and devices): call types, statuses, dispatch settings and call intake, your units, and making sure members can be reached through notifications and the Responder app. | +| 6 | **Your other modules** | The Recommended and Optional modules you marked **Use now**, such as shifts, training, records, checklists or inventory. | +| 7 | **Plan and add-ons** | Your subscription and capacity, and what each paid add-on adds. Nothing here purchases, starts a trial or switches anything on. See [Understand optional add-ons](#understand-addons). | +| 8 | **Verify and practice** | Open the Setup Report, fix what needs attention and look at anything that could not be verified. Run a [communication test](communication-tests) from its own screen when you are ready. | +| 9 | **Review and hand over** | Mark the report reviewed, choose a date to review it again and print a copy for your officers. Other administrators keep their own learning progress. | + +In steps 4 to 6, each module you use shows **Before you start** (what to have ready), how many of its key features are set up, each key feature with a link to the screen that configures it, and any of its checks that need attention or could not be verified. + + -Choose **Fresh setup**, **Review existing setup**, or **Import or migration**. The choice records your intent; it does not import or overwrite data. Use the department operating profile to describe your organization and link approved local policies. Fire, EMS, mental health, SAR, emergency response, Hazmat, industrial, security and mutual-aid packs suggest areas to review. They do not establish qualifications or authorize clinical, tactical or hazardous work. +## Department operating profile -The nine-step journey covers goals and applications, the department profile, all-area orientation, people and access, operational essentials, selected workflows, add-ons, verification and practice, and review and handover. Pause and resume without creating sample incidents or overwriting existing configuration. +**Department operating profile** (step 2, or `/User/Department/OperatingProfile`) describes your organization so Admin Assist can suggest modules to review. Department administrators and the managing user can edit it. -Selected operating packs suggest areas without changing your choices. Site references use existing department group IDs; policy references use existing, unexpired department document IDs. Saving checks those references and rejects concurrent overwrites. A valid reference does not prove that its contents are approved or sufficient. Verification checks whether linked policies or site groups later become unavailable, and flags documents scheduled for removal within 30 days. A reviewed profile without a continuity link receives an administrative review prompt; an external procedure may still exist. The checks do not read or certify policy contents. +| Section | Fields | +|---|---| +| **Operating packs** | Fire; EMS and ambulance; Mental health and mobile crisis; Search and rescue; Emergency management and response; Hazardous materials response; Industrial response; Security and facilities; Multi-agency and mutual aid. Tick every one that applies. | +| **Organization and operations** | **Workforce mix** (career, volunteer, contract, combination), **Approximate member count** (optional), **Dispatch model** (central, self, external, combination), **Operating hours** (24-hour operation, scheduled hours, on call, seasonal), **Participates in mutual aid**, **Expected email polling interval (minutes)** (optional), and the department time zone (shown here; change it on Department Settings). | +| **Seasonal operation** | **Season starts** / **Season ends** (month and day, optional). A season can run across the new year. | +| **Languages and accessibility** | **Working languages** and **Accessibility preferences** (captions, screen reader, large text, plain language). | +| **Sites, policies and systems** | **Sites and service-area groups** (chosen from your department's groups); **Approved staffing policies**, **Approved qualification policies** and **Approved continuity procedures** (chosen from your department's current documents); **Authoritative source systems** (short labels). | + +Use the department operating profile to describe your organization and link approved local policies. Fire, EMS, mental health, SAR, emergency response, Hazmat, industrial, security and mutual-aid packs suggest areas to review. They do not establish qualifications or authorize clinical, tactical or hazardous work. + +Selected operating packs suggest areas without changing your choices; suggested modules carry a *Suggested by your selected operating packs* label. Site references use existing department group IDs; policy references use existing, unexpired department document IDs. Saving checks those references and rejects concurrent overwrites. A valid reference does not prove that its contents are approved or sufficient. Verification checks whether linked policies or site groups later become unavailable, and flags documents scheduled for removal within 30 days. A reviewed profile without a continuity link receives an administrative review prompt; an external procedure may still exist. The checks do not read or certify policy contents. Choosing a group does not grant group access or change dispatch scope, and source-system labels are declarations: saving does not verify a connection or import. An optional **Expected email polling interval** compares recorded mailbox polls with your declared maximum interval. Leave it blank when no interval has been established. Missing or future poll timestamps remain unknown, and low call volume alone does not imply failure. SMS, CAD push and API intake require separate telemetry; the expectation does not change polling or send a test. -## Choose the areas your department uses -Mark each area **Use now**, **Learn later**, or **Not applicable**. A not-applicable choice requires a reason: outside the mission, managed in another approved system, managed by a responsible partner, or no current need. Baseline security remains in scope. Explore Resgrid covers applications, calls, people, units and location, communication, contacts and site knowledge, records, maintenance, inventory, deployments and business, automation, security and plans. Each feature explains its purpose, value, example and adoption requirements. +## Choose the modules your department uses + +Mark each module **Use now**, **Learn later**, or **Not applicable**. A not-applicable choice requires a reason: outside the mission, managed in another approved system, managed by a responsible partner, or no current need. Baseline security remains in scope: *Department administration and security* is always **Use now**. + +| Group | Modules | +|---|---| +| **Core modules** (every department sets these up) | Personnel and groups · Department administration and security · Dispatch and calls · Units and apparatus · Notifications and messaging · Apps and devices · Subscription and capacity | +| **Recommended** (most departments benefit) | Mapping and location · Shifts and scheduling · Training and certifications | +| **Optional modules** (included in your plan) | Contacts, documents and protocols · Records and reporting · Checklists · Inventory · Deployments · Automation and integrations | +| **Paid add-ons** | Maintenance and work orders · Workforce and business operations · Push-to-Talk · Advanced Data Protection · Enhanced AI | + +Your choices decide what the wizard walks through and what the Setup Report checks. **Explore this module** on each card, and the **Explore Resgrid & Addons** tab, describe a module in full: each feature explains its purpose, value, example and adoption requirements. Tick **I understand this feature** to record your own learning progress. Area choices are shared by department administrators. Learning and interest choices are personal. Another administrator's save can require you to reload and review before saving again. Learning a feature does not configure it, purchase an add-on, enable a module or send anything. + ## Configure and verify Use **Open owning screen** to configure a feature with its existing permissions and validation. Some settings include contextual help and a highlighted field when opened from Admin Assist. Save on that screen, then use **Return to setup and verify**. The return link does not submit the form. Its navigation context lasts 30 minutes and is tied to the current administrator and department, so it can survive the owning screen’s save and redirect. Returning to setup clears it. Choose **Verify again** after saving. -The report separates verified checks, failures and unknown evidence. Unpurchased optional add-ons do not reduce core completion. Deferring an area does not hide a verified critical failure or uncertainty in an active critical check. Selected areas with no automated checks are listed explicitly; they are not verified. Missing, restricted or unavailable source data remains unknown; it is never treated as zero. Critical unknowns prevent a fully verified result. Review the evidence time and refresh again if configuration changed during the read. +### Setup Report -Record an administrative review to retain the report version, evidence revision, selected-scope revision, timestamp and unresolved-check counts. A changed configuration, scope or catalog makes that review visibly out of date. Each newly added administrator still has a separate orientation checklist. An optional revisit date is stored in the report; it does not schedule a one-off notification. Weekly follow-up is a separate preference. +| Part | What it shows | +|---|---| +| **Summary** | Verified checks in your modules, checks needing attention, checks with unknown evidence, your learning progress, and when the evidence was read (*Evidence as of*). | +| **Next setup actions** | Up to five checks in your selected scope that need attention, most important first, each with a link to the screen that fixes it. | +| **Module readiness** | Each module's state and checks. Modules you deferred or marked not applicable are not counted, except security and critical checks, which always apply. **Change which modules you use** returns to the wizard. | +| **Setup review** | The last administrative review, **Mark this report reviewed**, the optional review date and the printable report. See [Review and hand over](#review-and-handover). | +| **Setup checklist for your modules** | Each key feature in four steps: understand it, confirm access, configure it on its own screen, then verify. Only supported checks can verify a feature; other steps stay *Not verified* until you review them. | +| **All checks in your selected scope** | Every check, grouped by result: needing attention, unknown, suggestions, passed, not applicable. | + +The report separates verified checks, failures and unknown evidence. Unpurchased optional add-ons do not reduce core completion. Deferring an area does not hide a verified critical failure or uncertainty in an active critical check. Selected areas with no automated checks are listed explicitly; they are not verified. Missing, restricted or unavailable source data remains unknown; it is never treated as zero. Critical unknowns prevent a fully verified result. Review the evidence time and refresh again if configuration changed during the read. Setup Report replaces the old numerical setup score. It is administrative configuration guidance, not certification of operational readiness or proof that a page was delivered. Start a Communication Test explicitly through its own screen when communication verification is needed. + + +### Review and hand over + +Record an administrative review (**Mark this report reviewed**) to retain the report version, evidence revision, selected-scope revision, timestamp and unresolved-check counts. A changed configuration, scope or catalog makes that review visibly out of date. Each newly added administrator still has a separate orientation checklist. + +An optional revisit date (**Review again on**, within the next year) is stored in the report; it does not schedule a one-off notification. **Download calendar reminder** gives you a calendar file to import into your own calendar if you want one; Resgrid does not send a message. Weekly follow-up is a separate preference. + **Open a fresh printable report** rechecks access and reloads the summary. It includes current findings, selected areas, personal feature interests and public add-on guidance. It omits protected notes, names, source records and credentials. Printing or saving a local copy does not create a managed server export; handle the copy under department policy. + ## Understand optional add-ons | Add-on | What it adds | Adoption considerations | @@ -49,20 +146,32 @@ Setup Report replaces the old numerical setup score. It is administrative config | Business Operations | Invoicing, rates, contracts, bids, reimbursement and workforce costing | Certifications and Deployment Finance remain available without the add-on. Pay-data reporting also requires enabled ADP; payment providers need separate setup. | | Enhanced AI | Planned summaries, drafts, knowledge assistance and optional conversation | Availability depends on release and rollout. Deterministic setup and Admin Assist do not require it. | -Availability can depend on subscription, rollout, module settings, permissions, protection enrollment and source availability. An unknown subscription is not confirmation of a free or paid plan. Only the managing member can perform subscription changes through the billing screen. Feature interest does not start a trial or purchase. +Availability can depend on subscription, rollout, module settings, permissions, protection enrollment and source availability. An unknown subscription is not confirmation of a free or paid plan. Only the managing member can perform subscription changes through the [billing screen](subscription-billing). Learning about an add-on does not start a trial or purchase. -The add-on step opens a comparison of all five add-ons. Each card lists its related features. Mark a feature **Interested in this feature** to see it in Setup Report with its current prerequisites and next available action. **I understand this feature**, availability, purchased entitlement, configuration and verified checks are separate states. Buying an add-on does not configure or verify the feature. The feature-setup section distinguishes recorded configuration, supported check results, current entitlement and optional opportunities. Initial evidence mappings cover personnel, groups, units, run cards, check-in timers, weather zones and email intake. Other feature configuration remains unassessed; absence of setup evidence does not prove a feature is unused. +Step 7 (**Plan and add-ons**) shows your subscription and capacity and a card for each of the five add-ons. Each card lists the features that use the add-on, shows whether it is part of your current plan, and takes a setup choice like any other module. **I understand this feature**, availability, purchased entitlement, configuration and verified checks are separate states. Buying an add-on does not configure or verify the feature. Feature rows distinguish recorded configuration, supported check results, current entitlement and optional opportunities. Recorded-setup evidence covers a set of key features, such as personnel, groups, units, run cards, check-in timers, weather zones and email intake. Other feature configuration remains unassessed; absence of setup evidence does not prove a feature is unused. + ## Follow up on findings -Admin Assist adds an administrative worklist. Claim an unresolved finding, set a review date, start a review, or record an accepted exception with a reason and expiry. Exceptions do not make the underlying check pass. Fresh verification resolves a finding; a later verified failure reopens it. An evidence outage cannot resolve it. Fix records, qualifications, inventory and other source tasks through their owning screens. +Admin Assist adds an administrative worklist (**Admin AI → Admin worklist**, once Admin AI is enabled; choose **Verify again** to create or update it). Claim an unresolved finding (**Assign to me**, optionally with a review date), start a review, or record an accepted exception with a reason and expiry (within 90 days). Exceptions do not make the underlying check pass. Fresh verification resolves a finding; a later verified failure reopens it. An evidence outage cannot resolve it. Fix records, qualifications, inventory and other source tasks through their owning screens. -Weekly follow-up is opt-in and only runs when the deployment enables scheduled digests. Quiet hours use the department time zone. The message contains a generic link to Admin Assist; open the authenticated page to see current evidence. A notification handoff is not confirmation of delivery. Turning the preference off suppresses future handoffs. +| Status | Meaning | +|---|---| +| **Unassigned** | Nobody has claimed the finding. | +| **Assigned** | An administrator claimed it. | +| **In review** | A review has started. | +| **Accepted exception** | Accepted for a reason until its expiry. The check still shows its actual result. | +| **Resolved by verification** | A fresh passing check resolved it. | + +Weekly follow-up is opt-in (**Follow-up preferences** on the worklist: **Send me a generic weekly summary link**, with quiet hours) and only runs when the deployment enables scheduled digests. Quiet hours use the department time zone. The message contains a generic link to Admin Assist; open the authenticated page to see current evidence. A notification handoff is not confirmation of delivery. Turning the preference off suppresses future handoffs. + ## Use Settings Reference and Change History +Settings reference, Change history and the change previews are on the **Admin AI** tab (Settings reference and Change history are sub-tabs; the previews are under **Overview → Preview a change before you make it**, and per setting in Settings reference). + Settings Reference searches a release-pinned public documentation catalog. It does not search department records or attachments. If your language has no reference article, the result labels its source language. Supported scalar settings offer **Preview a proposed value**. A preview compares values in memory, shows related health-check changes and lists its limits. It does not save configuration. Current operational previews cover v4 map-marker selection, the automatic-availability status projection and administrator MFA enrollment. These do not establish every client's behavior, actual physical availability or session/recovery readiness. @@ -86,3 +195,14 @@ Supported scalar settings offer **Preview a proposed value**. A preview compares Counts and checks are only as current as their source evidence. Unquantified effects still need review on the owning screen. Refresh after a configuration conflict and verify again after an actual save. Reference results can expand the full release-pinned source text and identify its source language. Change History starts when collection is enabled. Earlier changes are unavailable. History shows safe configuration differences; secrets and sensitive strings use presence/change markers. It does not expose another administrator's personal learning choices. + +## Technical reference + +| Item | Value | +|---|---| +| Controllers | `AdminAssistController` (one page; each route picks the tab it opens on); `DepartmentController.OperatingProfile`; legacy redirects in `DepartmentController.SetupWizard` and `HelpController.SetupReport` | +| Routes | `/User/AdminAssist` and `/User/AdminAssist/SetupWizard` (Setup Wizard), `/User/AdminAssist/SetupReport`, `/User/AdminAssist/Plans` (when plans are enabled), `/User/AdminAssist/PrintReport`, `/User/AdminAssist/ReviewCalendar` (calendar reminder), `/User/AdminAssist/DismissSetup` (POST, dashboard prompt), `/User/Department/OperatingProfile` | +| Legacy routes | `/User/Department/SetupWizard` → `/User/AdminAssist/SetupWizard`; `/User/Help/SetupReport` → `/User/AdminAssist/SetupReport`. The old setup modal and its `SubmitSetupWizard` writer were removed. | +| Access | Department administrators. Operating profile: department administrators and the managing user (`Department_Update`). | +| Feature flags | `Admin.Setup` — Setup Wizard, Setup Report and Explore. `Admin.Assist` plus `Ai.AdminAssist` — the Admin AI tab. | +| Page data | `api/v4/AdminAssist/` | diff --git a/docs/web-app/import-and-migration/_category_.json b/docs/web-app/import-and-migration/_category_.json new file mode 100644 index 0000000..7caa02b --- /dev/null +++ b/docs/web-app/import-and-migration/_category_.json @@ -0,0 +1,9 @@ +{ + "label": "Import & Migration", + "position": 54, + "link": { + "type": "generated-index", + "slug": "/web-app/import-and-migration", + "description": "Bring people, stations and groups, roles and certifications, unit types and units, custom statuses, call types and priorities, and points of interest into Resgrid from spreadsheets or the system you are leaving. Every row is checked and previewed before anything is saved, imports can be rolled back, and imported people stay dormant until you invite them." + } +} diff --git a/docs/web-app/import-and-migration/before-you-start.md b/docs/web-app/import-and-migration/before-you-start.md new file mode 100644 index 0000000..c4cdca0 --- /dev/null +++ b/docs/web-app/import-and-migration/before-you-start.md @@ -0,0 +1,113 @@ +--- +sidebar_position: 2 +title: Before You Start +--- + +# Before You Start an Import + +**Department menu → Import & Migration** + +A migration goes fastest when you have the right exports in hand before you open a workspace. This page lists what to ask your current vendor for, what Resgrid imports and what it deliberately leaves behind, the file formats it reads and the size limits for your plan. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +**Department menu → Import & Migration**, or **Setup Wizard → Import or migration → Open Import & Migration**. You do not need a workspace to read this page — but you can start one at any time and come back; nothing is saved to your department until you approve an import. + + +## Turning it on + +The module needs the `Onboarding.MigrationWizard` feature flag (off by default, turned on per department by Resgrid) and is available to **department administrators only** (permission 72, `ManageDepartmentImport`). See [Overview → Turning it on](overview#enable). + + +## Plan the move + +| Decide | Why it matters | +|---|---| +| **What to bring** | Pick the data sets you need (see [What you can bring](overview#import-migration)). You can import in waves: stations, roles and types first, people next, certifications and units after. | +| **Who approves** | Any department administrator can approve. Turn on **Require a second administrator to approve every import** in [settings](rollback-and-retention#import-settings) if two people should sign off. Approving needs two-factor authentication — set it up first. | +| **Who is an administrator in Resgrid** | People marked as administrators in your file become administrators only after you confirm each one at activation. | +| **When people hear about it** | Imported people receive nothing until you invite them. Pick a go-live date and tell your members before invitations go out. | +| **Plan capacity** | New people and units must fit your plan. Check **Subscription & Billing** before importing a large roster. | +| **Custom fields** | If you want to keep extra columns (badge colour, locker number …) as custom fields and your department already uses custom fields for people or units, add matching fields on the [User Defined Fields](../user-defined-fields) screen first. See [Keep as a custom field](matching-columns-and-values#custom-fields). | + + +## Exports to request from your current vendor + +Ask for these while your contract is still active. One file per kind of data, or one workbook with a sheet each, is ideal. Once your workspace exists, tell Resgrid which products you are moving from ([Where your data comes from](uploading-and-checks#products)) to see what their words are called in Resgrid. + +| Export | Needed for | Ask for these columns | +|---|---|---| +| **Member roster** | People | A stable member ID, first and last name, **email** (required — every member signs in with one), mobile and home phone, station or group, roles or positions, badge or ID number, active / inactive, whether the person is an administrator. | +| **Stations and groups** | Stations and groups | A stable ID, name, type (station or other group), parent group, street address, city, state, postal code, country, latitude and longitude if available. | +| **Roles / positions / ranks** | Roles | Name and description. | +| **Certification list** | Certification types | Name, short code, category, issuing authority, how long it is valid. | +| **Member certifications** | People's certifications | Member ID or email, certification name or code, certificate number, issued and expiry dates, issuing body, state or region. | +| **Apparatus list** | Unit types, Units | A stable ID, unit name or call sign, type, home station, VIN, plate, seats or riding positions. | +| **Status lists** | Statuses | Each status button with its set, text, colour and order. | +| **CAD call types and priorities** | Call types, Call priorities | Names; for priorities also colour, order and whether they page people and units. | +| **Map locations** | Point of interest types, Points of interest | Type, name, latitude, longitude, address, notes. | + +Ask for the files to be: + +- **CSV (UTF-8) or Excel `.xlsx`**, one row per record and the column names in the first row. +- **With the record IDs kept.** Map them to **Source ID** — later files can refer to a row by it (a person's station, a certification's holder), and re-uploading a corrected file updates instead of duplicating. +- **With full dates** — ideally `YYYY-MM-DD`. For dates like `03/04/2026`, which can be read two ways, you are asked once per column whether the day or the month comes first ([Dates](matching-columns-and-values#dates)). +- **With phone numbers including the country code** — `+1 555 123 4567`. Numbers without one are read using your department's country, and anything that cannot be read is flagged. +- **Without passwords, ID numbers or other sensitive data** (below). Resgrid drops those columns anyway, but it is better if they never leave your vendor. + + +## What is and isn't imported + +**Imported in this release:** the twelve data sets on the [overview](overview#import-migration), with the fields listed on each field reference page. Columns that do not match a field can be left out or, for people and units, [kept as custom fields](matching-columns-and-values#custom-fields). The department's own settings — name, time zone, address, profile and logo, modules, names, map, numbering and a few permissions — are set on the [Configure](configure) tab rather than from a file. + +**Never imported**, whatever the file says: + +| Kind of data | How it is recognized | +|---|---| +| Passwords and PINs | Headers containing *password*, *passwd*, *pwd*, *pin*, *pincode*. Each person sets their own password when they accept the invitation. | +| National and government ID numbers | *SSN*, *social security*, *SIN*, *national insurance*; driver's licence numbers (*driver's license / licence*). Values shaped like US social security numbers. | +| Card and bank details | *credit card*, *card number*, *CVV*, *CVC*, *IBAN*, *routing number*, *account number*. Values that look like payment card numbers. | +| Secrets | *API key*, *secret*, *token*. | +| Dates of birth and demographics | *date of birth*, *DOB*, *birthdate*, *birthday*, *race*, *ethnicity*. | +| Physical-access codes | *Knox*, *gate code*, *alarm code*, *Supra*. | +| Medical information | *diagnosis*, *medical condition*, *allergies*, *medication*. | + +Short words match only as whole words in the header (*Race* is dropped, *Trace* is not); longer terms also match inside run-together headers such as `DateOfBirth` or `user_password`. A column is also dropped when most of its values look like card numbers or social security numbers. A dropped column is shown as **Never imported (sensitive data)** on the matching screen, its values are not stored or displayed, and a resolved note (`IMP-EXCLUDED-SENSITIVE`, *A column was left out on purpose*) records it. + +**Not part of this release:** sign-in data (passwords, passkeys, two-factor and SSO links — people set these up themselves), department secrets and API keys, billing, audit history, historical calls and Records, shifts, calendars, inventory, checklists, work orders and contacts. + + +## File limits by plan + +"Paid" means any plan other than the free plan. + +| Limit | Free plan | Paid plans | +|---|---|---| +| One uploaded file | 50 MiB | 200 MiB | +| All files in one workspace | 500 MiB | 2 GiB | +| Rows in one data set | 20,000 | 500,000 | +| Columns in one sheet | 512 | 512 | +| Text in one cell | 32 KiB | 32 KiB | +| Sheets in one workbook | 50 | 50 | +| Time to read one data set | 5 minutes | 5 minutes | + +These limits are about the **files**. How many people and units you can actually add is your **plan capacity**, checked separately: you can upload a 500-person roster on a smaller plan, but only the people your plan has room for can be imported, and the preview says so before you approve. See [Review and import](review-and-import#capacity). + + +## Supported file formats + +| Format | Notes | +|---|---| +| **CSV, TSV, `.txt`, `.tab`** | The delimiter is detected. UTF-8 (with or without a byte-order mark) is expected; another encoding is guessed and flagged with a warning so you can check accented names. Always accepted, even where the server does not scan uploads. | +| **Excel `.xlsx`** | Every visible sheet becomes its own data set; hidden sheets and the starter workbook's *Instructions* and *Lists* sheets are skipped. Formulas are never calculated — the value Excel last saved is used. Dates follow the workbook's 1900 or 1904 date system. Macro-enabled (`.xlsm`), binary (`.xlsb`) and old (`.xls`) workbooks, password-protected files, embedded objects and links to other workbooks are refused. Needs virus scanning on the server. | +| **JSON** | A list of objects (one per record), or an object holding exactly one list — the `{"data": [ … ]}` shape many API exports use. Nested objects become columns with dotted names such as `address.city`. | +| **JSON Lines** (`.jsonl`, `.ndjson`) | One object per line. | +| **GeoJSON** | A `FeatureCollection`. Each feature's properties become columns; a `Point` geometry becomes `latitude` and `longitude` columns, ready for points of interest. | +| ZIP, KML, KMZ, GPX | Recognized but not imported yet. | + +Resgrid checks what a file really contains, not just its name: a file whose content does not match its type is refused (`IMP-FILE-SIGNATURE`). See [Uploading and checks](uploading-and-checks) for everything that happens next. diff --git a/docs/web-app/import-and-migration/call-types-and-priorities.md b/docs/web-app/import-and-migration/call-types-and-priorities.md new file mode 100644 index 0000000..35018ad --- /dev/null +++ b/docs/web-app/import-and-migration/call-types-and-priorities.md @@ -0,0 +1,83 @@ +--- +sidebar_position: 16 +title: Call Types & Priorities Field Reference +sidebar_label: "Reference: Call types & priorities" +--- + +# Call Types and Priorities — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +Two data sets bring over your dispatch vocabulary: **Call types** (Structure fire, Medical …) and **Call priorities** (with their colours, order and whether they page people and units). After the import they are on the [Types](../types-configuration) screen. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **Call types** and **Call priorities** sheets of the [starter workbook](starter-workbook) (or `resgrid-call-types.csv` and `resgrid-call-priorities.csv`), or upload lists from your CAD and match them on the [matching](matching-columns-and-values) page. **Download current data** exports your existing call types and priorities. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + + +## Call types sheet + + + +The kinds of call you are dispatched to (Structure fire, Medical…). + +Starter workbook sheet **Call types**; CSV template `resgrid-call-types.csv`. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The call type's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The call type's name. Calls refer to their type by this name. Up to 100 characters. Must be unique in the file. Example: `Structure fire`. Headers recognized: name, type, call type, nature, incident type. | +| `Class [base_type]` | `base_type` | Choice from a list | | What kind of call this type is. Resgrid uses the class, not the name, for reports, defaults and integrations, so a department can name its call types however it likes. Choices: `fire` Fire (also: fires, fire call); `medical` Medical (also: ems, medical aid, patient); `rescue` Rescue (also: technical rescue, search); `traffic-collision` Traffic Collision (also: traffic, mva, mvc, vehicle accident, collision, rtc); `hazardous-materials` Hazardous Materials (also: hazmat, haz mat, gas leak); `alarm` Alarm (also: fire alarm, alarm activation, false alarm); `service-call` Service Call (also: service, public assist, public assistance); `law-enforcement` Law Enforcement (also: police, security, public order); `disaster-weather` Disaster or Weather (also: disaster, weather, storm, flood); `mutual-aid` Mutual Aid (also: mutual aid given, assist other agency); `non-emergency` Non-Emergency Activity (also: training, drill, standby, non emergency, event); `other` Other (also: misc, miscellaneous). Leave it empty to set it later on the Types screen; an import never guesses it from the name. Example: `medical`. Headers recognized: base type, call class, class, classification, incident class. | + +*Contract `call-types` version 2026.11.1, generated from the import catalog.* + + + + +## Call priorities sheet + + + +Your call priorities with their colours and dispatch behaviour. Importing priorities replaces the four built-in ones. + +Starter workbook sheet **Call priorities**; CSV template `resgrid-call-priorities.csv`. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The call priority's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The priority's name. Up to 100 characters. Must be unique in the file. Example: `Emergency`. Headers recognized: name, priority, priority name, level. | +| `Colour [color]` | `color` | Colour | | The priority's colour, as a hex code such as #e34948. Example: `#e34948`. Headers recognized: color, colour. | +| `Order [sort]` | `sort` | Whole number | | The priority's position in lists; lower comes first. From 0 to 1000. Example: `0`. Headers recognized: order, sort, rank, position. | +| `Default [is_default]` | `is_default` | Yes/No | | Yes for the one priority new calls start with. Example: `no`. Headers recognized: default, is default. | +| `Page people [dispatch_personnel]` | `dispatch_personnel` | Yes/No | | Yes when a call with this priority pages the people dispatched to it. Example: `yes`. Headers recognized: dispatch personnel, page people, notify personnel. | +| `Page units [dispatch_units]` | `dispatch_units` | Yes/No | | Yes when a call with this priority pages the units dispatched to it. Example: `yes`. Headers recognized: dispatch units, page units, notify units. | +| `Notify everyone [notify_everyone]` | `notify_everyone` | Yes/No | | Yes when a call with this priority notifies every member, whatever their notification settings. Example: `no`. Headers recognized: notify all, force notify, notify everyone. | +| `Meaning [base_type]` | `base_type` | Choice from a list | | Which standard priority this one means. Resgrid uses it wherever a priority must be compared across departments or apps, such as reports and sorting by urgency. Choices: `low` Low (also: routine, non urgent, non-urgent); `medium` Medium (also: normal, moderate); `high` High (also: urgent, priority); `emergency` Emergency (also: critical, code 3, immediate, lights and sirens). Leave it empty to set it later on the Types screen; an import never guesses it from the name. Example: `high`. Headers recognized: base priority, base type, severity, priority class. | + +*Contract `call-priorities` version 2026.11.1, generated from the import catalog.* + + + + +## How call types and priorities are matched + +- Both are matched by Source ID (same workspace, or the import it [continues](uploading-and-checks#continue)), otherwise by **name**, ignoring case, accents, spaces and punctuation. Two existing records with the same name block the row until you rename one. +- An import never renames a call type: calls, quick templates and protocols refer to call types by name. Rename call types on the [Types](../types-configuration#call-types) screen. + +More rules: + +- **Importing priorities replaces the four built-in ones.** A department without priorities of its own uses Resgrid's built-in set; once you import any, your department's own priorities are used instead — so import the full list you want. +- **Default** — the one priority new calls start with. When an imported priority is marked default, the previous default stops being the default (and gets it back if the import is rolled back). +- **Page people** and **Page units** are on for a new priority unless your file says *no*. +- **Notify everyone** notifies every member for calls of this priority, whatever their notification settings. +- Rolling back marks imported priorities deleted (calls keep showing their priority), and deletes imported call types. diff --git a/docs/web-app/import-and-migration/configure.md b/docs/web-app/import-and-migration/configure.md new file mode 100644 index 0000000..1f4c210 --- /dev/null +++ b/docs/web-app/import-and-migration/configure.md @@ -0,0 +1,193 @@ +--- +sidebar_position: 6.5 +title: Configure Resgrid +--- + +# Configure Resgrid + +**Department menu → Import & Migration → (workspace) → Configure** + +The **Configure** tab lists the settings an import can change in your department: the department record, your profile and logo, which modules are turned on, the names your department uses, the map, call, document and record numbering, and a few permissions. Resgrid suggests values from your [operating profile](../help-setup) and from the data you are importing; you accept, change or decline each one. Nothing changes until you approve an import: accepted settings are changed first, before any data, and each change can be rolled back while nobody has changed that setting since. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +The **Configure** tab of a workspace, between **Issues** and **Review & import**. The **Configure Resgrid** step of the journey on the Overview tab opens it too. + +| Area | Contents | +|---|---| +| **Your department** | Your operating profile (kinds of department, workforce, dispatch model, operating hours) and **Edit your operating profile** — or **Describe your department** when you have not saved one yet. | +| **Stat tiles** | **Will be changed** (accepted settings that differ from what your department has now; opens Review & import) and **Waiting for your decision** (suggestions you have not accepted or declined). | +| **Accept all suggestions** | Accepts every suggestion still waiting, except permissions you cannot preview. Each group also has **Accept the suggestions in this group**. | +| **Groups** | **Department**, **Profile and logo**, **Modules**, **Names**, **Map**, **Numbering** and **Permissions**. A group with something to change or decide opens by itself. | + +Each group is a table with the columns **Setting**, **Now**, **Proposed** and **Status**, and per row **Accept**, **Decline**, **Change** and **Undo**. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + +**Permissions** additionally need Admin Assist's impact preview, so the department administrator must be able to use Admin Assist (the `Admin.Assist` flag). Without it the Permissions group says *Permission changes need Admin Assist's impact preview, which is not available to you. Use the Security page to change permissions.* and offers no change. + + +## Describe your department + +The suggestions come from your department's operating profile — the same profile Admin Assist uses. **Describe your department** (or **Edit your operating profile**) opens it; it is saved straight away, without waiting for an import. Choose every kind of department you are (fire, EMS, search and rescue, security…), your workforce, how you are dispatched and your operating hours. + +Without a saved profile, nothing is suggested from it; data sets can still ask for the modules they need. + + +## Where suggestions come from + +Every proposed value carries its origin under it: + +| Origin | What it suggests | +|---|---| +| **Suggested from your operating profile** | **Modules** that each of your kinds of department works in, when they are turned off (the pack's name is shown, for example *Search and rescue*). **Names** that departments of your kind commonly use, when the module still has Resgrid's name: search and rescue *Missions* for Calls and *Teams* for Units, security *Incidents* for Calls and *Officers* for Personnel, industrial *Incidents* for Calls. A name is suggested only when every kind you chose that names it agrees. With an upstream CAD as your dispatch model, **Who can Create Calls** set to **Department and Group Admins** (*calls come from an upstream CAD*). | +| **From the data you are importing** | A module that a data set needs, when it is turned off — for example **Mapping** for points of interest (*for Points of interest*). A data set whose module is off is refused when the import starts, so turning it on here lets the same import write it. And the **Map centre**, when your department has none yet: the middle of the stations you are importing (*the middle of the 12 stations you are importing*), worked out from the latitude and longitude of the station rows that passed the checks and aren't left out. It uses the median position, so a station or two in the wrong place doesn't pull the map away; a position of 0, 0 counts as missing. | +| **Suggested from the products you are moving from** | **Names** the products you chose under [Where your data comes from](uploading-and-checks#products) use for Resgrid's features, when the feature still has Resgrid's name (the products are shown, for example *Aladtec*): *Members* for Personnel (Aladtec, Active911, D4H Team Manager, IamResponding), *Apparatus* for Units (First Due, Emergency Reporting, NFIRS 5.0), *Vehicles* for Units (DIVERA 24/7; *Fahrzeuge* when you use Resgrid in German) and *Incidents* for Calls (D4H Team Manager). Only a word in the language you use Resgrid in is suggested, because the name is shown in every language. When two of your products name the same feature differently, neither is suggested. | +| **Entered by you** | Any value you type or choose with **Change**. | +| **Entered by Resgrid Support** | A value Resgrid support entered with **Prepare** or **Operate** [support access](getting-help-from-support#import-support-access). | + +Suggestions never turn a module off, never replace a name you have chosen, and never touch a setting that already has the suggested value. They are worked out again every time the page opens, so changing your profile or your data sets changes them; your decisions are kept. + + +## The settings + + +### Department + +| Setting | What it changes | +|---|---| +| **Department name** | The department's name (up to 150 characters). | +| **Time zone** | The time zone calls, shifts, numbering and reports use. | +| **24-hour clock** | Whether times are shown in 24-hour format. | +| **Address** | The department's address (street, city, state or region and country required; postal code optional). | + +An import never changes the department's managing user. + + +### Profile and logo + +**Short name** (up to 50 characters), **Description** (up to 2,000), **Phone number** (up to 50) and **Website** (an `http` or `https` address) are shown on your profile, printouts and emails. Leave one empty to clear it. + +**Logo**: **Upload a logo** takes a PNG or JPEG of at most 2 MB and at least 200 pixels on the longer side, and accepts it as the proposed logo. The image is checked when you upload it and re-encoded into the logo, print header, email masthead and thumbnail when the import runs — exactly as on the Profile screen; the file you uploaded is never shown to anyone. An uploaded logo is kept with the workspace's other files and purged with them. + + +### Modules + +**Messaging**, **Mapping**, **Shifts**, **Logs**, **Reports**, **Documents**, **Calendar**, **Notes**, **Trainings**, **Inventory**, **Maintenance and Work Orders (Readiness Pro)**, **Checklists** and **Business Operations**, each **On** or **Off** — the same switches as [Module settings](../department-settings). Turning a module off hides it from everyone; its data is kept. Calls, Personnel and Units are always on, and AI features are turned on or off on their own screen. + +With Admin Assist, a module change shows *What this changes*: how many members' menus change and how much existing data the module holds. + + +### Names + +Every module and record type your department can rename (see [Department settings → Terminology](../department-settings#terminology)): Calls, Personnel, Units, Contacts, Mapping, Shifts, Records, Logs, Reports, Documents, Calendar, Notes, Trainings, Inventory, Readiness, Work Orders, Checklists, Workforce & Business, and the record types Run, Training, Work, Meeting, Coroner, Callback, Unit activity and NERIS incident report. + +A name is up to 50 characters and is shown in every language. Leave it empty to keep Resgrid's name (shown as *Resgrid's name (Calls)*). When both your operating profile and a product you are moving from suggest a name for the same feature, the product's word is suggested. + + +### Map + +| Setting | What it changes | +|---|---| +| **Map centre** | Where maps open: a latitude and longitude in decimal degrees. Suggested from your stations' positions when you have none. | +| **Map zoom level** | From 0 (the whole world) to 15 (streets). | +| **Map style by day** / **Map style by night** | The map styles of [Mapping settings](../mapping), or **Automatic**. | + + +### Numbering + +| Setting | What it changes | +|---|---| +| **Call numbers · pattern** | How call numbers are written, for example `{YYYY}-{SEQ}`. | +| **Call numbers · sequence digits** | How many digits the sequence has (1 to 8, zero-padded). | +| **Call numbers · numbering year starts** | The first day of the numbering year, when numbers start again from 1. | +| **Call numbers · next number** | The sequence the next call receives: continue your old system's numbering. | +| **Document numbers · numbering year starts** | The same for work orders, invoices, bids and time reports. | +| **Work orders / Invoices / Bids / Time reports · pattern, sequence digits, next number** | Each kind's own pattern (empty = Resgrid's built-in numbers), digits and next number. | + +Patterns use `{YYYY}`, `{YY}`, `{MM}`, `{DD}` and `{SEQ}` (exactly once) with letters, digits and `- _ . /`, as on [Call settings](../department-settings) and Document numbering. Rules: + +- **The next number can only go up.** It can't be lower than the number Resgrid would use next already, and a rollback does not lower it. +- **A document kind needs its own pattern** before it takes sequence digits or a next number: Resgrid's built-in numbers have neither. Accept the pattern and the next number together. +- A next number accepted together with a new pattern or year start is checked against the new numbering when the import runs. +- Record numbers have their own group, below. + + +### Record numbering + +Shown only while Records is turned on for your department. These are the settings of [Records settings → Numbering](../records/settings#numbering). + +| Setting | What it changes | +|---|---| +| **Record numbers · pattern** | How record numbers are written, for example `{PREFIX}-{YYYY}-{SEQ}` (RUN-2026-0153). | +| **Record numbers · sequence digits** | How many digits the sequence has (3 to 8, zero-padded). | +| **Record numbers · numbering year starts** | The first day of the numbering year. Records request, prevention, investigation and evidence numbers follow it too. | +| **Run, Training, Work, Meeting, Coroner, Callback, Unit activity, NERIS incident report · prefix** | What `{PREFIX}` writes for the record type: 2 to 6 letters or digits. Empty is the type's default (RUN, TRN, WRK, MTG, COR, CBK, UNT, INC). A new prefix starts its own sequence. Record types are named as your department names them. | +| **… · next number** | The sequence the type's next record receives this numbering year, for records with no station or group: continue the numbers your old system issued. | +| **Records requests / Occupancies / Inspections / Permits / Investigations / Evidence · pattern, sequence digits, next number** | Each kind's own pattern (empty = Resgrid's built-in numbers), digits and next number. | + +The record pattern uses `{PREFIX}`, `{YYYY}` or `{YY}`, `{GROUP}` (the station, followed by `-`, `_` or `.`) and `{SEQ}` (exactly once) with letters, digits and `- _ .`, up to 40 characters. The other kinds use the call-number tokens. Besides the numbering rules above: + +- **Shared sequences.** A pattern without `{PREFIX}`, or two types given the same prefix, gives those types one sequence; two different next numbers for it are named before you can approve (*These record types share one sequence, so give them the same next number.*). +- **Station sequences.** A pattern with `{GROUP}` numbers each station separately; set those next numbers in the Records settings (*This pattern numbers each station separately…*). +- The pattern, digits, year start and prefixes are written before the next numbers, so a next number is checked against the numbering it lands in. +- If Records is turned off after you decided record numbering, the decisions stay visible with *Records isn't turned on for your department…* and hold the import back until you undo them. + + +### Permissions + +**Who can Create Calls**, **Who can Create Notes**, **Who can View Personal Info**, **Who can view users**, **Who can view units**, **Who can see the Location of Personnel** and **Who can see the Location of Units** — the permissions Admin Assist can preview. For each, choose who can do it (**Everyone**, **Department Admins**, **Department and Group Admins**, or **Department Admins and Select Roles** with the roles), and for the four viewing permissions (users, units and their locations) whether it applies **Only within their own group**. + +Permissions are never read from a file: they are suggested or chosen here. Each proposed change shows Admin Assist's *What this changes* — how many members gain or lose the permission — before you accept it. Other permissions are set on the [Security](../security-permissions) page. + + +## When Resgrid support prepares settings + +With **Prepare** or **Operate** [support access](getting-help-from-support#import-support-access), Resgrid support can prepare settings for you from BackOffice: accept or decline suggestions, enter values and upload a logo. Their drafts show a **Resgrid staff** label (and *Entered by Resgrid Support* when they typed the value), appear on the timeline as Resgrid staff actions, and change nothing until an import is approved — by you, or under a managed migration by two Resgrid staff members (and you, when you asked to approve imports). + +- Support **never changes permissions**: those stay your decision, with Admin Assist's preview. +- Support **never overrides a value you decided**. They can ask you in the message thread instead. +- You can change or undo any staff draft; once you decide a setting yourself it is yours. Support can undo only their own drafts. +- With **Observe** or **Inspect** access, support can see this tab as you do, but change nothing. At **Observe** the map centre suggestion is hidden from them, because it comes from the station positions in your files. + + +## Statuses + +| Status | Meaning | +|---|---| +| **Suggested** | A suggestion waiting for your decision. | +| **Will be changed** | Accepted, and different from what your department has now: the next approval changes it. | +| **Already set** | Accepted, but your department already has this value: nothing to change. | +| **Declined** | You declined the suggestion; it stops waiting. **Undo** brings it back. | +| **Changed** | Changed by an import. | +| **Not changed** | The import could not change it; the reason is shown (for example *The next number can't be lower than the number Resgrid would use next already.*). Change the value and approve again. | +| **Rolled back** | Changed by an import and undone by its rollback. | + +An accepted value that cannot be changed as it stands — a document's next number without its own pattern, a role that no longer exists, a logo that was purged — shows the reason under its status and stops approval until you fix it. + + +## When the settings change + +Accepted settings go with every import you approve: + +- [Review & import](review-and-import) shows *N settings will be changed first, before any data.* with the count per group, and adds the statement *I have reviewed the settings that will change. Each one can be rolled back while nobody has changed it since.* An import can be settings alone, with no data set. +- While an import or rollback is waiting or running, the Configure tab is read-only: the approval covers the exact values, and changing one would make it stale. +- When the import runs, settings are changed first, one at a time, each through the same screen logic as the department's own settings pages. Then the data sets are written — so a module turned on here is on before the data that needs it. +- Each change is recorded with the value it replaced, and appears in Admin Assist's **Change history** like any other settings change. +- The check after the import confirms each setting still reads as it was written; History shows **Configuration** with the number changed, already set and not changed. + + +## Rolling back settings + +[Rolling back](rollback-and-retention) the import puts each setting back to the value it replaced — but only when nobody has changed that setting since. A setting someone changed after the import is left as they set it and listed for you to check. Two kinds of change can't be undone: + +- **Next numbers** only ever go up; the numbers already issued stay issued. +- **A replaced logo** is not kept, so the previous logo is not restored; upload it again on the Profile screen. A logo added where there was none is removed. diff --git a/docs/web-app/import-and-migration/fixing-issues.md b/docs/web-app/import-and-migration/fixing-issues.md new file mode 100644 index 0000000..8a1456f --- /dev/null +++ b/docs/web-app/import-and-migration/fixing-issues.md @@ -0,0 +1,322 @@ +--- +sidebar_position: 6 +title: Fixing Issues +--- + +# Fixing Issues + +**Department menu → Import & Migration → (workspace) → Issues** + +The checks rarely find one problem at a time — usually it is *23 people have a phone number we couldn't read*. So the **Issues** tab groups problems by kind, explains why each matters and how to fix it, and offers one-click fixes for the whole group. Every issue has a stable code (`IMP-…`) that support can look up; this page lists all of them. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +- The **Issues** tab of a workspace. Its badge is the number of open **blocking** issues. +- **Issues to fix** on the Overview tab (the five most important groups), the blocked count on each data set, and the **Fix issues** link on a data set page all open it filtered to that data set. + +Filter by **Data set** and tick **Show resolved issues** to see what has been accepted or excluded. When nothing is left, the tab shows *No issues — Everything we checked is ready to import* and a button to **Review and import**. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + + +## How an issue group works + +Each group is a panel with: + +| Part | Contents | +|---|---| +| **Heading** | A severity chip — **Blocking**, **Warning** or **Note** — and the title with the number of open rows, for example *12 dates couldn't be read*. The code is shown on the right. | +| **Where** | The data set, the column and the first affected row numbers. | +| **Why and how** | The explanation and the fix, in plain words. | +| **Actions** | The fixes that apply to this group (below). | + +Values from your file are never written into an issue; the rows are named by number. + +| Severity | What it means | +|---|---| +| **Blocking** | The rows cannot be imported as they are. Fix them or exclude them — a data set with open blocking issues cannot be approved. | +| **Warning** | The rows can be imported, but something will be different from your file (a value left empty, a text shortened). **Accept** the warning to go ahead, or fix it. | +| **Note** | Information — for example that rows match records that already exist and will be linked rather than added. | + + +## Ways to fix + +| Action | What it does | Offered when | +|---|---|---| +| **Accept** | Accepts a warning or note for every row in the group. | Warnings and notes | +| **Exclude these N rows** | Leaves the rows out of the import (you are asked to confirm). They can be included again later with **Reopen**. | The issue is on rows | +| **Use this value** | Replaces the problem cell in every row of the group with the value you type, then checks the rows again — for example the same station for every row with an unknown one. | The issue is on one column of some rows | +| **Ask support about this** | Opens the Support tab with the issue code attached. | Always | +| **Reopen** | Puts an accepted or excluded group back to open. | With *Show resolved issues* | + +Other fixes happen elsewhere: + +- **Match columns or values** — most *value doesn't match* and *reference doesn't match* issues are fixed on the data set's [matching](matching-columns-and-values) pages. +- **Fix the file and upload it again** — often quickest for many small problems. Upload the corrected file, then **Exclude** the old data set on **Files & data sets** so only the new one is imported. +- **Change something in Resgrid** — rename a duplicate record, switch on a module, add custom fields, upgrade the plan. + +Every fix re-checks only what it affects, and the counts on the Overview tab update as it finishes. Accepting and excluding are remembered: a re-check does not bring back an issue you have already decided. + + +## Where issues show up + +The **Shown as** column in the tables below says where you meet each code: + +| Shown as | Where | What to do | +|---|---|---| +| **Blocking**, **Warning**, **Note** | On the Issues tab, before approval. | Fix, exclude, accept — as above. | +| **Blocking if the field is required, otherwise a warning** | On the Issues tab. A required field's value is needed; for an optional field the value is left empty if you accept. | Fix, exclude, or accept for optional fields. | +| **File refused** | On the **Uploaded files** list. The file was not read at all. | Fix the file and upload it again. | +| **Upload stopped** | While uploading, under the upload button. Nothing was stored. | Upload again, or fix the file first. | +| **Run status** | On the **History** tab, next to a run. | Mostly nothing — Resgrid retries or waits automatically; some need a new approval. | +| **Row not imported** | After an import, on the rows the import skipped. | Check the rows, fix them and import again, or ask support. | +| **Warning after import** | After an import, on the data set. | Check by hand; see [Verify the result](verify-and-activate#verify-results). | +| **Check by hand** | After a rollback, on the History tab. | Compare the record with your source and fix it in Resgrid. | + + +## Every issue code + +Grouped by the stage that raises them. Titles and explanations are the ones shown on screen; *N* stands for the number of rows or values. + + + + + +### File safety and storage + +Checked when the file arrives, before anything in it is read. A refused file is never opened; upload a corrected copy. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-FILE-TOO-LARGE` | The file is larger than your plan allows | Split the file into smaller files, or remove sheets and columns you don't need. **Tip:** Limits by plan are on [Before you start](before-you-start#file-limits). | Upload stopped | +| `IMP-FILE-SIGNATURE` | The file's content doesn't match its type | Export it again from your system as CSV or Excel (.xlsx). | File refused | +| `IMP-FILE-MACRO` | Files with macros can't be imported | Save the workbook as a plain Excel workbook (.xlsx) without macros and upload it again. | File refused | +| `IMP-FILE-ENCRYPTED` | The file is password-protected | Remove the password in the program that created it, save it again and upload the new copy. | File refused | +| `IMP-FILE-EMBEDDED-OBJECTS` | The workbook contains embedded objects | Embedded files and objects aren't read. Remove them or copy the data into a new workbook. | File refused | +| `IMP-FILE-EXTERNAL-LINKS` | The workbook links to other files | Formulas that read other files can't be refreshed here. Paste the values in place and save again. | File refused | +| `IMP-FILE-EMPTY` | The file has no data | Check that you exported the right report and that the first row holds the column names. | File refused | +| `IMP-FILE-ENCODING` | We had to guess the text encoding | If names with accents look wrong, export the file again as UTF-8 CSV. | Warning | +| `IMP-FILE-FIELD-TOO-LONG` | A cell is too long to read | One cell holds more text than Resgrid accepts. Shorten it or remove the column. | Blocking | +| `IMP-FILE-HASH-MISMATCH` | The upload was damaged on the way | The file we received differs from the one you chose. Upload it again. | File refused | +| `IMP-FILE-INFECTED` | The file failed the virus scan | Resgrid didn't open this file. Check your computer, export the data again and upload the new file. | File refused | +| `IMP-FILE-SCAN` | The file couldn't be scanned | Try again later. If it keeps happening, ask Resgrid support. | File refused | +| `IMP-FILE-SCAN-PENDING` | Waiting for the virus scan | The scanner is busy; Resgrid keeps trying automatically. | Run status | +| `IMP-FILE-SCAN-UNAVAILABLE` | Virus scanning is unavailable | Resgrid keeps trying for a while. If it doesn't recover, upload a CSV file instead. | File refused | +| `IMP-FILE-SCANNING-REQUIRED` | This kind of file needs a virus scan | Scanning isn't available here, so only CSV, text and JSON files are accepted. Export the data as CSV. **Tip:** Excel workbooks need virus scanning on the server; CSV always works. | Upload stopped | +| `IMP-FILE-TOO-MANY-ROWS` | The file has more rows than your plan allows | Only the first rows were checked. Split the file into smaller files. | Blocking | +| `IMP-FILE-TOO-WIDE` | The file has too many columns | Remove columns you don't need, or split the file. | Blocking | +| `IMP-FILE-UNSUPPORTED` | This kind of file isn't supported yet | Upload CSV, Excel (.xlsx) or JSON. **Tip:** ZIP packages, KML, KMZ and GPX are recognized but not imported yet. | File refused | +| `IMP-FILE-CONTROL-CHAR` | N cells contain hidden control characters | Invisible characters were found that Resgrid can't store. Remove them in your spreadsheet, or exclude the rows. | Blocking | +| `IMP-ZIP-ENTRIES` | The archive holds too many files | Unpack it and upload the files you need one by one. | File refused | +| `IMP-ZIP-NESTED` | The archive contains another archive | Unpack both and upload the files you need one by one. | File refused | +| `IMP-ZIP-PATH` | The archive contains an unsafe file path | Unpack it and upload the files you need one by one. | File refused | +| `IMP-ZIP-RATIO` | The archive expands to an unusually large size | Unpack it and upload the files you need one by one. | File refused | +| `IMP-ZIP-TOO-LARGE` | The archive is too large | Unpack it and upload the files you need one by one. | File refused | +| `IMP-ARTIFACT-CORRUPT` | The stored file is damaged | Upload the file again. | Run status | +| `IMP-ARTIFACT-KEY-INVALID` | The stored file can't be read | Upload the file again. If this keeps happening, ask Resgrid support. | Run status | +| `IMP-ARTIFACT-KEY-MISSING` | The stored file can't be read | Upload the file again. If this keeps happening, ask Resgrid support. | Run status | +| `IMP-ARTIFACT-MISSING` | The file is no longer available | It may have passed its retention date. Upload it again. | Run status | +| `IMP-ARTIFACT-PURGED` | The file was deleted after its retention period | Upload it again to continue. | Run status | +| `IMP-ARTIFACT-TAMPERED` | The stored file failed its integrity check | Resgrid didn't use it. Upload the file again and tell Resgrid support. | Run status | +| `IMP-ARTIFACT-TRUNCATED` | The stored file is incomplete | Upload the file again. | Run status | +| `IMP-STORE-UNAVAILABLE` | File storage is unavailable | Resgrid retries automatically. You can close this page. | Run status | + + + +### Reading the file + +The file passed the safety checks but its rows or columns could not be read cleanly. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-PARSE-COLUMNS` | N rows have more values than there are columns | A stray comma or tab usually shifts the row. Fix the rows in your file, or exclude them. | Blocking | +| `IMP-PARSE-CSV` | The CSV file couldn't be read | Check that quotes are balanced. Saving it again from Excel usually fixes it. | Blocking | +| `IMP-PARSE-HEADER-DUP` | Two columns have the same name | Only one of them can be matched. Rename one in the file if both hold data you need. | Warning | +| `IMP-PARSE-JSON` | The JSON file couldn't be read | Check that the file is valid JSON. | Blocking | +| `IMP-PARSE-JSON-SHAPE` | The JSON file isn't a list of records | Upload a list of objects, one per record. | Blocking | +| `IMP-PARSE-TIMEOUT` | Reading the file took too long | Split the file into smaller files. | Blocking | +| `IMP-PARSE-XLSX` | The Excel workbook couldn't be read | Open it in Excel and save it again as .xlsx. | Blocking | + + + +### Matching columns + +What the file contains and which column fills which Resgrid field. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-DETECT-LOW-CONFIDENCE` | We're not sure what this file contains | Choose what the file contains under Destination, then check the column matches. | Blocking | +| `IMP-MAP-REQUIRED-UNMAPPED` | A required field has no column | Match a column to it, or set the same value for every row: the issue offers the field's value and **Use for every row** (see [Same value for every row](matching-columns-and-values#same-value)). | Blocking | +| `IMP-MAP-FIELD-TWICE` | Two columns are matched to the same field | Match only one column to each Resgrid field. | Blocking | + + + +### Values + +Each matched value is converted to its field's type. A value that cannot be read blocks the row when the field is required; otherwise it is a warning and the value is left empty if you accept it. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-TYPE-BOOLEAN` | N values aren't yes or no | Use yes/no, true/false, 1/0, or x and blank. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-COLOUR` | N colours couldn't be read | Use a hex colour such as #D32F2F. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-COORDINATE` | N coordinates are out of range | Latitude is between -90 and 90 and longitude between -180 and 180, in decimal degrees. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-DATE` | N dates couldn't be read | Use a full date such as 2026-03-04. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-DATE-AMBIGUOUS` | N dates could be read two ways | Tell us whether the column is day/month or month/day; we ask once per column. On the Issues tab, answer *Does 03/04/2026 mean 3 April 2026 or 4 March 2026?* with **Day first** or **Month first**, or choose under [How dates are written](matching-columns-and-values#dates) on the data set page. **Tip:** Dates written as YYYY-MM-DD (2026-03-04) are never ambiguous: fix the column in your spreadsheet and upload it again, or exclude the rows. | Blocking | +| `IMP-TYPE-DATETIME` | N dates and times couldn't be read | Use a full date and time such as 2026-03-04 14:30. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-DATETIME-DST` | N times fall in a daylight-saving gap | These local times don't exist on that date. Check them in your system. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-DECIMAL` | N values aren't numbers | Use digits with a point or comma for decimals. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-INTEGER` | N values aren't whole numbers | Use whole numbers without units. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-LANGUAGE` | N languages weren't recognized | Use a language code such as en, es or fr. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-RANGE` | N values are out of range | Check the allowed range shown with the field. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-TIME` | N times couldn't be read | Use 24-hour times such as 14:30. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-TIMEZONE` | N time zones weren't recognized | Use a time zone name such as America/Chicago, or leave it empty for your department's time zone. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-TOO-LONG` | N values are too long | They are shortened if you accept the warning, or you can edit them in your file. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-UNKNOWN` | N values couldn't be read | Check the values in your file. | Blocking if the field is required, otherwise a warning | +| `IMP-TYPE-URL` | N web addresses couldn't be read | Use a full address that starts with https://. | Blocking if the field is required, otherwise a warning | +| `IMP-EMAIL-INVALID` | N email addresses look wrong | Each person needs a working email address to be invited. | Blocking if the field is required, otherwise a warning | +| `IMP-PHONE-UNPARSEABLE` | N phone numbers couldn't be read | Phone numbers need a country code, for example +1 555 123 4567. We assumed your department's country; check these numbers. | Blocking if the field is required, otherwise a warning | +| `IMP-CHOICE-UNMAPPED` | N values don't match a Resgrid option | Match each value to a Resgrid option under Match values. **Tip:** See [Matching values](matching-columns-and-values#match-values). | Blocking if the field is required, otherwise a warning | + + + +### Row rules + +Rules that look at a whole row. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-REQUIRED-MISSING` | N rows are missing a required value | Fill in the value in your file, set a value for these rows, or exclude them. | Blocking | +| `IMP-ROW-EXPIRES-BEFORE-ISSUED` | N certifications expire before they were issued | Check the dates; one of them is probably wrong. | Blocking | +| `IMP-ROW-COORDINATES-PAIR` | N rows have only a latitude or only a longitude | Give both or neither. | Blocking | +| `IMP-EXCLUDED-SENSITIVE` | A column was left out on purpose | Resgrid never imports passwords, national ID numbers, card numbers or similar data. Nothing to do. **Tip:** See [what is never imported](before-you-start#not-imported). | Note | + + + +### File-wide rules + +Rules that look across every row of the data set. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-DUP-IN-FILE` | N rows are duplicates within the file | Each value may appear only once. Remove the extra rows or exclude them. | Blocking | +| `IMP-DUP-SOURCE-ID` | N rows share the same record ID | Each record ID must be unique. Fix the IDs or exclude the extra rows. | Blocking | +| `IMP-HIERARCHY-CYCLE` | N groups form a loop of parents | A group can't be its own parent's parent. Change one parent to break the loop. | Blocking | + + + +### References + +Values that point at another record: a row in another file of the workspace or a record already in Resgrid. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-REF-UNRESOLVED` | N references don't match anything | The value names a record we couldn't find in your files or in Resgrid. Match it under Match values, or add the record. **Tip:** See [Matching values](matching-columns-and-values#match-values). | Blocking | +| `IMP-REF-AMBIGUOUS` | N references match more than one record | Make the names unique, or match the value under Match values. | Blocking | + + + +### Your department + +Checks against what your department already has, your plan and the modules you use. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-MATCH-EXISTING` | N rows match records that already exist | They are linked to the existing records, not added again. | Note | +| `IMP-MATCH-AMBIGUOUS` | N rows match more than one existing record | Your department has two records with this name. Rename one in Resgrid, or exclude these rows. | Blocking | +| `IMP-PERSON-EXISTING-ACCOUNT` | N people already have a Resgrid account | They are invited to join your department at activation instead of being added. **Tip:** See [Existing Resgrid accounts](people#people-accounts). | Note | +| `IMP-PERSON-DELETED-MEMBER` | N people were removed from your department before | They come back when you confirm it on Review & import, and can't sign in or receive anything until you invite them. Exclude their rows to leave them out. | Note | +| `IMP-PERSON-INACTIVE` | N people are marked inactive | They are imported disabled and hidden. | Note | +| `IMP-PERSON-WILL-BE-ADMIN` | N people will become administrators | You confirm each one before going live; until then they are normal members. | Note | +| `IMP-PLAN-CAPACITY` | Your plan doesn't have room for everyone | Upgrade your plan, or import fewer people or units. **Tip:** Your plan's limits are on [Subscription & Billing](../subscription-billing). | Blocking | +| `IMP-PLAN-CAPACITY-UNKNOWN` | We couldn't check your plan's limits | Try again shortly. Nothing that needs a seat is imported until the check works. | Blocking | +| `IMP-ENTITLEMENT-MISSING` | This data needs a feature your department hasn't turned on | Turn on the module, or ask Resgrid support. **Tip:** Points of interest need the Mapping module switched on under Department Settings → Module Settings. | Blocking | +| `IMP-CUSTOM-FIELDS-MISSING` | Add these custom fields first: ‹field names› | Your department already has custom fields. Add fields with these names on the Custom Fields screen, then check the file again. **Tip:** The screen is [User Defined Fields](../user-defined-fields) (Department menu). | Blocking | + + + +### Consequences + +What Resgrid will do later because the imported data exists. Each one is a statement you tick on Review & import. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-CONSEQUENCE-UNDECIDED` | A consequence needs your decision | Read the statement under Review & import and tick it to continue. **Tip:** See [Consequences](review-and-import#l8-consequences). | Blocking | +| `IMP-REPLACE-UNSUPPORTED` | Replace isn't available for this kind of data | Replace works for call priorities and certification types. Choose Add only or Review updates, or leave this data set out. **Tip:** See [Replace](review-and-import#replace). | Blocking | +| `IMP-REPLACE-ONE-DATASET` | Replace takes one file per kind of data | Another data set has the same destination. Exclude one of them, or put all the rows in one file. | Blocking | +| `IMP-REPLACE-CANNOT-RETIRE` | Some existing records can't be retired | They are still in use, for example a certification type people hold, so Replace can't retire them. Add them to your file, or choose Review updates. | Blocking | + + + +### Import and approval + +Shown on the History tab while an import runs, or on the rows an import could not write. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-APPROVAL-STALE` | The data changed after it was approved | Review it and approve it again. | Run status | +| `IMP-APPROVER-NOT-AUTHORIZED` | The approver can no longer approve imports | Another administrator needs to approve the import again. | Run status | +| `IMP-DEPARTMENT-LOCKED` | Another operation is running for your department | Resgrid tries again automatically when it finishes. | Run status | +| `IMP-RUN-ERROR` | A temporary problem interrupted the work | Resgrid tries again automatically. | Run status | +| `IMP-RUN-TRANSIENT` | A temporary problem interrupted the work | Resgrid tries again automatically. | Run status | +| `IMP-RUN-NO-HANDLER` | This kind of run isn't available | Ask Resgrid support. | Run status | +| `IMP-RUN-NOTHING-APPROVED` | Nothing was approved for this run | Approve data sets under Review & import. | Run status | +| `IMP-RUN-STALLED` | The work stopped making progress | Resgrid restarts it automatically from the last checkpoint. | Run status | +| `IMP-WORKSPACE-CLOSED` | The workspace is closed | Start a new workspace. | Run status | +| `IMP-CHANGED-SINCE-PREVIEW` | N records changed after the preview | Someone edited them in Resgrid. Review those rows again. | Row not imported | +| `IMP-TARGET-MISSING` | N matched records no longer exist | They were deleted after the preview. | Row not imported | +| `IMP-ROW-WRITE-FAILED` | N rows couldn't be imported | The rest of the import continued. Ask Resgrid support about these rows. | Row not imported | +| `IMP-PERSON-ACCOUNT-FAILED` | N accounts couldn't be created | The rest of the import continued. Ask Resgrid support about these people. | Row not imported | +| `IMP-CERT-TYPE-SCOPE` | N certifications use a type meant for units | Choose a certification type that people hold. | Row not imported | +| `IMP-UNIT-CERT-TYPE-SCOPE` | N unit certifications use a type meant for people | Choose a certification type meant for units. | Row not imported | +| `IMP-REQUIREMENT-TYPE-SCOPE` | N role requirements use a type meant for units | A role can only require a certification type that people hold. | Row not imported | +| `IMP-PROTECTED-WRITE-BLOCKED` | N rows couldn't be saved with their protection | Advanced Data Protection could not protect these values, so they were not saved. Try the import again later, or ask Resgrid support. | Row not imported | +| `IMP-DEFERRED-FAILED` | Some finishing steps didn't complete | Group parents, next statuses or roles may need a check by hand. | Warning after import | +| `IMP-REPLACE-RETIRE-FAILED` | Some records weren't retired | They were taken into use after the preview, so they were kept. | Warning after import | +| `IMP-RECONCILE-MISMATCH` | The check after the import found a difference | Compare the counts under History, and ask Resgrid support if they don't match. **Tip:** See [Verify the result](verify-and-activate#verify-results). | Warning after import | + + + +### Rollback + +Items a rollback left in place for you to check by hand. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-ROLLBACK-ACCOUNT` | An account couldn't be closed | Remove the person on the Personnel screen. | Check by hand | +| `IMP-ROLLBACK-CHANGED-SINCE` | A record changed after the import | It was left as it is; check it by hand. | Check by hand | +| `IMP-ROLLBACK-FAILED` | A record couldn't be undone | Check it by hand. | Check by hand | +| `IMP-ROLLBACK-HAS-ACTIVITY` | A record is in use | It was used after the import (for example on a call, or the person signed in), so it was kept. **Tip:** See [what rollback keeps](rollback-and-retention#rollback-keeps). | Check by hand | +| `IMP-ROLLBACK-MANUAL` | A record needs a check by hand | Compare it with your source and fix it in Resgrid if needed. | Check by hand | +| `IMP-ROLLBACK-MEMBER-UPDATE` | Changes to an existing member need a check by hand | Something the import added to this person was changed afterwards, so it was left as it is. Review their group, roles and details on the Personnel screen. | Check by hand | +| `IMP-ROLLBACK-NO-COMMIT` | The import to undo wasn't found | Ask Resgrid support. | Run status | +| `IMP-ROLLBACK-NO-WRITER` | This kind of record can't be undone automatically | Check it by hand. | Check by hand | + + + +### Upload + +Shown while a file is being sent. Nothing was stored; start the upload again. + +| Code | Title | What to do | Shown as | +|---|---|---|---| +| `IMP-UPLOAD-CHUNK-CONFLICT` | Two uploads of the same file overlapped | Wait a moment and try again. | Upload stopped | +| `IMP-UPLOAD-CHUNK-EMPTY` | Part of the upload was empty | Upload the file again. | Upload stopped | +| `IMP-UPLOAD-CHUNK-HASH` | Part of the upload was damaged | Upload the file again. | Upload stopped | +| `IMP-UPLOAD-CHUNK-ORDER` | Parts of the upload arrived out of order | Upload the file again. | Upload stopped | +| `IMP-UPLOAD-CHUNK-SIZE` | Part of the upload had the wrong size | Upload the file again. | Upload stopped | +| `IMP-UPLOAD-EXPIRED` | The upload took too long | Start the upload again. | Upload stopped | +| `IMP-UPLOAD-INCOMPLETE` | The upload didn't finish | Upload the file again. | Upload stopped | +| `IMP-UPLOAD-TOO-MUCH` | More data arrived than the file's size | Upload the file again. | Upload stopped | +| `IMP-WORKSPACE-FULL` | The workspace holds as much data as your plan allows | Delete files you don't need, or start a new workspace. | Upload stopped | + +*121 codes, from the English UI text.* + + diff --git a/docs/web-app/import-and-migration/getting-help-from-support.md b/docs/web-app/import-and-migration/getting-help-from-support.md new file mode 100644 index 0000000..755f4e5 --- /dev/null +++ b/docs/web-app/import-and-migration/getting-help-from-support.md @@ -0,0 +1,93 @@ +--- +sidebar_position: 10 +title: Getting Help from Support +--- + +# Getting Help from Resgrid Support + +**Department menu → Import & Migration → (workspace) → Support** + +If an import is stuck, open a **support request** from the workspace. Resgrid support sees the request with its context — which data set, which issue codes, which run — but none of your data. If they need to see more, you decide how much and for how long by granting **support access**, and you can take it back at any time. Every action a Resgrid staff member takes in your workspace appears on its timeline. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +- The **Support** tab of a workspace — its badge counts unread messages. +- **Help from Resgrid** on the Overview tab (*Stuck? Ask Resgrid support. We see what you choose to share, never more.*) with **Get help from Resgrid support**, your recent requests and any waiting suggestions. +- **Ask support about this** on every issue group, which opens the Support tab with the issue code attached. +- The workspace heading shows the current support access (*Off*, or the level and its expiry), open requests and unread messages. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. Granting access needs your second factor. See [Overview → Turning it on](overview#enable). + + +## Support requests + +**Get help from Resgrid support** — *Describe what you need. We attach the workspace and the item you came from; your data stays private unless you grant access below.* + +| Field | Notes | +|---|---| +| **About** | The issue code you came from, attached automatically. | +| **What do you need?** | *Something went wrong* (handled with higher priority), *A problem with my data* or *A question*. *Please do the migration for us* appears only when Resgrid has set up a [managed migration](#managed) for your department. | +| **Subject** | Required, up to 200 characters. | +| **Details** | Up to 4,000 characters. *Please don't paste personal information here; grant access instead if support needs to see your data.* | + +**Send request** — *Request sent. We'll reply here and by email.* The request gets a number and is listed under **Support requests** with its category and status: + +| Status | Meaning | +|---|---| +| **Open** | Waiting for Resgrid support. | +| **Acknowledged** | Support is working on it. | +| **Waiting for you** | Support needs something from you — see Messages. | +| **Resolved** | Support thinks it is fixed: **Confirm resolved** to close it, or **Reopen** it. | +| **Closed** | Done. | + +A request carries the workspace, the data set or run you came from, the issue codes with their counts and the number of blocking issues — never values from your files, file names or column names. On Resgrid's hosted service it is also filed in Resgrid's helpdesk with your department's name, the category, your own words and those codes and counts. On a self-hosted installation without a helpdesk configured, requests stay inside the application. + + +## Messages + +Each workspace has one conversation with Resgrid support. Your messages are labelled *Your department*, staff messages *Resgrid support*; status updates appear here too. Staff messages are plain text. When support posts a message, a suggestion or a status change, the administrator who started the workspace gets a notification and the unread count appears on the Support tab. On Resgrid's hosted service, support's replies about a request are also copied to that request's helpdesk ticket as internal notes, so the support team sees the whole conversation there; your own messages stay in the workspace. + + +## Suggestions + +With access at **Observe** or above, support can propose fixes instead of telling you what to click. They appear on the Support tab labelled **Suggested by Resgrid Support** — *Suggested column matches*, *Suggested value matches*, *Suggested fix for an issue* or a *Note* — and the Overview tab says how many are waiting. **Accept** applies the suggestion as your own decision and checks the data set again; **Reject** discards it. Nothing support suggests changes your workspace until you accept it, and accepted changes still need your approval on Review & import before anything is imported. + + +## Support access + +**Support access** — *Choose how much Resgrid support may see or do in this workspace, and for how long. You can revoke it at any time.* + +| Level | Support can see | Support can do | +|---|---|---| +| **Off** (default) | Only how the import is going: statuses, row and issue counts, issue codes, run times and errors, file sizes and scan results, your requests and messages. No workspace, data set, file or column names and no values. | Reply in the message thread and set a request's status (*Acknowledged*, *Waiting for you*, *Resolved*). Recovery actions that change none of your data: retry a failed run, release a run whose worker lease has expired, pause a run, re-run the checks (approvals already given are withdrawn), flag the workspace for Resgrid engineering, and — at your request — keep files up to 30 days longer or delete the stored files now. | +| **Observe** | *Progress, counts and issue codes, no values* — plus the names of your workspace, data sets and files, your column names and how they are matched, the row numbers of issues, and your [Configure](configure) tab as you see it (your settings, suggestions and decisions). | Everything above, plus suggest column and value matches. | +| **Inspect** | *Also sample values to diagnose a problem*: up to 20 rows behind one issue, with personal values (such as emails and phone numbers) partly masked and restricted or protected values never shown. Each time, your timeline shows *Sample rows viewed to diagnose an issue* with support's reason, and you get a notification. | Everything above, plus suggest fixes for issues. | +| **Prepare** | Everything above. | *Also fix mappings and values as drafts you approve*: choose a data set's destination, match its columns and values (including how dates are written, a column used for two fields and a value every row should share), choose how existing records are treated (the preview is recalculated), say which earlier import this one continues and which [products you are moving from](uploading-and-checks#products), prepare [settings](configure) (accept or decline suggestions, enter values, upload a logo — never permissions, and never over a value you decided), and — while this access lasts — let you choose [Replace](review-and-import#replace), and upload files into your workspace on your behalf. Support can also download a file you uploaded to work on it, unless your department uses Advanced Data Protection; each download appears on your timeline as *Uploaded file downloaded to work on it* with the reason, and you get a notification. Uploads are labelled as staff-authored and every change appears on the timeline as *Resgrid staff*. Staff never approve or import at this level. | +| **Operate** | Shown only for an agreed managed migration — see [below](#managed). | *Run the import for you, with two-person control.* | + +To grant access choose the **Access** level, **For how many days** (it starts at your department's [Default support access](rollback-and-retention#import-settings), 7 days unless changed; at most 30, or 90 for Operate), an optional **Note for support**, and **Grant access**, then confirm with your second factor. The panel then shows, for example, *Observe access until …* with **Revoke access**. Granting a new level replaces the current one, and access ends by itself when it expires. + +Values protected by [Advanced Data Protection](../data-protection) are never shown to Resgrid staff through Import & Migration, at any level. + +The **Access log** lists every grant with its date and level and whether it was revoked or expired. Grants, revocations and every staff action are also on the workspace **Timeline** (Overview tab), where staff actions carry a **Resgrid staff** label. Grants and revocations are recorded in your department's [audit log](../security-permissions#audit-logs) as well. + + +## If Resgrid is running your migration + +Some departments arrange for Resgrid to carry out the migration for them (a **managed migration**). This is agreed with Resgrid separately; it is described here so you know what you will see. + +- **Operate access.** It is granted either by one of your administrators — the **Operate** level appears in the Access list only once Resgrid has set up the engagement for your department — or, under a contract, by two different Resgrid super-administrators, in which case your department is notified straight away. +- **The banner.** While Operate access is active every workspace page shows *Managed by Resgrid (engagement) until (date). Resgrid staff can run this import for you; every action is logged.* with **Revoke access**. +- **Two-person control.** A Resgrid operator prepares an import or a rollback and asks for approval; a **different** Resgrid staff member reviews the same preview and approves it. Nobody approves their own work. If you ticked **Ask me before anything is imported** when granting access, the import or rollback then also waits for an administrator of your department: Review & import shows *Two Resgrid staff members approved this. It starts when an administrator of your department approves it.* with **Approve and start**. Before the second staff approval it shows *Resgrid staff requested this on your department's behalf. It waits for a second Resgrid staff member to approve it.* and you cannot approve yet. +- **Allowed actions.** Operate covers preparing data, fixing issues, importing and rolling back, and, when your grant allows it, confirming administrators, inviting your people and signing off. **Replace** is never included unless you tick it when granting access. Those last three always show up first on your [Verify & activate tab](verify-and-activate#managed), where you can approve or cancel them. Under a contract authorization every administrator is told 24 hours ahead, and nothing happens sooner unless one of you approves it. +- **Fixing rows.** To fix an issue, an operator may open the row behind it. Each time, the timeline shows *Row values viewed to fix an issue* with the operator's reason. Rather than a notification per row, every administrator gets one summary a day saying how many rows Resgrid staff opened since the last one, and by how many staff members. Protected (ADP) values are never shown, and staff cannot change them. +- **The timeline.** Every staff action is on your workspace timeline labelled *Resgrid staff*, and you are notified when an import Resgrid prepared is approved or waiting for you. +- **Revoking.** **Revoke access** takes effect immediately for viewing; an import that is running stops at its next safe point. Anything already imported stays, and it is your decision whether to roll it back. diff --git a/docs/web-app/import-and-migration/matching-columns-and-values.md b/docs/web-app/import-and-migration/matching-columns-and-values.md new file mode 100644 index 0000000..a5c772e --- /dev/null +++ b/docs/web-app/import-and-migration/matching-columns-and-values.md @@ -0,0 +1,184 @@ +--- +sidebar_position: 5 +title: Matching Columns & Values +--- + +# Matching Columns and Values + +**Department menu → Import & Migration → (workspace) → Files & data sets → Open** + +Every file other than the Resgrid starter workbook needs two kinds of matching before it can be imported. **Columns**: which column of your file fills which Resgrid field — *Cell* in your file is *Mobile phone* in Resgrid. **Values**: how the codes and names in your file map to Resgrid options and records — *ENG* is the unit type *Engine*, *Stn 1* is *Station 1*. Resgrid proposes both; you confirm or change them. Every change re-checks the file in the background. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Open a data set from the **Files & data sets** tab, from its card on the **Overview** tab (*Match columns*), or from the **Next step** card. The data set page has: + +| Panel | Contents | +|---|---| +| **Match columns** | One row per column of your file — see [below](#match-columns). | +| **Match values** | A link per field whose values must match a Resgrid option or record — see [Matching values](#match-values). | +| **Destination** | The data set's status and counts (*rows · ready · warnings · blocked*), **What does this file contain?** with a description of the chosen kind of data, and **Confirm** / **Change**. | +| **Saved matches** | **Use saved matches** and **Save these matches as** — see [Saved matches](#saved-maps). | +| **Issues** | The data set's top issues and **Fix issues**. | + +Once a data set is being imported (or has been), its matches are locked. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + + +## Confirm what the file contains + +Resgrid proposes a destination from the column headers (see [From files to data sets](uploading-and-checks#data-sets)). While it is not confirmed, the Data sets table shows an *N% sure* chip and, below 85%, a blocking issue *We're not sure what this file contains*. Pick the right kind of data under **What does this file contain?** and select **Confirm** (or **Change** after it has been confirmed). Changing the destination proposes a fresh set of column matches for it. + + +## Glossary + +When you have told Resgrid which products you are moving from ([Where your data comes from](uploading-and-checks#products)), a **Glossary** panel on the data set page (and, closed, on the Files and Configure tabs) lists each product's words next to what Resgrid calls that kind of record — for example, from Aladtec: + +| In Aladtec | In Resgrid | +|---|---| +| Members | People *(Suggested name)* | +| Work groups | Stations and groups | +| Positions | Roles | +| Qualifications | Certification types | +| Schedules | Shifts (not imported) | +| Payroll | Not imported | + +A word that lands in a data set names it as **What does this file contain?** does, so you can pick the right destination. *(not imported)* means Resgrid has that feature but an import doesn't fill it; **Not imported** means Resgrid keeps no such record. Features are named as your department names them. **Suggested name** marks a word that the [Configure tab](configure#suggestions) offers as your name for the feature. Words are shown in your language when the product has them (DIVERA 24/7 in German, for example), otherwise as the product shows them. + + +## Matching columns + +| Column | What it shows | +|---|---| +| **Column in your file** | The header, with a confidence chip for the proposed match; matches below 80% are highlighted as uncertain. | +| **What we found** | The value type Resgrid sees (Text, Whole number, Date, Email, Phone …), how full the column is (*N% filled*) and up to three example values. Columns with emails, phone numbers or many different names show **Values hidden** instead of examples; columns that look like passwords, ID numbers, card numbers or other [never-imported data](before-you-start#not-imported) show **Never imported (sensitive data)** and are dropped whatever you choose. | +| **Resgrid field** | **Don't import**, any field of the destination (required fields end in `*`), or **Keep as a custom field** for people and units. | +| **Clean-up** | Optional transforms applied to every value of the column before it is checked — see [Clean-up transforms](#transforms). | +| **How dates are written** | Shown when the column goes to a date field — see [Dates](#dates). | + +Under each column, **Also use for another field** adds a second row for the same column, so one column can fill two fields — see [One column, two fields](#split). **Remove** takes such a row away again. + +Select **Save matches** when you are done: *Saved. We're checking the file again.* The matches, the date answers and the [same value for every row](#same-value) are saved together. + +How the proposal works: each header is compared with the field names and the other names each field is known by (*e-mail*, *mail* and *email address* all mean the person's email; the known names are listed on each [field reference](people) page). An exact match is 100%; a header that contains a known name scores between 60% and 90%; anything weaker is left as *Don't import*. Each field is proposed for one column only. + +Rules the checks enforce: + +- Every **required** field (marked `*`) needs a column or a [same value for every row](#same-value) — otherwise *A required field has no column*. +- A field can be filled by **one column** only — otherwise *Two columns are matched to the same field*. One column can fill several fields, though ([below](#split)). +- Match the column holding the old system's record ID to **Source ID**. Other files can then refer to these rows by it, and re-uploading a corrected file in the same workspace — or in a workspace that [continues this import](uploading-and-checks#continue) — recognizes the rows already imported. +- Columns left as **Don't import** are not imported. + + +## Clean-up transforms + +Choose up to five per column; they run in the order listed. + +| Transform | Turns | Into | +|---|---|---| +| **Trim spaces** | ` Engine 1 ` | `Engine 1` | +| **Collapse spaces** | `Engine 1` | `Engine 1` | +| **UPPER CASE** | `e1` | `E1` | +| **lower case** | `ALEX@EXAMPLE.ORG` | `alex@example.org` | +| **Title Case** | `STATION ONE` | `Station One` | +| **Digits only** | `(555) 123-4567` | `5551234567` | +| **First name from full name** | `Rivera, Alex` or `Alex Rivera` | `Alex` | +| **Last name from full name** | `Rivera, Alex` or `Alex Rivera` | `Rivera` | +| **First word** | `Engine 1 Reserve` | `Engine` | +| **Last word** | `Engine 1 Reserve` | `Reserve` | + + +## One column, two fields + +To split a single *Name* column into first and last names, match the column to **First name** with *First name from full name*, select **Also use for another field** under it, and match the new row (*Same column, another field*) to **Last name** with *Last name from full name*. Each use has its own clean-ups. The same works for any column that holds two things, for example the first word of *Engine 1 Reserve* as one field and the last word as another. + + +## Dates + +A date such as `03/04/2026` can be read two ways. For a column that goes to a date field, **How dates are written** answers it once for the whole column, showing one of the column's own values both ways: + +| Choice | Reads `03/04/2026` as | +|---|---| +| **Work it out from the values** (default) | Only dates that settle it themselves (`13/04/2026`, `2026-04-03`); the rest raise *N dates could be read two ways*. | +| **Day first** | 3 April 2026 | +| **Month first** | 4 March 2026 | +| **Year first** | Dates written `2026-04-03` | + +The answer is about order, not punctuation: `03.04.2026` and `03-04-2026` are read the same way as `03/04/2026`. Dates written `2026-04-03`, and date cells in Excel, are always read correctly. You can also answer from the issue itself on the [Issues tab](fixing-issues#imp-type-date-ambiguous). + + +## Same value for every row + +**Same value for every row** lists the fields no column fills, with any value you already set. A value there fills that field in every row — for example the same **Station or group** for everyone in a roster that has no station column — and also fills rows whose column for that field is empty. Choice fields offer their options; other fields show an example of what they accept, and a value the field cannot hold is refused when you save (*That value doesn't fit this field*). **Source ID** and fields that must be unique, such as a person's email, cannot share one value. A required field with no column can also be given its value from the issue on the Issues tab. + + +## Keep as a custom field + +For **people** and **units**, a column with no matching Resgrid field — badge colour, locker number, radio ID — can be kept as a [custom field](../user-defined-fields). Its values go into the custom field whose label matches the column header (ignoring case, spaces and punctuation). + +- **If your department has no custom fields yet** for that kind of record, the import creates them: one text field per kept column, labelled with the column header and **visible to department administrators only**. You can change the fields afterwards on the User Defined Fields screen. +- **If your department already has custom fields** for that kind of record, the import does **not** change them — publishing a new set would hide every value saved against the current one. Instead the data set shows *Add these custom fields first: …* with the missing labels. Add fields with exactly those labels on **Department menu → User Defined Fields**, then select **Save matches** again so the file is checked again. + + +## Saved matches + +Column matches can be saved for the next file with the same layout — next month's export, or a sister station's roster. + +- **Save these matches as** stores the current matches under a name for this kind of data. Saving again with the same name keeps the old version and adds a new one. +- **Use saved matches** lists the saved matches for this kind of data; **Apply** fills in the matches by column header and checks the file again. + +Saved matches belong to your department, not to a workspace, and are kept while your department exists. They hold column names and choices only — never values from your files. + + +## Matching values + +Fields that must match something in Resgrid are listed under **Match values** on the data set page: + +- **Choice fields** must be one of the field's options — a station's *Type* is `station` or `organizational`, a status set's *Set type* is `personnel`, `unit` or `staffing`. Values equal to an option's code or one of its known names (listed on the field reference pages) are matched automatically. +- **Reference fields** point at another record — a person's *Station or group*, a unit's *Type*, a certification's *Person*. A reference is found automatically when it names a row in another file of the same workspace (by its Source ID, or by its name, code or email) or a record already in Resgrid (by name; a person by email), ignoring case, accents, spaces and punctuation. + +Open a field to see every distinct value in the file (the 500 most frequent), how many rows use it, Resgrid's **Suggestion** with a confidence chip, and **Your choice**: + +| Choice | Effect | Offered for | +|---|---|---| +| *an option* / *an existing record* | Use it for every row with this value. | Choices; references (when Resgrid found a record with the same name) | +| **Create new** | Create a record with this name during the import; every row with the value shares the one new record. | References to stations and groups, roles, certification types, unit types and point of interest types | +| **Keep as text** | Import the rows without linking them to a record. | References | +| **Leave empty** | Import the rows with this field empty. | Choices and references | +| *Not decided* | Leave it to the automatic match — rows that still match nothing get an issue. | Both | + +The bar **For all rows:** applies **Accept the suggestions**, **Create new for all** (references) or **Leave empty for all** at once. Select **Save choices**: *Saved. We're checking the file again.* Your choices are saved with this data set and count as part of what you approve. + +Choice suggestions are 100% when a value equals an option's code or known name and 60% when it is the start of one (`stat` → `station`). Reference suggestions are existing Resgrid records with the same name; rows in your other files do not need a decision because they are matched automatically. + + +## How values are read + +| Type | Accepted | +|---|---| +| **Text** | Trimmed. Longer than the field allows: a warning — the text is shortened if you accept it. | +| **Whole number** | Digits with an optional sign; spaces are ignored and `12.0` counts as `12`. Checked against the field's range. | +| **Number** | A point or a single comma as the decimal separator. | +| **Yes/No** | Yes: `yes`, `y`, `true`, `t`, `1`, `x`, `on`, `active`, `enabled` (also `ja`, `oui`, `si`, `sí`, `sì`, `tak`, `так`, `ναι`, `نعم`). No: `no`, `n`, `false`, `f`, `0`, `off`, `inactive`, `disabled`, `-` (also `nein`, `non`, `nie`, `nej`, `ні`, `όχι`, `لا`). Empty means not set. | +| **Date** | `2026-03-04` or `2026/03/04`; Excel date cells; named months (`4 Mar 2026`, `March 4, 2026`, `4-Mar-26`). `04/03/2026`-style dates are accepted only when the value itself shows the order (a part above 12) — otherwise *dates could be read two ways*. | +| **Date and time** | A date as above plus `14:30`; with a `Z` or an offset it is taken as given, otherwise in your department's time zone. | +| **Email** | Lower-cased; `mailto:` and angle brackets are removed. | +| **Phone** | Stored in international format. A number without a country code is read with your department's country. | +| **Choice** | An option's code or a known name, or your value match. | +| **Reference** | See [Matching values](#match-values). | +| **Latitude / Longitude** | Decimal degrees (a comma also works as the decimal point), up to ±90 and ±180. | +| **Colour** | Hex, with or without `#`: `#d32f2f`, `d32f2f`, `#d33`. | +| **Time zone** | A Windows name (`Central Standard Time`) or an IANA name (`America/Chicago`). Empty uses the department's. | +| **Language** | `en`, `es`, `sv`, `de`, `fr`, `it`, `pl`, `uk`, `ar`, `el` — regional forms such as `en-US` are accepted. Empty uses the department's. | +| **List** | Values separated by `;` (or by commas when there are no semicolons); duplicates are dropped. | + +A value that cannot be read blocks its row when the field is required; otherwise it is a warning and the value is left empty if you accept it. See [Fixing issues](fixing-issues). diff --git a/docs/web-app/import-and-migration/overview.md b/docs/web-app/import-and-migration/overview.md new file mode 100644 index 0000000..8dedf1f --- /dev/null +++ b/docs/web-app/import-and-migration/overview.md @@ -0,0 +1,153 @@ +--- +sidebar_position: 1 +title: Import & Migration Overview +--- + +# Import & Migration — Overview + +**Department menu → Import & Migration** + +**Import & Migration** brings the data your department already has into Resgrid: people and their emergency contacts, stations and groups, roles and the certifications they require, certification types and the certifications people hold, unit types, units and their certifications, custom statuses, call types, call priorities, and points of interest with their types. You work from a spreadsheet (CSV, Excel `.xlsx`, JSON, JSON Lines or GeoJSON), from the Resgrid starter workbook, or from an export of the system you are leaving. Every row is checked and shown to you before anything is saved, every import is journaled so it can be rolled back, and imported people stay **dormant** — they cannot sign in and receive nothing — until you invite them. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## What you can bring + +Each kind of data is a **data set** with a fixed list of fields (its *contract*). One uploaded CSV file, or one sheet of a workbook, becomes one data set. Data sets are imported in dependency order: stations before the people who belong to them, unit types before the units that use them. + +| Data set | What it holds | Field reference | +|---|---|---| +| **Statuses** | Status buttons for people, units and staffing levels, grouped into sets. | [Statuses](statuses) | +| **Certification types** | The certifications your people (or units) hold — Firefighter I, EMT, CPR … | [Roles & certifications](roles-and-certifications#sheet-certification-types) | +| **Stations and groups** | Stations and organizational groups, with addresses and parent groups. | [Stations & groups](stations-and-groups) | +| **Roles** | The roles people fill — Engineer, Paramedic, Officer … | [Roles & certifications](roles-and-certifications#sheet-roles) | +| **People** | Members with contact details, station or group, roles and department-only details. | [People](people) | +| **People's certifications** | Which certifications each person holds, with numbers and dates. | [Roles & certifications](roles-and-certifications#sheet-personnel-certifications) | +| **Unit types** | The kinds of apparatus you run — Engine, Ladder, Ambulance … | [Units](units#sheet-unit-types) | +| **Units** | Apparatus and other units, with type, station, vehicle details and seats. | [Units](units#sheet-units) | +| **Call types** | The kinds of call you are dispatched to. | [Call types & priorities](call-types-and-priorities#sheet-call-types) | +| **Call priorities** | Priorities with colours and dispatch behaviour. | [Call types & priorities](call-types-and-priorities#sheet-call-priorities) | +| **Point of interest types** | The kinds of place on your map — Hydrants, Hospitals, Schools … | [Points of interest](points-of-interest#sheet-poi-types) | +| **Points of interest** | Places on your map, each with a type and a location. | [Points of interest](points-of-interest#sheet-pois) | + +Passwords, national ID numbers, card and bank numbers, dates of birth, alarm and gate codes and medical information are **never** imported — see [Before you start](before-you-start#not-imported). + + +## Where to find it + +- **Department menu → Import & Migration** (below *Subscription & Billing*). The item appears only for department administrators, and only when the feature is turned on for your department. +- **Admin Assist → Import & Migration**: the button in the toolbar on every Admin Assist tab, and the **Import & Migration** card beside the review on **Setup Report** and **Admin AI → Overview**. See [Help & Setup](../help-setup#start-setup). +- **Setup Wizard → step 1 → Import or migration → Open Import & Migration** — the starting point for a new department. See [Help & Setup](../help-setup#start-setup). +- Directly at `/User/DepartmentImport`. + +The landing page lists your **import workspaces** (name, what you are doing, status, last activity) with **Resume** / **Open** and **Cancel**, a **Start an import** panel, a link to these pages and a **Settings** button ([Import & Migration settings](rollback-and-retention#import-settings)). Two banners can appear: *File storage for imports is not set up on this system yet* (uploads are disabled until the server's import storage is configured) and *An import is running for your department right now* (you can prepare another workspace, but only one import writes at a time). + +A **workspace** holds everything for one migration: the files, the checked rows, your decisions, the import runs and the support conversation. You can leave and come back at any time; long steps run in the background and keep going if you close the page. + +| Start an import field | Notes | +|---|---| +| **What are you doing?** | *Set up a new department*, *Add to a live department*, *Update a live department (reviewed)* or *Continue an earlier import* — see [Workspace modes](#modes). | +| **Name** | For example *Move from our old system*. | +| **Internal reference** | Optional — a ticket or project number. | +| **Target go-live date** | Optional; shown in the workspace heading. | + +Inside a workspace the heading shows the mode, the target go-live date, *N of N data sets ready*, the **support access** badge (*Off*, or the level and its expiry), open support requests, unread messages and when it was last saved. The tabs are: + +| Tab | What it is for | Page | +|---|---|---| +| **Overview** | Your progress (journey steps with *Done* / *Needs attention* / *To do* chips), the **Next step** card, stat tiles (rows checked, ready to import, need attention, imported, people to invite), one card per data set, the top issues, help from Resgrid and the timeline. | this page | +| **Files & data sets** | Upload files, download the starter workbook and templates, see each data set; open one to match its columns and values. | [Uploading and checks](uploading-and-checks), [Matching](matching-columns-and-values) | +| **Issues** | Everything the checks found, grouped by problem, with one-click fixes. The tab shows the number of open blocking issues. | [Fixing issues](fixing-issues) | +| **Configure** | The settings the import changes — department record, profile and logo, modules, names, map, numbering, permissions — with suggestions from your operating profile and your data. | [Configure Resgrid](configure) | +| **Review & import** | The preview, the statements you confirm and **Approve and import**. | [Review and import](review-and-import) | +| **Verify & activate** | Results, the activation checklist, administrators, invitations and sign-off. | [Verify and activate](verify-and-activate) | +| **History** | Every run with its progress and counts; pause, resume, cancel and roll back. | [Rollback and retention](rollback-and-retention) | +| **Support** | Support requests, messages, suggestions and support access. | [Getting help from support](getting-help-from-support) | + + +## Turning it on + +| Requirement | Notes | +|---|---| +| **Feature flag `Onboarding.MigrationWizard`** | Off by default. On the hosted service Resgrid turns it on per department; on a self-hosted installation the operator does (see [Feature flags](../../reference/feature-flags)). | +| **Department administrator** | Only department administrators and the managing user can open the module — permission **72** *Manage Department Import* (`ManageDepartmentImport`). It is fixed to administrators: it is not on the Security screen and cannot be widened to roles. There is no read-only view for other members. | +| **Two-factor authentication** | Approving an import, rolling back, signing off and granting support access ask you to confirm with your second factor (within the last 10 minutes). Set it up under [Account security](../account-security). | +| **File storage** (self-hosted) | Uploaded files are stored encrypted in the installation's S3-compatible object store (`ImportConfig.S3*`, bucket `resgrid-imports`). Without it uploads are disabled. | +| **Virus scanning** (for Excel) | Excel workbooks are accepted only when the server scans uploads (`AttachmentScanningConfig`). Without scanning, CSV, text and JSON files still work. | +| **Mapping module** | Needed only for points of interest and their types. | + + +## The journey + +The **Your progress** list on the Overview tab follows these steps. Steps 3–6 repeat for each data set, and you can import in **waves** — for example stations and roles first, check them in Resgrid, then come back for people. + +| # | Step | You | Resgrid | +|---|---|---|---| +| 1 | **Start** | Start a workspace and choose what you are doing. | Creates the workspace. | +| 2 | **Get your files** | Download the [starter workbook](starter-workbook) or export from your current system, then upload. | Uploads in pieces, scans the file, splits workbooks into data sets and works out what each one contains ([details](uploading-and-checks)). | +| 3 | **Match columns and values** | Confirm what each file contains, which column fills which field, and how codes in your file map to Resgrid options ([details](matching-columns-and-values)). Skipped for the starter workbook. | Re-checks after every change. | +| 4 | **Fix issues** | Work through grouped issues: accept a warning, exclude rows, set a value, or fix the file and upload it again ([details](fixing-issues)). | Runs the [verification ladder](uploading-and-checks#ladder). | +| 4a | **Configure Resgrid** | Describe your department, then accept, change or decline the settings the import will change: names, modules, numbering and more ([details](configure)). | Suggests values from your operating profile and your data; changes nothing until you approve. | +| 5 | **Review & approve** | Read the preview, tick the statements, choose how existing records are treated, approve with your second factor ([details](review-and-import)). | Freezes what you approved; a second administrator may need to approve too. | +| 6 | **Import** | Watch progress on the History tab, or leave. You can pause or cancel between chunks. | Changes the accepted settings first, then writes in dependency order, in small chunks, journaling every change. | +| 7 | **Verify** | Review the checks that compare what was written with what was approved ([details](verify-and-activate)). | Reconciles counts and refreshes caches and search. | +| 8 | **Activate & invite** | Confirm administrators, invite people, sign off ([details](verify-and-activate#invite-people)). | Sends invitations in small batches outside night hours. | +| 9 | **After import** | Roll back within the window, or let files and checked data expire ([details](rollback-and-retention)). | Deletes files and checked data on schedule. | + + +## Workspace modes + +| Mode | Use it when | Default for existing records | Rollback window | +|---|---|---|---| +| **Set up a new department** | You are moving everything into a department that is not live yet. | Your department default (*Add only* unless changed in Settings). | Until you sign off, then 30 more days. | +| **Add to a live department** | Adding records — new members, more units — while people keep working. | Your department default. | 30 days after each import. | +| **Update a live department (reviewed)** | Correcting or enriching records that already exist — plates, phone numbers, groups. | **Review updates**. | 30 days after each import. | +| **Continue an earlier import** | A later export from the same system, or the next part of a phased move. | Your department default. | 30 days after each import. | + +Within one workspace, a row that was already imported is recognized by its **Source ID** when you upload a corrected file again, so it is not added twice. A new workspace recognizes an earlier workspace's Source IDs only when you say it [continues that import](uploading-and-checks#continue) on its Files tab — do that first when you choose *Continue an earlier import*. Otherwise, rows are matched to existing records by name (people by email) — see the matching rules on each [field reference](people#people-matching) page. + + +## Safety principles + +- **Nothing is saved before you approve it.** Uploading, matching and fixing only change the workspace. Records are written only by an import you approved on **Review & import**, and only for the data sets you ticked. +- **Imported people are dormant.** They cannot sign in, password reset is refused, and they receive no dispatches, messages, reminders or digests until you invite them. Nobody is emailed during an import — not even a welcome email. See [Dormant members](verify-and-activate#import-dormant-members). +- **Existing data is not overwritten by default.** *Add only* never changes what is already in Resgrid; *Review updates* changes only fields of matched records, skips anything someone edited after the preview, and never touches a person's own profile (name, phone numbers, language). +- **Every import can be rolled back** within its window. Records the import created are removed, changed records get their earlier values back, and anything used since stays for you to check by hand. See [Rollback](rollback-and-retention). +- **One import writes at a time.** An import holds a department lock that keeps a second import, an Advanced Data Protection migration and department deletion out — but your department keeps working normally while it runs. +- **Resgrid support sees only what you choose to share,** for as long as you choose, and every staff action is on your timeline. See [Getting help from support](getting-help-from-support). +- **Sensitive data stays out of your department's records.** Columns that look like passwords, ID numbers, card numbers, dates of birth or medical data are left out when the file is read: their values are never checked, held as workspace data, shown on screen or imported. The file you uploaded still contains them — it is stored encrypted and deleted on [a schedule](rollback-and-retention#retention-schedule), so take those columns out of the export before you upload it. + + +## Not in this release + +- **Configuration presets** (setting Resgrid up from your operating profile) and **historical data** (closed calls, training history, Records) are not part of this release. +- **Product packs** that recognize a specific vendor's export automatically are planned for later releases; until a pack is published, every file other than the Resgrid starter workbook goes through column matching, which works for any spreadsheet. +- ZIP packages, KML, KMZ and GPX files are recognized but not imported yet. + + +## Notices you receive + +The administrator who started the workspace (or, if they are no longer an administrator, the first active administrator) gets a notification when an import or rollback finishes, fails, pauses or waits for a decision; when Resgrid support posts a message, a suggestion or a status change; and after 30 days without activity. Notices name the outcome and link to the workspace — they never contain imported data. Each administrator receives them in the language set on their own profile (English when none is set). + +[Admin Assist](../help-setup) also follows imports: **Setup Report** counts the area as complete once an import has been verified, and findings appear when an import has been stuck on blocking issues for over a week, finished with unexplained differences, left imported people uninvited for over two weeks, or kept files longer than usual. + + +## Technical reference + +| Item | Value | +|---|---| +| Routes | `/User/DepartmentImport/{Index,Create,CancelWorkspace,Workspace,Files,Dataset,Values,Issues,Review,History,Verify,Support,Settings}`; JSON actions `Summary`, `UploadStart`, `UploadChunk`, `UploadComplete`, `UploadStatus`, `SaveMapping`, `SaveValues`, `IssueAction`, `RunStatus`; downloads `Template`, `CurrentData`; a form post per action (`SetDestination`, `Approve`, `ApproveAsChecker`, `RunControl`, `Rollback`, `Invite`, `SignOff`, `GrantAccess`, `RevokeAccess` …) | +| v4 API | `api/v4/DepartmentImport/{GetContracts,GetTemplate,GetWorkspaces,GetWorkspace,GetProgress,StartUpload,UploadChunk,CompleteUpload,StartAnalysis}` — read-mostly. Approval, import, rollback and activation need two-factor confirmation and exist only in the web application; department API keys get no import access. | +| Permissions | `ManageDepartmentImport` (72) — department administrators only, not on the Security screen; `ManageRecordImports` (73) — reserved for Records history imports, department administrators only | +| Feature flags | `Onboarding.MigrationWizard` (master, seeded off); `Onboarding.OperationsData`, `Onboarding.ReadinessData`, `Onboarding.OperationalHistory`, `Onboarding.HistoricalRecords`, `Onboarding.VendorPacks`, `Onboarding.DepartmentPackage` (later waves, seeded off); `Onboarding.ManagedMigration` (operator-only, per department) — see [Feature flags](../../reference/feature-flags#onboarding-flags) | +| Workers | **47** `DepartmentImportCommand` — every minute: runs checks, imports and rollbacks, a watchdog every five minutes, and sends due invitations in batches. **48** `DepartmentImportMaintenanceCommand` — hourly: aborts abandoned uploads, expires support access, deletes files and checked data past retention, reminds and closes idle workspaces, sends support requests to the helpdesk. | +| Department setting | `DepartmentSettingTypes.DepartmentImportConfig` (83) | +| Notifications | `EventTypes.DepartmentImportRunFinished` (50), `EventTypes.DepartmentImportSupportMessage` (51) — sent to the workspace owner, not department broadcasts | +| Department lock | `DepartmentOperationLockType.DepartmentImport` (2) — held by import and rollback runs; does not block normal department work | +| Member state | `DepartmentMembers.ImportActivationState` — empty (not imported or active), 1 Dormant, 2 Invited, 3 Activated | +| Contracts | `Providers/Resgrid.Providers.Import/Catalog/contracts/*.json` (catalog 2026.11.1) | +| Configuration | `ImportConfig` (object store, limits, engine), `AttachmentScanningConfig` (virus scanning), `SupportConfig` (helpdesk) | +| Design | `int-Coordination/docs/architecture/department-onboarding-migration-wizard-plan.md` | diff --git a/docs/web-app/import-and-migration/people.md b/docs/web-app/import-and-migration/people.md new file mode 100644 index 0000000..7c0b285 --- /dev/null +++ b/docs/web-app/import-and-migration/people.md @@ -0,0 +1,113 @@ +--- +sidebar_position: 11 +title: People Field Reference +sidebar_label: "Reference: People" +--- + +# People — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +The **People** data set brings in your members: names, email, phone numbers, station or group, roles and department-only details such as an ID number or home address. Every imported person is created **dormant** — they cannot sign in and receive nothing until you [invite them](verify-and-activate#invite-people). Because email addresses are unique across all of Resgrid, people are matched by email and some rows become *invitations to join* rather than new members; the rules are [below](#people-matching). + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **People** sheet of the [starter workbook](starter-workbook) or `resgrid-personnel.csv`, or upload your own roster and match it to *People* on the [matching](matching-columns-and-values) page. People refer to [stations and groups](stations-and-groups) and [roles](roles-and-certifications#sheet-roles), so import those first or in the same import. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. New people use seats on your plan. See [Overview → Turning it on](overview#enable). + + +## People sheet + + + +Your members: names, contact details, station or group, roles and department-only details. Imported people cannot sign in and receive nothing until you invite them. + +Starter workbook sheet **People**; CSV template `resgrid-personnel.csv`; imported after [Stations and groups](stations-and-groups#sheet-groups), [Roles](roles-and-certifications#sheet-roles); extra columns can be kept as custom fields. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The person's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `First name [first_name]` | `first_name` | Text | Yes | The person's first name. Up to 100 characters. Example: `Alex`. Headers recognized: first name, firstname, given name, first. | +| `Last name [last_name]` | `last_name` | Text | Yes | The person's last name. Up to 100 characters. Example: `Rivera`. Headers recognized: last name, lastname, surname, family name, last. | +| `Email [email]` | `email` | Email | Yes | The person's email address. Every Resgrid member needs one; it is how they are invited and sign in. Must be unique in the file. Example: `alex.rivera@example.org`. Headers recognized: email, e-mail, email address, mail. | +| `Mobile phone [mobile_phone]` | `mobile_phone` | Phone | | The number Resgrid texts and calls for dispatches. Include the country code, for example +1 555 123 4567. Example: `+1 555 123 4567`. Headers recognized: mobile, cell, mobile phone, cell phone, mobile number, phone. | +| `Home phone [home_phone]` | `home_phone` | Phone | | A second number Resgrid can call. Example: `+1 555 765 4321`. Headers recognized: home phone, home, home number, landline. | +| `Station or group [group]` | `group` | Reference | | The station or group the person belongs to, by its source ID or its name. A person belongs to one group. Refers to [Stations and groups](stations-and-groups#sheet-groups). Example: `Station 1`. Headers recognized: group, station, company, assigned station, home station. | +| `Group administrator [group_admin]` | `group_admin` | Yes/No | | Yes when the person manages their station or group. Example: `no`. Headers recognized: group admin, group administrator, station officer. | +| `Roles [roles]` | `roles` | List of reference | | The person's roles, separated by semicolons, by name or source ID. Separate values with `;`. Refers to [Roles](roles-and-certifications#sheet-roles). Example: `Engineer; EMT`. Headers recognized: roles, role, positions, qualifications. | +| `Department administrator [will_be_admin]` | `will_be_admin` | Yes/No | | Yes when the person should become a department administrator. It is applied only when you activate them, after you confirm it. Example: `no`. Headers recognized: admin, administrator, department admin, is admin. | +| `ID number [identification_number]` | `identification_number` | Text | | The department-issued member or badge number. Up to 100 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `E-1042`. Headers recognized: id number, badge, badge number, employee number, member number, employee id. | +| `Time zone [time_zone]` | `time_zone` | Time zone | | The person's time zone. Left empty, the department's is used. Example: `Central Standard Time`. Headers recognized: time zone, timezone, tz. | +| `Language [language]` | `language` | Language | | The language Resgrid uses for the person, such as en, es or fr. Left empty, the department's is used. Example: `en`. Headers recognized: language, locale, preferred language. | +| `Notes [notes]` | `notes` | Text | | Department-only notes about the person. Up to 4000 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `Prefers night shifts`. Headers recognized: notes, comments, remarks. | +| `Home street address [home_street]` | `home_street` | Text | | The person's home street and number, kept as department-only data. Up to 500 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `15 Oak Ave`. Headers recognized: home address, street, address. | +| `Home city [home_city]` | `home_city` | Text | | The person's home city. Up to 150 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `Springfield`. Headers recognized: home city, city. | +| `Home state or region [home_state]` | `home_state` | Text | | The person's home state, province or region. Up to 100 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `IL`. Headers recognized: home state, state. | +| `Home postal code [home_postal_code]` | `home_postal_code` | Text | | The person's home postal or ZIP code. Up to 32 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `62704`. Headers recognized: home zip, zip, postal code. | +| `Home country [home_country]` | `home_country` | Text | | The person's home country. Up to 100 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `United States`. Headers recognized: home country, country. | +| `Active [active]` | `active` | Yes/No | | No for former or inactive members: they are imported disabled and hidden, and never invited. Example: `yes`. Headers recognized: active, status, is active, enabled. | + +*Contract `personnel` version 2026.11.1, generated from the import catalog.* + + + + +## Emergency contacts sheet + + + +Who to call for each person in an emergency. Every value except the order and the primary flag is protected when your department uses Advanced Data Protection, and Resgrid staff never see them. + +Starter workbook sheet **Emergency contacts**; CSV template `resgrid-emergency-contacts.csv`; imported after [People](#sheet-personnel). + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The contact's id in the system you are leaving. A re-import of the same contact (same workspace, or an import that continues it) is recognized by it instead of adding the contact again. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Person [person]` | `person` | Reference | Yes | Whose contact this is, by the person's source ID or email. Refers to [People](#sheet-personnel). Example: `alex.rivera@example.org`. Headers recognized: person, member, member email, employee, employee email, staff. | +| `Contact name [name]` | `name` | Text | Yes | The full name of the person to call. Up to 200 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `Jordan Rivera`. Headers recognized: contact name, emergency contact, emergency contact name, next of kin, contact. | +| `Relationship [relationship]` | `relationship` | Text | | How the contact is related to the person, such as spouse or parent. Up to 100 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `Spouse`. Headers recognized: relationship, relation, relationship to member. | +| `Phone [phone]` | `phone` | Phone | | The contact's phone number. Include the country code, for example +1 555 987 6543. Department-only; protected by Advanced Data Protection when your department uses it. Example: `+1 555 987 6543`. Headers recognized: contact phone, emergency phone, phone, telephone. | +| `Alternate phone [alternate_phone]` | `alternate_phone` | Phone | | A second number to try. Department-only; protected by Advanced Data Protection when your department uses it. Example: `+1 555 222 3333`. Headers recognized: alternate phone, other phone, second phone, phone 2. | +| `Contact email [email]` | `email` | Email | | The contact's email address. Up to 256 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `jordan.rivera@example.org`. Headers recognized: contact email, emergency contact email, emergency email. | +| `Notes [notes]` | `notes` | Text | | Anything that helps reach the contact, such as when to call. Up to 4000 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `Call after 6 pm`. Headers recognized: notes, comments, contact notes. | +| `Primary contact [is_primary]` | `is_primary` | Yes/No | | Yes for the contact to call first. A person has at most one; the last one marked wins. Example: `yes`. Headers recognized: primary, is primary, first contact, primary contact. | +| `Order [sort]` | `sort` | Whole number | | The contact's position in the person's list; lower comes first. From 0 to 1000. Example: `1`. Headers recognized: order, sort, sort order, priority. | + +*Contract `emergency-contacts` version 2026.11.1, generated from the import catalog.* + + + +Emergency contacts are never matched by their values: every value except the order and the primary flag is protected, so a row always **adds** a contact. Give contacts a Source ID if you may upload the file again — a re-upload in the same workspace, or in one that [continues this import](uploading-and-checks#continue), then recognizes them. An import never changes an existing contact. A person has at most one primary contact; when several rows mark one, the last row wins. Rolling the import back removes the contacts it added. + + +## How people are matched + +A row is matched by its **Source ID** when the same workspace — or the import it [continues](uploading-and-checks#continue) — imported it before, otherwise by its **email address** — never by name or phone number. Emails must be unique within the file. + + + +| The row's email is … | What happens | +|---|---| +| **New to Resgrid** | A new account is created with **no password** and an unconfirmed email, a user name made from the email, the profile from the row, and a **dormant** membership in your department. No welcome email is sent. The person chooses a password when they accept their invitation. | +| **A current member of your department** (including dormant members) | Matched — *Update or link* in the preview. With *Add only* nothing changes. With *Review updates* only department data changes: station or group, group administrator, roles, ID number, notes and home address. Name, phone numbers, time zone and language belong to the person's own profile and are never changed by an import. | +| **A member removed from your department earlier** | Brought back, if you agree: the preview counts them under *Update or link*, and Review & import asks you to confirm *N people who were removed from your department will come back*. They return like everyone the import adds — not an administrator, unable to sign in or receive anything until you invite them — with the row's station or group, roles and details added where none are set. Each one takes a seat on your plan. Exclude their rows to leave them out; rolling the import back removes them again. | +| **An account that belongs only to other departments** | Never created, linked or changed, and nothing about the other department is shown — the issue only says *N people already have a Resgrid account*. The row becomes **Invite to join**: at activation the person gets an invitation to join your department with their existing account, and becomes a member only when they accept. See [Existing accounts](verify-and-activate#existing-accounts). | +| **Missing or invalid** | Blocking — every member needs a working email address, and Resgrid never invents one. Add the email or exclude the row. | + +More rules: + +- **Department administrator** = *yes* does not make anyone an administrator during the import. You [confirm each person](verify-and-activate#administrators) on Verify & activate. +- **Active** = *no* imports the person **disabled and hidden** (and dormant). They are never offered for invitation. +- **Roles** a person cannot hold yet because of your [certification requirements](../business-ops/certifications) are retried at the end of the import, after people's certifications have been written — so approve People and People's certifications in the same import. +- **Phone numbers** are stored in international format; numbers without a country code are read with your department's country. +- **Department-only fields** (ID number, notes, home address) are stored as department member data, protected by [Advanced Data Protection](../data-protection) when your department uses it. +- Extra columns can be [kept as custom fields](matching-columns-and-values#custom-fields) on people. diff --git a/docs/web-app/import-and-migration/points-of-interest.md b/docs/web-app/import-and-migration/points-of-interest.md new file mode 100644 index 0000000..d2ac22c --- /dev/null +++ b/docs/web-app/import-and-migration/points-of-interest.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 17 +title: Points of Interest Field Reference +sidebar_label: "Reference: Points of interest" +--- + +# Points of Interest — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +Two data sets put places on your [map](../mapping#points-of-interest-pois): **Point of interest types** (Hydrants, Hospitals, Schools …, each with a marker colour and whether it can be a status destination) and **Points of interest** (each place with its type and location). Types come first, or in the same import. GeoJSON files work well here: a point's coordinates become the latitude and longitude columns automatically. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **Point of interest types** and **Points of interest** sheets of the [starter workbook](starter-workbook) (or `resgrid-poi-types.csv` and `resgrid-pois.csv`), or upload a spreadsheet or GeoJSON export and match it on the [matching](matching-columns-and-values) page. **Download current data** exports your existing point of interest types. + + +## Turning it on + +Besides Import & Migration itself (the `Onboarding.MigrationWizard` flag and a department administrator), both data sets need the **Mapping** module switched on under **Department Settings → Module Settings**. Without it the data sets are blocked (*This data needs a feature your department hasn't turned on*). See [Overview → Turning it on](overview#enable). + + +## Point of interest types sheet + + + +The kinds of place on your map (Hydrants, Hospitals, Schools…). + +Starter workbook sheet **Point of interest types**; CSV template `resgrid-poi-types.csv`; needs the **Mapping** module switched on. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The point of interest type's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The type's name. Up to 100 characters. Must be unique in the file. Example: `Hospital`. Headers recognized: name, type, category, layer. | +| `Colour [color]` | `color` | Colour | | The map marker's colour, as a hex code. Example: `#1baf7a`. Headers recognized: color, colour. | +| `Destination [is_destination]` | `is_destination` | Yes/No | | Yes when people and units can pick these places as a destination with a status. Example: `no`. Headers recognized: destination, is destination. | + +*Contract `poi-types` version 2026.11.1, generated from the import catalog.* + + + + +## Points of interest sheet + + + +Places on your map, each with its type and location. + +Starter workbook sheet **Points of interest**; CSV template `resgrid-pois.csv`; imported after [Point of interest types](#sheet-poi-types); needs the **Mapping** module switched on. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The point of interest's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Type [type]` | `type` | Reference | Yes | The place's type, by name. Refers to [Point of interest types](#sheet-poi-types). Example: `Hospital`. Headers recognized: type, category, layer, poi type. | +| `Name [name]` | `name` | Text | | The place's name. Up to 200 characters. Example: `Memorial Hospital`. Headers recognized: name, title, place. | +| `Latitude [latitude]` | `latitude` | Latitude | Yes | Where the place is, as decimal degrees north (negative for south). Example: `39.7990`. Headers recognized: latitude, lat, y. | +| `Longitude [longitude]` | `longitude` | Longitude | Yes | Where the place is, as decimal degrees east (negative for west). Example: `-89.6440`. Headers recognized: longitude, long, lng, lon, x. | +| `Address [address]` | `address` | Text | | The place's address, shown with it on the map. Up to 500 characters. Example: `701 N First St`. Headers recognized: address, street, location. | +| `Note [note]` | `note` | Text | | Anything responders should know about the place. Up to 2000 characters. Example: `Helipad on roof`. Headers recognized: note, notes, description, comments. | + +*Contract `pois` version 2026.11.1, generated from the import catalog.* + + + + +## How places are matched + +- **Point of interest types** are matched by Source ID (same workspace, or the import it [continues](uploading-and-checks#continue)), otherwise by **name**, ignoring case, accents, spaces and punctuation. New types get the standard map pin marker. +- **Points of interest** are matched by Source ID (same workspace, or the import it [continues](uploading-and-checks#continue)), otherwise by **name and exact position** together: the same name at the same latitude and longitude is the same place. A place that moved, or two places with one name, are separate records. + +More rules: + +- **Type** is required and refers to a point of interest type by name — a row in your types file or an existing type. Unknown types can be **created new** on the [value matching](matching-columns-and-values#match-values) page. +- **Latitude** and **Longitude** are required, in decimal degrees. Addresses are never looked up during an import; the **Address** column is shown with the place as text. +- From GeoJSON, each feature's properties become columns (nested properties as `parent.child`), and a `Point` geometry becomes `latitude` and `longitude`. +- Rolling back deletes imported places and types; a type that places still use (including ones added since) is kept for you to check. diff --git a/docs/web-app/import-and-migration/review-and-import.md b/docs/web-app/import-and-migration/review-and-import.md new file mode 100644 index 0000000..4be7c7f --- /dev/null +++ b/docs/web-app/import-and-migration/review-and-import.md @@ -0,0 +1,160 @@ +--- +sidebar_position: 7 +title: Review & Import +--- + +# Review and Import + +**Department menu → Import & Migration → (workspace) → Review & import** + +**Review & import** is the only place where data is written to your department. It shows exactly what will happen — how many records will be added, linked, updated or skipped, whether your plan has room, and what Resgrid will do afterwards because the data exists — and asks you to confirm it in plain sentences before you approve with your second factor. The import then runs in the background, in small steps you can pause. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +The **Review & import** tab of a workspace, or **Review and import** on a ready data set's card or the **Next step** card. + +| Area | Contents | +|---|---| +| **Stat tiles** | Totals across the data sets: **Add**, **Update or link**, **Unchanged**, **Invite to join**, **Blocked** (opens the Issues tab). | +| **What will happen** | A bar chart per data set and a table: data set, status, *Add*, *Update or link*, *Unchanged*, *Skip*, *Blocked*. | +| **Approve** | The [capacity statement](#capacity), anything that stops approval, the [settings that change first](#configuration), the data sets in this import, the statements to confirm, the [write mode](#write-modes) and **Approve and import**. | + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. Approving needs **two-factor authentication** — you confirm with your second factor (within the last 10 minutes) when you approve. See [Overview → Turning it on](overview#enable). + + +## Reading the preview + +| Decision | Meaning | +|---|---| +| **Add** | A new record will be created. | +| **Update or link** | The row matches a record that already exists. With *Add only* it is **linked** — not changed, but other rows can refer to it. With *Review updates*, rows whose values differ are **updated**. People who were removed from your department before are counted here too: they [come back](people#people-matching) when you confirm it. | +| **Unchanged** | Already imported from this workspace (same Source ID), or nothing to change. | +| **Skip** | Left out: rows you excluded, and people whose email already has a Resgrid account elsewhere (shown separately as **Invite to join** — they are invited to join at activation instead of being added). | +| **Blocked** | Rows with open blocking issues. They are not imported; fix or exclude them on the Issues tab. | + +How rows are matched to existing records is described on each field reference page — for example [People](people#people-matching) are matched by email. + + +## Settings changed first + +The settings you accepted on the [Configure](configure) tab go with every import you approve. The **Approve** panel shows *N settings will be changed first, before any data.* with the count per group, **Review the settings** opens the Configure tab, and one more statement is ticked: *I have reviewed the settings that will change. Each one can be rolled back while nobody has changed it since.* An import can be settings alone, without a data set. + + +## Plan capacity + +People and units must fit your plan. The preview reads your plan fresh and says, for example, *This adds 412 people (room for 438) and 27 units (room for 40).* Other data sets — stations, roles, types, statuses, places — use no seats. On plans with one combined limit for people and units, the room is shared. + +| Message | Meaning | +|---|---| +| *Your plan doesn't have room for everyone in this import.* | Approval is blocked. Upgrade on [Subscription & Billing](../subscription-billing), exclude rows, or import fewer people or units. | +| *We couldn't check your plan's limits right now. People and units can't be added until the check works.* | Approval is blocked while the plan cannot be read. Try again in a few minutes. | + +Capacity is checked again when the import starts, and each new person or unit is counted as it is written, so nothing beyond your plan is ever written. + + +## What stops approval + +- *Some accepted settings cannot be changed as they stand: fix them on the Configure tab first.* See [Configure → Statuses](configure#statuses). +- *An import is already waiting or running for this workspace.* Only one import or rollback runs per department at a time. +- *No data set is ready yet: fix the open issues first.* +- The capacity messages above. +- *Another data set must be imported first, or in the same import (for example stations before people).* A data set that refers to another data set of the workspace needs it imported earlier or ticked in the same import. + + +## Please confirm + +Before **Approve and import** works you tick every statement: + +| Statement | When it appears | +|---|---| +| *N people will be added. None of them will be notified or able to sign in until you invite them.* | Always. | +| *N certifications have already expired. Resgrid will mark them expired and will not email the holders.* | People's certifications with an expiry date in the past. | +| *N certifications expire soon. Reminders wait until the holder is invited.* | Certifications expiring within your department's certification reminder period (60 days if none is set). | +| *N new status sets will become the buttons your people and units see.* | New personnel or staffing status sets. | + + +### Consequences + +The last three statements are **consequences**: things Resgrid would do later, on its own schedule, because the imported data exists. Writing quietly is not enough to stop them, so each one is decided up front and shown as an issue (*A consequence needs your decision*) until you tick it. Expired certifications are imported already marked *Expired*, so the nightly expiry check has nothing to announce; reminders for certifications expiring soon cannot reach anyone while the holder is dormant, and start once the person accepts their invitation. + + +## How existing records are treated + +**How to treat records that already exist**: + +| Mode | What it does | +|---|---| +| **Add only** | Never changes what is already in Resgrid. New rows are added; rows that match an existing record are linked to it. | +| **Review updates** | Also updates matched records — only the fields your file fills, and only where the value differs. It skips any record someone edited in Resgrid after the preview (*records changed after the preview* — review those rows again). For **people** only department data changes: station or group, group administrator, roles, ID number, notes and home address. A person's own profile — name, phone numbers, time zone, language — is never changed by an import. Links to other records (a unit's type and station, a group's parent) and a station's address are set when a record is created and are not changed by an update. | +| **Replace** | Works like *Review updates*, and also **retires** the records of this kind that your file doesn't contain, so what you import becomes the whole set — for example your call priorities or certification types. Only offered while [Resgrid support](getting-help-from-support#import-support-access) has **Prepare** access or more to the workspace, and always needs a second administrator. See [Replace](#replace). | + +The default comes from the workspace: *Update a live department (reviewed)* uses **Review updates**; the other modes use the department default in [settings](rollback-and-retention#import-settings) (*Add only* unless changed). The preview — every row's decision and the counts above — is worked out for the workspace's choice. To change it, choose the other mode under **How to treat records that already exist** on the Approve panel and select **Recalculate the preview**: *Saved. We're recalculating the preview; it appears here when it's ready.* Approvals already given are withdrawn, and approval waits until the new preview is ready (*The preview is being recalculated. Refresh this page in a moment.*). Approving always uses the mode the preview was calculated for. + + +### Replace + +Replace is for making your file the complete list of one kind of record. It is deliberately hard to reach: + +- It is offered only while Resgrid support holds **Prepare** access or more to the workspace (support helps you check the file), or — in a [managed migration](getting-help-from-support#managed) — when your Operate grant includes Replace. +- It covers **one data set** of one kind of record at a time, and works for **call priorities** and **certification types**: records Resgrid can retire and bring back exactly. For any other kind the data set shows *Replace isn't available for this kind of data*. +- The preview lists how many existing records will be retired, as a statement you tick: *N existing records that your file doesn't contain will be retired. Rolling the import back restores them.* The list is fixed when the preview is calculated; a record added afterwards is never retired, and if the list changes you are asked again. +- A record still in use — a certification type people hold — cannot be retired: the data set shows *Some existing records can't be retired*. Add it to your file or use *Review updates*. +- A second administrator always approves a Replace, even when your settings don't require one. + +Retired records are marked deleted, as the Types and Certifications screens do, so calls and history that mention them stay intact. [Rolling the import back](rollback-and-retention#rollback-does) brings them back. + + +## Approving + +1. Tick the **data sets in this import** (all ready data sets are ticked). +2. Tick every statement. +3. Check the write mode shown on the Approve panel; to change it, recalculate the preview first ([above](#write-modes)). +4. Select **Approve and import** and confirm with your second factor. + +The approval freezes exactly what you saw — the rows, your matches and value choices, your fixes and the catalog version. If anything in those data sets changes afterwards, the approval is withdrawn and the data set has to be approved again. The approved data sets show **Approved** and you are taken to the **History** tab. + + +### Second approver + +When **Require a second administrator to approve every import** is on ([settings](rollback-and-retention#import-settings)), the import waits as **Waiting for second approval** and the Review & import tab shows *This import waits for a second administrator to approve it.* A **different** department administrator opens the tab, reviews the same preview and selects **Approve as second administrator** (with their own second factor). *Two people, not one person twice*: the first approver cannot approve again. If the data changed after the first approval, the second approval is refused — approve it again from the start. + +When Resgrid staff run an import or a rollback for you under a [managed migration](getting-help-from-support#managed), this tab shows its state instead: *Resgrid staff requested this on your department's behalf. It waits for a second Resgrid staff member to approve it.* (no button), then — if you asked to approve before anything is imported — *Two Resgrid staff members approved this. It starts when an administrator of your department approves it.* with **Approve and start** (with your second factor). Your approval is not possible until the second Resgrid staff member has approved. + + +## What runs in the background + +The import runs on Resgrid's background workers, so you can close the page. It goes through these phases: + +1. **Prepare** — checks that the data is still exactly what was approved and that the approver is still an administrator, takes the department's import lock, reads plan capacity once more and creates any [custom fields](matching-columns-and-values#custom-fields) the import needs. +2. **Write** — data sets in dependency order (statuses, certification types, stations and groups, roles, people, people's certifications, unit types, units, call types, call priorities, point of interest types, points of interest), 200 rows at a time. Each group of rows is saved together and every change is journaled for rollback. A row that cannot be written is set aside with an issue and the rest continue. +3. **Finish** — work that needs a whole data set first: parent groups, a status button's next statuses, and roles that waited for certifications to arrive. +4. **Refresh** — caches, the apps and search are refreshed once, and one audit entry per kind of data is recorded. +5. **Verify** — every written record is checked against what was approved; see [Verify and activate](verify-and-activate#verify-results). + +While it runs, nobody is notified: no dispatch, message, welcome email or workflow is triggered, and no address is looked up with an outside service. Your department keeps working normally — the import lock only keeps a second import, an Advanced Data Protection migration and department deletion out until it finishes. + + +## Watching, pausing and cancelling + +The **History** tab lists every run — file checks, imports, verifications and rollbacks — with its status, when it was requested and its progress per kind of data: *N added, N updated or linked, N unchanged, N skipped, N failed*, plus *N checks matched* or *N checks differ* when verified. It refreshes while something runs. + +| Status | Meaning | Actions | +|---|---|---| +| **Waiting** | Queued. | **Pause**, **Cancel** | +| **Running** | Writing. | **Pause**, **Cancel** | +| **Checking** | Verifying what was written. | — | +| **Paused** | Stopped at a safe point, by you or because something needs a decision (the reason is shown). | **Resume** | +| **Retrying** | A temporary problem — Resgrid tries again automatically, waiting longer each time (1, 4, 16 minutes … up to 6 hours, at most 8 attempts). | **Resume** to try now | +| **Waiting for second approval** | See [Second approver](#two-approvers). | — | +| **Done** | Finished. The import can be [rolled back](rollback-and-retention#rollback) within its window. | **Roll back** | +| **Cancelled** | Stopped by you. Records already written stay; if any were written, the import can be [rolled back](rollback-and-retention#rollback) like a finished one, within 30 days of the cancellation (until 30 days after sign-off for a new department). | **Roll back** (when it wrote records) | + +**Pause** and **Cancel** take effect at the next safe point between groups of rows: *Stop this run at the next safe point? What was already imported stays and can be rolled back.* Use **Pause** if you want to continue later. A run that stops making progress for 15 minutes is restarted automatically from its last checkpoint. You get a [notice](overview#notices) when an import finishes, fails or needs you. diff --git a/docs/web-app/import-and-migration/roles-and-certifications.md b/docs/web-app/import-and-migration/roles-and-certifications.md new file mode 100644 index 0000000..85aea26 --- /dev/null +++ b/docs/web-app/import-and-migration/roles-and-certifications.md @@ -0,0 +1,138 @@ +--- +sidebar_position: 13 +title: Roles & Certifications Field Reference +sidebar_label: "Reference: Roles & certifications" +--- + +# Roles and Certifications — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +Three data sets cover what people do and what they are qualified for: **Roles** (Engineer, Paramedic, Officer …), **Certification types** (the certifications that exist — Firefighter I, EMT, CPR …) and **People's certifications** (which person holds which certification, with numbers and dates). Roles and certification types come before people; people's certifications come after them. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **Roles**, **Certification types** and **People's certifications** sheets of the [starter workbook](starter-workbook) (or `resgrid-roles.csv`, `resgrid-certification-types.csv`, `resgrid-personnel-certifications.csv`), or upload your own lists and match them on the [matching](matching-columns-and-values) page. **Download current data** exports your existing roles and certification types. + +After the import, roles are on the [Personnel](../personnel) screen and certifications in [Certifications](../business-ops/certifications) and [Types](../types-configuration#certification-types). + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + + +## Roles sheet + + + +The roles people fill (Engineer, Paramedic, Officer…). + +Starter workbook sheet **Roles**; CSV template `resgrid-roles.csv`. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The role's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The role's name. Up to 250 characters. Must be unique in the file. Example: `Engineer`. Headers recognized: name, role, role name, position, rank, title. | +| `Description [description]` | `description` | Text | | What the role does. Up to 3000 characters. Example: `Drives and pumps the engine`. Headers recognized: description, notes. | + +*Contract `roles` version 2026.11.1, generated from the import catalog.* + + + + +## Certification types sheet + + + +The kinds of certification your people hold (Firefighter I, EMT, CPR…). + +Starter workbook sheet **Certification types**; CSV template `resgrid-certification-types.csv`. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The certification type's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The certification's name as your people know it. Up to 100 characters. Must be unique in the file. Example: `Firefighter I`. Headers recognized: name, certification, certification name, type, qualification. | +| `Code [code]` | `code` | Text | | A short code for the certification. Left empty, Resgrid makes one from the name. Up to 50 characters. Must be unique in the file. Example: `FF1`. Headers recognized: code, abbreviation, short name. | +| `Category [category]` | `category` | Choice from a list | | The group the certification belongs to. Choices: `fire` Fire (also: firefighting); `ems` EMS (also: medical services, emergency medical); `sar` Search and rescue (also: search and rescue, rescue); `wildland` Wildland (also: wildfire); `emergency-management` Emergency management (also: em); `industrial` Industrial; `security` Security; `medical` Medical (also: health); `driver` Driver (also: driving, evoc); `vehicle` Vehicle; `other` Other. Example: `fire`. Headers recognized: category, discipline. | +| `Held by [applies_to]` | `applies_to` | Choice from a list | | Whether people or units hold this certification. Choices: `person` People (also: people, personnel, member); `unit` Units (also: apparatus, vehicle). Example: `person`. Headers recognized: applies to, scope, held by. | +| `Issuing authority [issuing_authority]` | `issuing_authority` | Text | | Who issues the certification. Up to 200 characters. Example: `State Fire Academy`. Headers recognized: issuing authority, issuer, issued by, authority. | +| `Valid for (months) [validity_months]` | `validity_months` | Whole number | | How many months a new certification stays valid. Leave empty when it never expires. From 1 to 600. Example: `24`. Headers recognized: validity, valid months, renewal period, months valid. | +| `Never expires [never_expires]` | `never_expires` | Yes/No | | Yes when this certification does not expire. Example: `no`. Headers recognized: never expires, no expiry, permanent. | +| `Needs verification [requires_verification]` | `requires_verification` | Yes/No | | Yes when an administrator must verify a new certification before it counts. Example: `no`. Headers recognized: requires verification, verify. | +| `Description [description]` | `description` | Text | | Anything people should know about the certification. Up to 2000 characters. Example: `Basic structural firefighting`. Headers recognized: description, notes. | + +*Contract `certification-types` version 2026.11.1, generated from the import catalog.* + + + + +## People's certifications sheet + + + +The certifications each person holds, with numbers and dates. Certifications that are already expired are imported as expired without emailing anyone. + +Starter workbook sheet **People's certifications**; CSV template `resgrid-personnel-certifications.csv`; imported after [People](people#sheet-personnel), [Certification types](#sheet-certification-types). + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Person [person]` | `person` | Reference | Yes | Who holds the certification, by the person's source ID or email. Refers to [People](people#sheet-personnel). Example: `alex.rivera@example.org`. Headers recognized: person, member, email, employee, name. | +| `Certification [certification_type]` | `certification_type` | Reference | Yes | Which certification, by its name, code or source ID. Refers to [Certification types](#sheet-certification-types). Example: `Firefighter I`. Headers recognized: certification, certification type, qualification, type, course. | +| `Certificate number [number]` | `number` | Text | | The number on the certificate. Up to 200 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `FF-2019-0042`. Headers recognized: number, certificate number, license number, cert number. | +| `Area [area]` | `area` | Text | | Where the certification is valid (a state or region), when that matters. Up to 200 characters. Department-only. Example: `Illinois`. Headers recognized: area, state, jurisdiction. | +| `Issued by [issued_by]` | `issued_by` | Text | | Who issued the certificate. Up to 200 characters. Department-only. Example: `State Fire Academy`. Headers recognized: issued by, issuer, authority. | +| `Issued on [issued_on]` | `issued_on` | Date | | The date the certificate was issued. Example: `2019-05-14`. Headers recognized: issued, issued on, issue date, received, date issued, certified on. | +| `Expires on [expires_on]` | `expires_on` | Date | | The date the certificate expires. Leave empty when it does not expire. Example: `2027-05-14`. Headers recognized: expires, expires on, expiration, expiration date, expiry, valid until. | + +*Contract `personnel-certifications` version 2026.11.1, generated from the import catalog.* + + + + +## Role requirements sheet + + + +Which certifications each role requires. A role's other requirements stay as they are. If your department enforces requirements, people lacking one can lose the role at the next nightly check. + +Starter workbook sheet **Role requirements**; CSV template `resgrid-role-requirements.csv`; imported after [Roles](#sheet-roles), [Certification types](#sheet-certification-types). + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Role [role]` | `role` | Reference | Yes | Which role, by its name or source ID. Refers to [Roles](#sheet-roles). Example: `Engineer`. Headers recognized: role, position, role name. | +| `Required certification [certification_type]` | `certification_type` | Reference | Yes | Which certification the role requires, by its name, code or source ID. It must be a type people hold. Refers to [Certification types](#sheet-certification-types). Example: `Driver/Operator`. Headers recognized: certification, certification type, required certification, qualification. | +| `Mandatory [mandatory]` | `mandatory` | Yes/No | | Yes when the role cannot be held without it (the default); no for a recommended certification. Example: `yes`. Headers recognized: mandatory, required, is required. | +| `Any-of group [any_of_group]` | `any_of_group` | Whole number | | Requirements of one role with the same number are alternatives: holding any one of them is enough. From 1 to 99. Example: `1`. Headers recognized: any of group, group, one of group, alternative group. | +| `Trainee allowed [allow_trainee]` | `allow_trainee` | Yes/No | | Yes when someone still training for the certification may hold the role. Example: `no`. Headers recognized: allow trainee, trainee allowed, trainee. | +| `Grace days [grace_days]` | `grace_days` | Whole number | | Days a person keeps the role after the certification lapses, instead of the department's default. From 0 to 3650. Example: `30`. Headers recognized: grace days, grace period, grace. | + +*Contract `role-requirements` version 2026.11.1, generated from the import catalog.* + + + +One row is one role and one certification type. A role's other requirements stay as they are; a row for a role and type that already have a requirement is matched to it (and, with *Review updates*, its options are changed). Rows with the same **Any-of group** number for a role are alternatives. The type must be one people hold (*N role requirements use a type meant for units*). If your department enforces role requirements (certification settings, mode *Enforce*), the preview asks you to confirm that people lacking a newly required certification can lose the role at the next nightly check. Rolling the import back removes the requirements it added and puts back the options it changed. + + +## How rows are matched + +| Data set | Matched to existing records by | +|---|---| +| **Roles** | Source ID (same workspace, or the import it [continues](uploading-and-checks#continue)), otherwise **name** — ignoring case, accents, spaces and punctuation. Two existing roles with the same name block the row. | +| **Certification types** | Source ID (same workspace, or the import it [continues](uploading-and-checks#continue)), otherwise **name**. | +| **People's certifications** | **Never** matched to certifications already in Resgrid — the same person can hold two records of one certification. Within a workspace, a row already imported (same person, certification and certificate number) is recognized and not added again; in a different workspace it would be added again, so import each person's certifications once. | + +More rules: + +- **Person** refers to a person by their Source ID or email — a row in your People file or an existing member. It must point at a person; *Keep as text* is not possible here. +- **Certification** refers to a certification type by its name, code or Source ID. The type must be one that **people** hold — a type for units fails the row (*certifications use a type meant for units*). +- **Expires on** must not be before **Issued on**. +- **Certifications that have already expired** are imported marked *Expired*, and nobody is emailed. **Certifications expiring soon** get no reminders while the holder is dormant. Both are [statements you confirm](review-and-import#l8-consequences) before approving. +- A person's **roles** that require certifications are retried at the end of the import, after the certifications are written — approve People and People's certifications in the same import so [certification requirements](../business-ops/certifications) do not leave those roles out. +- **Certificate number** is protected by [Advanced Data Protection](../data-protection) when your department uses it. **Area** and **Issued by** are not: they describe the qualification, and qualification-based dispatch reads them. +- On the [value matching](matching-columns-and-values#match-values) page, unknown roles and certification types can be **created new** with just their name. diff --git a/docs/web-app/import-and-migration/rollback-and-retention.md b/docs/web-app/import-and-migration/rollback-and-retention.md new file mode 100644 index 0000000..8e73ba1 --- /dev/null +++ b/docs/web-app/import-and-migration/rollback-and-retention.md @@ -0,0 +1,117 @@ +--- +sidebar_position: 9 +title: Rollback & Retention +--- + +# Rollback, Retention and Settings + +**Department menu → Import & Migration → (workspace) → History** + +Every import is journaled change by change, so for a while afterwards you can **roll it back**: what it created is removed, what it changed gets its earlier values back, and anything people have used since stays for you to check by hand. Uploaded files and the checked copy of your data are kept only as long as they are useful, then deleted on a schedule you can adjust in **Import & Migration settings**. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +- **Roll back** is on the **History** tab, next to each finished import that can still be rolled back — and next to a cancelled import that had already written records. +- **Settings** is the button at the top of the Import & Migration landing page (`/User/DepartmentImport/Settings`). +- File states (*Received*, *Deleted after retention*) are on the **Files & data sets** tab. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. Rolling back needs your second factor. See [Overview → Turning it on](overview#enable). + + +## Rolling back an import + +1. On the **History** tab, select **Roll back** next to the import. +2. The **Roll back this import** dialog explains what happens — *Records this import created are removed, changed records get their earlier values back, and anything used since stays for you to check by hand* — shows *Rollback is possible until …* and lists, per kind of data, how many records there are **to remove**, **to restore**, **links (nothing to undo)** and **settings to restore**. +3. Select **Roll back** and confirm with your second factor. + +A **cancelled** import keeps what it wrote before it stopped, and that part can be rolled back exactly like a finished import. + +The rollback runs in the background like an import, under the same department lock, and appears on the History tab as its own run. When it finishes, the data sets it covered go back to **Ready**, so you can fix them and import again. + +Instead of the button you may see why a rollback is not possible: *The rollback period for this import has ended*, *This import has already been rolled back*, *An import or rollback is already waiting or running for your department* or *Only a finished import can be rolled back* (shown for an import cancelled before it wrote anything — there is nothing to undo). + + +## The rollback window + +| Workspace mode | Rollback is possible | +|---|---| +| **Set up a new department** | At any time until you [sign off](verify-and-activate#checklist), and for **30 days** after that. | +| **Add to a live department**, **Update a live department (reviewed)**, **Continue an earlier import** | For **30 days** after the import finished — or, for a cancelled import, after it was cancelled. | + +Each import can be rolled back once, and only one import or rollback runs for a department at a time. + + +## What rollback removes, restores and keeps + +Changes are undone in the reverse order they were written — people before the stations they belong to — and each change on its own, so one record that cannot be undone never stops the rest. + +| What the import did | What rollback does | +|---|---| +| **Created** a station or group, role, certification type, unit type, call type, point of interest type, point of interest or person's certification | Deletes it through Resgrid's normal delete. | +| **Created** a unit | Marks it deleted, so calls, statuses and logs that mention it stay intact. | +| **Created** a call priority, status set or status button | Marks it deleted, as the Types and Custom Statuses screens do. | +| **Created** a person | If the import created the account, the person never accepted an invitation and has no other department, the account is closed with the membership. If the account belongs to other departments too, only the membership in yours is removed. | +| **Updated** a record (*Review updates*) | Puts back the values the import replaced, field by field. | +| **Updated** an existing member (*Review updates*) | Takes back exactly what the import added: the station or group it gave someone who had none, the roles it added, and the ID number, notes and address it stored when none were stored. Anything changed since (the person was moved to another station, their details were edited) is left as it is and listed for a check by hand. | +| **Brought back** a member removed earlier | Removes them again, as they were before, together with what the import added — unless they accepted their invitation since. | +| **Retired** a record (*Replace*) | Brings it back, unless a record with the same name has been created since. | +| **Made a different call priority the default** | Restores the previous default. | +| **Changed a setting** ([Configure](configure)) | Puts back the value it replaced, unless someone changed the setting since. A next number is never lowered, and a replaced logo is not restored (a logo added where there was none is removed). | +| **Linked** an existing record | Nothing to undo. | + + +### What is kept for a check by hand + +Rollback never deletes something people have started to use. These records stay in place and are counted on the rollback run (*N checks differ*): + +| Situation | Code | +|---|---| +| The record is in use: a person accepted their invitation; a station still has members, units or child groups; a role still has members; a certification, unit or point of interest type is still used; a status set still has buttons added since. | `IMP-ROLLBACK-HAS-ACTIVITY` | +| Someone changed the record after the import, so restoring the old values would overwrite their work. | `IMP-ROLLBACK-CHANGED-SINCE` | +| Something the import added to an existing member was changed afterwards — review the person's group, roles and details on the Personnel screen. | `IMP-ROLLBACK-MEMBER-UPDATE` | +| A next number the import raised: numbers only go up, so it stays. Nothing to do unless you want a different numbering. | `IMP-ROLLBACK-NUMBER-KEPT` | +| The import replaced the department logo; the previous one is not kept. Upload it again on the Profile screen. | `IMP-ROLLBACK-LOGO-REPLACED` | +| An account could not be closed — remove the person on the Personnel screen. | `IMP-ROLLBACK-ACCOUNT` | +| The record could not be undone, or cannot be undone automatically. | `IMP-ROLLBACK-FAILED`, `IMP-ROLLBACK-NO-WRITER`, `IMP-ROLLBACK-MANUAL` | + +Custom fields the import created for people or units stay; remove them on [User Defined Fields](../user-defined-fields) if you no longer need them. See the [rollback codes](fixing-issues#issues-rollback). + + +## Retention + +| Data | Kept | Then | +|---|---|---| +| **Uploaded files** (encrypted) | 7 days after the import that used them has been verified (72 hours when Advanced Data Protection is enforced); 30 days after an import fails or the workspace is cancelled; 30 days for a refused file. A deadline that is already earlier is never pushed later. Adjustable in settings. | Deleted from storage. The file list shows *Deleted after retention*. | +| **Unfinished uploads** | 24 hours. | Discarded. | +| **Checked data** — the checked rows, issues and value choices of a workspace | Until 30 days after [sign-off](verify-and-activate#checklist) (adjustable); for a cancelled workspace, as long as its files. | Deleted; the workspace becomes **Closed**. Imported records stay. | +| **Idle workspaces** | A reminder after 30 days without activity. | After 90 days without activity the workspace is closed as **Abandoned** and its files and checked data are deleted. | +| **Saved matches** | While your department exists. | — | +| **Support access** | Until the grant expires or you revoke it. | Expires automatically. | +| **Imported records** | They are your department's data. | Kept like any other record. | + +Deletion runs hourly. You can also **Cancel** an unfinished workspace on the landing page — *Uploaded files and checked data will be deleted after the retention period. Records already imported stay.* — which puts its files on the shorter failure schedule. A workspace that is importing, or one that is already live, cannot be cancelled. + + + +## Import & Migration settings + +**Import & Migration → Settings** — *How long imported files and checked data are kept, and how imports are approved.* The values apply to the whole department. + +| Field | Default | Notes | +|---|---|---| +| **Keep uploaded files after a successful import (days)** | 0 = 7 days (72 hours with Advanced Data Protection) | 0–180. | +| **Keep files that failed (days)** | 0 = 30 days | 0–180. Also used when a workspace is cancelled. | +| **Keep checked data after go-live (days)** | 0 = 30 days | 0–180. *Rollback needs this data* — keep it at least as long as you may want to roll back. | +| **Default for records that already exist** | *Add only* | *Add only* or *Review updates* — the default for new workspaces (see [write modes](review-and-import#write-modes)). | +| **Default support access (days)** | 0 = 7 days | 0–30. The length the **Grant access** dialog starts with on the Support tab. | +| **Require a second administrator to approve every import** | Off | *Two people, not one person twice: the second approver must be a different administrator.* Turning it on applies to every approval from then on; workspaces started while it was on keep requiring it. | + +Stored as department setting 83, `DepartmentImportConfig`. diff --git a/docs/web-app/import-and-migration/starter-workbook.md b/docs/web-app/import-and-migration/starter-workbook.md new file mode 100644 index 0000000..93adeee --- /dev/null +++ b/docs/web-app/import-and-migration/starter-workbook.md @@ -0,0 +1,115 @@ +--- +sidebar_position: 3 +title: Starter Workbook & Templates +--- + +# Starter Workbook, Templates and Current Data + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +The **Resgrid starter workbook** is an Excel file built for your department: one sheet per kind of data, an example row on each sheet, and drop-down lists of the accepted options and of the stations, roles and types you already have. Fill it in and upload it, and Resgrid knows exactly which column is which — no column matching needed. If you prefer CSV there is one template per kind of data, and **Download current data** gives you what your department already has in the same layout, ready to edit and upload again. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Open a workspace and choose the **Files & data sets** tab. The right-hand panel **Resgrid starter workbook** has: + +| Control | What you get | +|---|---| +| A tick box per kind of data (all ticked) + **Download workbook** | `resgrid-starter-workbook.xlsx` with a sheet for each ticked kind of data. | +| *Prefer CSV? Download one template per kind of data* | One `resgrid-.csv` per kind of data, for example `resgrid-personnel.csv`. | +| **Download current data** | `resgrid-current-data.xlsx` with your department's existing records (see [below](#current-data)). | + + +## Turning it on + +Available wherever Import & Migration is: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + + +## What is in the workbook + +| Part | Details | +|---|---| +| **Instructions** sheet | Five short rules: fill in one sheet per kind of data and delete the sheets you don't need; keep the column headers exactly as they are; the first row of each sheet is an example and is never imported; columns with a drop-down accept the listed values (other text is matched when you upload); save as `.xlsx` and upload — nothing is saved until you review and approve it. | +| **One sheet per kind of data** | In import order: Statuses, Certification types, Stations and groups, Roles, Role requirements, People, Emergency contacts, People's certifications, Unit types, Units, Unit certifications, Call types, Call priorities, Point of interest types, Points of interest. The header row is frozen. | +| **Column headers** | `Label [field_key]` — for example `First name [first_name]` or `Station or group [group]`. The code in brackets tells Resgrid which field the column fills, so the headers must stay as they are. Each field is described on its [field reference](#all-fields) page. | +| **Example row** | Row 2 of every sheet holds example values and an `x` in the last column, `resgrid:example`. Any row with `x` in that column is skipped, so you can leave the example in place. Add your own rows below it with that column empty. Completely blank rows are skipped too. | +| **Drop-down lists** | Choice columns (for example *Type* on Stations and groups: `station` or `organizational`) list the accepted codes. Reference columns list the names your department **already has** — stations and groups, roles, certification types, unit types and point of interest types. The lists live on a hidden *Lists* sheet and cover the first 2,000 rows. | +| **Date columns** | Checked by Excel as dates. | + +The drop-downs are guides, not locks: Excel warns but lets you type something else. That is on purpose — a station you add on the Stations and groups sheet is not in Resgrid yet, so it is not in the list, but People can still name it. Anything not in a list is matched when you upload. + + +## Filling it in + +1. Delete the sheets you don't need (or leave them with only the example row — an empty sheet is simply not imported). +2. Fill in rows below the example. Keep one record per row. +3. Give records a **Source ID** — the ID from the system you are leaving, or one you invent (`ST-1`, `ST-2` …). Other sheets can then refer to a record by its Source ID or by its name, and uploading a corrected copy later updates rows instead of adding them twice. +4. Use the formats Resgrid reads without questions: + + | Type | Write it as | + |---|---| + | Dates | `2026-03-04` (year-month-day). `03/04/2026` can be read two ways: you are asked once per column whether the day or the month comes first. | + | Yes / No | `yes` / `no`, `true` / `false`, `1` / `0`, or `x` and blank. | + | Phone numbers | With the country code: `+1 555 123 4567`. | + | Lists | Several values separated by semicolons: `Engineer; EMT`. | + | Colours | Hex codes: `#2a78d6`. | + | Coordinates | Decimal degrees: `39.7817`, `-89.6501`. | + +5. Save as **`.xlsx`** (not `.xlsm` or `.xls`) and upload it on **Files & data sets**. + +When the workbook arrives, each sheet becomes a data set, its destination is confirmed automatically and every column is already matched. You still see any [issues](fixing-issues) the checks find — a missing email, a station name that matches nothing, a value that is not in a list — and you still [review and approve](review-and-import) before anything is saved. + + +## CSV templates + +Each CSV template has the same headers as the matching workbook sheet, the `resgrid:example` column and one example row. It is saved as UTF-8 with a byte-order mark so Excel shows accented names correctly; if you edit it in Excel, save it again as *CSV UTF-8*. Upload one CSV file per kind of data. + +| Template | Data set | +|---|---| +| `resgrid-custom-statuses.csv` | Statuses | +| `resgrid-certification-types.csv` | Certification types | +| `resgrid-groups.csv` | Stations and groups | +| `resgrid-roles.csv` | Roles | +| `resgrid-personnel.csv` | People | +| `resgrid-personnel-certifications.csv` | People's certifications | +| `resgrid-unit-types.csv` | Unit types | +| `resgrid-units.csv` | Units | +| `resgrid-call-types.csv` | Call types | +| `resgrid-call-priorities.csv` | Call priorities | +| `resgrid-poi-types.csv` | Point of interest types | +| `resgrid-pois.csv` | Points of interest | + + +## Download current data + +**Download current data** exports your department's existing records in the template layout, one sheet per kind of data, so you can correct or complete them in a spreadsheet and upload them again. It covers **stations and groups, roles, certification types, unit types, units, call types, call priorities and point of interest types**. People are never exported (personal data does not leave Resgrid this way), and statuses, people's certifications and points of interest are not exported in this release. + +Each exported row has a Source ID of the form `resgrid:` and the example row at the top. To use it for corrections: + +1. Start a workspace as **Update a live department (reviewed)** (or choose **Review updates** when you approve). +2. Edit the values you want to change; delete the rows you don't want to touch. +3. Upload the file. Rows are matched to your existing records by **name**, and the preview shows which records will be updated. + +:::caution Don't rename records this way +Because rows are matched by name, a row whose name you changed no longer matches its record and would be added as a **new** record. Rename stations, units and types on their own screens in Resgrid instead. +::: + +Values in every download are written as plain text — never as formulas — so a cell starting with `=` cannot run anything when the file is opened. + + +## Field reference + +Every column of every sheet, with its type, whether it is required, its length limit, the accepted choices and an example: + +- [People](people) — people and emergency contacts +- [Stations and groups](stations-and-groups) +- [Roles and certifications](roles-and-certifications) — roles, certification types, role requirements and people's certifications +- [Units](units) — unit types, units and unit certifications +- [Statuses](statuses) +- [Call types and priorities](call-types-and-priorities) +- [Points of interest](points-of-interest) — point of interest types and points of interest diff --git a/docs/web-app/import-and-migration/stations-and-groups.md b/docs/web-app/import-and-migration/stations-and-groups.md new file mode 100644 index 0000000..7ea4a53 --- /dev/null +++ b/docs/web-app/import-and-migration/stations-and-groups.md @@ -0,0 +1,67 @@ +--- +sidebar_position: 12 +title: Stations & Groups Field Reference +sidebar_label: "Reference: Stations & groups" +--- + +# Stations and Groups — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +The **Stations and groups** data set creates your [stations and organizational groups](../groups-stations) with their addresses, locations and where each one sits in your organization. People and units refer to these rows, so import them first — or in the same import. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **Stations and groups** sheet of the [starter workbook](starter-workbook) or `resgrid-groups.csv`, or upload your own list and match it to *Stations and groups* on the [matching](matching-columns-and-values) page. **Download current data** exports your existing stations and groups in this layout. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. Stations and groups use no plan seats. See [Overview → Turning it on](overview#enable). + + +## Stations and groups sheet + + + +Your stations and the groups people belong to, with their addresses and where they sit in your organization. + +Starter workbook sheet **Stations and groups**; CSV template `resgrid-groups.csv`. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The station or group's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The station's or group's name. Up to 50 characters. Must be unique in the file. Example: `Station 1`. Headers recognized: name, station, group, station name, group name. | +| `Type [type]` | `type` | Choice from a list | | Station for a place units respond from; organizational for any other group of people. Choices: `station` Station (also: firehouse, house, base, post); `organizational` Organizational (also: organisational, group, team, company, division). Example: `station`. Headers recognized: type, group type, kind. | +| `Belongs to [parent]` | `parent` | Reference | | The station or group this one sits under, by its source ID or its name. Refers to [Stations and groups](#sheet-groups). Example: `Battalion 1`. Headers recognized: parent, parent group, belongs to, battalion, district. | +| `Street address [street]` | `street` | Text | | Street and number of the station. Up to 500 characters. Example: `120 Main St`. Headers recognized: address, street, address 1, address1. | +| `City [city]` | `city` | Text | | City of the station. Up to 150 characters. Example: `Springfield`. Headers recognized: city, town. | +| `State or region [state]` | `state` | Text | | State, province or region of the station. Up to 100 characters. Example: `IL`. Headers recognized: state, province, region. | +| `Postal code [postal_code]` | `postal_code` | Text | | Postal or ZIP code of the station. Up to 32 characters. Example: `62701`. Headers recognized: zip, zip code, postal code, postcode. | +| `Country [country]` | `country` | Text | | Country of the station. Up to 100 characters. Example: `United States`. Headers recognized: country. | +| `Latitude [latitude]` | `latitude` | Latitude | | Where the station is, as decimal degrees north (negative for south). Example: `39.7817`. Headers recognized: latitude, lat, y. | +| `Longitude [longitude]` | `longitude` | Longitude | | Where the station is, as decimal degrees east (negative for west). Example: `-89.6501`. Headers recognized: longitude, long, lng, lon, x. | + +*Contract `groups` version 2026.11.1, generated from the import catalog.* + + + + +## How stations and groups are matched + +- A row is matched by its **Source ID** when the same workspace — or the import it [continues](uploading-and-checks#continue) — imported it before, otherwise by its **name**, ignoring case, accents, spaces and punctuation (*Station 1*, *station-1* and *STATION 1* are the same). +- A matched station is **linked** with *Add only*. With *Review updates* its type, latitude and longitude are updated where they differ; the address and the parent group are set only when a station or group is created. +- If your department has **two** stations or groups with the same name, rows with that name are blocked (*rows match more than one existing record*) until you rename one in Resgrid. +- Names must be unique within the file. + +More rules: + +- **Belongs to** can name a row anywhere in the same file — even one further down — or an existing station or group. Parents are set after all rows are written. A loop (A belongs to B, B belongs to A) is blocked. +- **Type** left empty creates an *organizational* group. Use `station` for places units respond from. +- The address is saved with the station. Give both **Latitude** and **Longitude** or neither; addresses are not looked up during the import. +- People's **Station or group** and units' **Station** can refer to a row here by its Source ID or its name. On the [value matching](matching-columns-and-values#match-values) page you can also choose **Create new**, which creates a group with only its name. diff --git a/docs/web-app/import-and-migration/statuses.md b/docs/web-app/import-and-migration/statuses.md new file mode 100644 index 0000000..d66fa5f --- /dev/null +++ b/docs/web-app/import-and-migration/statuses.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 15 +title: Statuses Field Reference +sidebar_label: "Reference: Statuses" +--- + +# Statuses — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +The **Statuses** data set creates [custom status](../custom-statuses) buttons — what people press when they respond, what units report, and staffing levels. Each row is **one button**; rows with the same **Set name** and **Set type** make one status set. Statuses are imported first, so unit types can refer to their unit status set. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **Statuses** sheet of the [starter workbook](starter-workbook) or `resgrid-custom-statuses.csv`, or upload your own list and match it to *Statuses* on the [matching](matching-columns-and-values) page. After the import the sets are on the [Custom Statuses](../custom-statuses) screen. + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. See [Overview → Turning it on](overview#enable). + + +## Statuses sheet + + + +Status buttons for people, units and staffing levels. Each row is one button; rows with the same set name make one set. + +Starter workbook sheet **Statuses**; CSV template `resgrid-custom-statuses.csv`. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Set name [set_name]` | `set_name` | Text | Yes | The status set the button belongs to. Up to 200 characters. Example: `Engine statuses`. Headers recognized: set, set name, status set, group. | +| `Set type [set_type]` | `set_type` | Choice from a list | Yes | Who the statuses are for: people (responding), units or staffing levels. Choices: `personnel` Personnel (also: people, person, member, responder, response); `unit` Units (also: units, apparatus, vehicle); `staffing` Staffing (also: availability, staffing level). Example: `unit`. Headers recognized: set type, type, applies to, for. | +| `Button text [button_text]` | `button_text` | Text | Yes | The words on the status button. Up to 100 characters. Example: `En route`. Headers recognized: status, button, button text, name, label. | +| `Button colour [button_color]` | `button_color` | Colour | | The button's colour, as a hex code such as #2a78d6. Example: `#2a78d6`. Headers recognized: color, colour, button color, background. | +| `Text colour [text_color]` | `text_color` | Colour | | The colour of the button's words. Left empty, white. Example: `#ffffff`. Headers recognized: text color, text colour, font color. | +| `Location required [gps_required]` | `gps_required` | Yes/No | | Yes when choosing this status must send the device's location. Example: `no`. Headers recognized: gps, gps required, location required. | +| `Note [note]` | `note` | Choice from a list | | Whether a note can or must be added when choosing this status. Choices: `none` None (also: no); `optional` Optional (also: allowed); `required` Required (also: mandatory). Example: `none`. Headers recognized: note, note type, comment. | +| `Destination [destination]` | `destination` | Choice from a list | | What the person or unit may pick as a destination with this status. Choices: `none` None; `stations` Stations (also: station); `calls` Calls (also: call); `calls-and-stations` Calls and stations; `pois` Points of interest (also: poi, points of interest); `calls-and-pois` Calls and points of interest; `stations-and-pois` Stations and points of interest; `calls-stations-and-pois` Calls, stations and points of interest (also: all). Example: `none`. Headers recognized: destination, destination type, detail type. | +| `Order [order]` | `order` | Whole number | | The button's position in its set. From 0 to 1000. Example: `1`. Headers recognized: order, sort, position, sequence. | +| `Next statuses [next_statuses]` | `next_statuses` | List of text | | Buttons offered after this one, by their button text, separated by semicolons. Separate values with `;`. Example: `On scene; Available`. Headers recognized: next, next statuses, next status. | + +*Contract `custom-statuses` version 2026.11.1, generated from the import catalog.* + + + + +## How statuses are matched + +- A button is matched by **set name + set type + button text**, ignoring case, accents, spaces and punctuation. A matching button that already exists is linked (or, with *Review updates*, updated) instead of added again. +- A **set** with the same name and type that already exists is reused: new buttons are added to it. Otherwise the set is created with the first row that names it. + +More rules: + +- **A new personnel or staffing set becomes the set your people see.** The preview shows this as a statement — *N new status sets will become the buttons your people and units see* — which you confirm before approving. Unit sets apply only to the unit types that name them. +- **Next statuses** names other buttons **of the same set** by their button text (`On scene; Available`). They are filled in after every row has been written, so the order of rows does not matter. +- **Button colour** and **Text colour** are hex codes; an empty text colour is white. +- Rolling back marks the imported buttons and sets deleted, as the Custom Statuses screen does. diff --git a/docs/web-app/import-and-migration/units.md b/docs/web-app/import-and-migration/units.md new file mode 100644 index 0000000..b0c0e0d --- /dev/null +++ b/docs/web-app/import-and-migration/units.md @@ -0,0 +1,113 @@ +--- +sidebar_position: 14 +title: Units Field Reference +sidebar_label: "Reference: Units" +--- + +# Units — Field Reference + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +Two data sets cover your apparatus: **Unit types** (Engine, Ladder, Ambulance …, each optionally with its own unit status set) and **Units** (each unit with its type, home station, vehicle details and riding positions). Units refer to unit types and stations, so those come first — or in the same import. Each new unit uses a unit seat on your plan. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +Fill in the **Unit types** and **Units** sheets of the [starter workbook](starter-workbook) (or `resgrid-unit-types.csv` and `resgrid-units.csv`), or upload your apparatus list and match it on the [matching](matching-columns-and-values) page. **Download current data** exports your existing unit types and units. After the import they are on the [Units](../units) screen and under [Types](../types-configuration#unit-types). + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. Units need room on your plan — see [Plan capacity](review-and-import#capacity). See [Overview → Turning it on](overview#enable). + + +## Unit types sheet + + + +The kinds of apparatus you run (Engine, Ladder, Ambulance…). + +Starter workbook sheet **Unit types**; CSV template `resgrid-unit-types.csv`; imported after [Statuses](statuses#sheet-custom-statuses). + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The unit type's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The unit type's name. Units refer to their type by this name. Up to 100 characters. Must be unique in the file. Example: `Engine`. Headers recognized: name, type, unit type, apparatus type, vehicle type. | +| `Status set [status_set]` | `status_set` | Reference | | The unit status set this type uses, by name. Left empty, the default unit statuses are used. Refers to [Statuses](statuses#sheet-custom-statuses). Example: `Engine statuses`. Headers recognized: status set, statuses, status. | +| `Class [base_type]` | `base_type` | Choice from a list | | What kind of unit this type is. Resgrid uses the class, not the name, for reports, defaults and integrations. Choices: `engine` Engine (also: pumper, pump, fire engine); `aerial` Aerial (also: ladder, truck, tower, platform); `rescue` Rescue (also: rescue unit, heavy rescue, squad); `tanker` Tanker (also: tender, water tender); `ambulance` Ambulance (also: als, bls, medic, transport); `medical-response` Medical Response (also: first responder, qrv, fly car, response vehicle); `wildland` Wildland (also: brush, brush truck, type 6, type 3); `hazardous-materials` Hazardous Materials (also: hazmat, haz mat); `command` Command (also: chief, command vehicle, battalion); `support` Support (also: utility, logistics, rehab, air unit); `watercraft` Watercraft (also: boat, fire boat, vessel); `aircraft` Aircraft (also: helicopter, drone, uav); `patrol` Patrol (also: police, security vehicle, patrol car); `other` Other (also: misc, miscellaneous). Leave it empty to set it later on the Types screen; an import never guesses it from the name. Example: `engine`. Headers recognized: base type, unit class, apparatus class, class, classification. | + +*Contract `unit-types` version 2026.11.1, generated from the import catalog.* + + + + +## Units sheet + + + +Your apparatus and other units, with their type, station and vehicle details. + +Starter workbook sheet **Units**; CSV template `resgrid-units.csv`; imported after [Unit types](#sheet-unit-types), [Stations and groups](stations-and-groups#sheet-groups); extra columns can be kept as custom fields. + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The unit's id in the system you are leaving. Lets later files refer to this row and makes a re-import update it instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Name [name]` | `name` | Text | Yes | The unit's name or call sign. Up to 100 characters. Must be unique in the file. Example: `Engine 1`. Headers recognized: name, unit, unit name, call sign, callsign, apparatus, vehicle. | +| `Type [type]` | `type` | Reference | | The unit's type, by name. Refers to [Unit types](#sheet-unit-types). Example: `Engine`. Headers recognized: type, unit type, apparatus type, vehicle type. | +| `Station [station]` | `station` | Reference | | The station the unit runs from, by its source ID or name. Refers to [Stations and groups](stations-and-groups#sheet-groups). Example: `Station 1`. Headers recognized: station, group, home station, quarters. | +| `VIN [vin]` | `vin` | Text | | The vehicle identification number. Up to 50 characters. Example: `1FDUF5HT1JDA00000`. Headers recognized: vin, vehicle identification number, serial number. | +| `Plate number [plate_number]` | `plate_number` | Text | | The license plate. Up to 50 characters. Example: `FD 1234`. Headers recognized: plate, plate number, license plate, registration, tag. | +| `Four-wheel drive [four_wheel_drive]` | `four_wheel_drive` | Yes/No | | Yes when the unit has four-wheel drive. Example: `no`. Headers recognized: 4wd, four wheel drive, 4x4, awd. | +| `Special permit [special_permit]` | `special_permit` | Yes/No | | Yes when driving the unit needs a special permit. Example: `no`. Headers recognized: special permit, permit, cdl. | +| `Seats [seats]` | `seats` | List of text | | The unit's riding positions, separated by semicolons. Separate values with `;`. Example: `Officer; Driver; Firefighter; Firefighter`. Headers recognized: seats, positions, riding positions, roles, crew. | + +*Contract `units` version 2026.11.1, generated from the import catalog.* + + + + +## Unit certifications sheet + + + +Each unit's inspections, registrations and tests, with numbers and dates. Records that are already expired are imported as expired, so nothing is announced. + +Starter workbook sheet **Unit certifications**; CSV template `resgrid-unit-certifications.csv`; imported after [Units](#sheet-units), [Certification types](roles-and-certifications#sheet-certification-types). + +| Column header | Field key | Type | Required | Notes | +|---|---|---|---|---| +| `Source ID [source_id]` | `source_id` | Text | | The record's id in the system you are leaving. Lets a re-import recognize the record instead of adding it twice. Up to 256 characters. Must be unique in the file. Example: `1042`. Headers recognized: id, source id, external id, record id, key. | +| `Unit [unit]` | `unit` | Reference | Yes | Which unit, by its source ID or name. Refers to [Units](#sheet-units). Example: `Engine 1`. Headers recognized: unit, apparatus, vehicle, unit name. | +| `Certification [certification_type]` | `certification_type` | Reference | Yes | Which certification, by its name, code or source ID. It must be a type meant for units. Refers to [Certification types](roles-and-certifications#sheet-certification-types). Example: `Annual pump test`. Headers recognized: certification, certification type, inspection, registration, type. | +| `Certificate number [number]` | `number` | Text | | The number on the certificate or registration. Up to 200 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `PT-2026-117`. Headers recognized: number, certificate number, registration number, inspection number. | +| `Issued by [issued_by]` | `issued_by` | Text | | Who issued it or carried out the inspection. Up to 200 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `County Fleet Services`. Headers recognized: issued by, issuer, inspector, authority. | +| `Issued on [issued_on]` | `issued_on` | Date | | The date it was issued or the inspection took place. Example: `2026-03-02`. Headers recognized: issued, issued on, issue date, inspected on, date. | +| `Expires on [expires_on]` | `expires_on` | Date | | The date it expires or is due again. Leave empty when it does not expire. Example: `2027-03-02`. Headers recognized: expires, expires on, expiration, expiration date, expiry, valid until, due. | +| `Notes [notes]` | `notes` | Text | | Findings or remarks about the record. Up to 4000 characters. Department-only; protected by Advanced Data Protection when your department uses it. Example: `Passed with minor findings`. Headers recognized: notes, comments, remarks. | + +*Contract `unit-certifications` version 2026.11.1, generated from the import catalog.* + + + +Unit certifications are never matched automatically — a unit can hold two records of one type — so give them a Source ID if you may upload the file again. A record whose **Expires on** date has passed is imported as *Expired*, so nothing announces it; the preview asks you to confirm *N unit certifications have already expired*. The certification type must be one meant for units (*N unit certifications use a type meant for people*). Rolling the import back removes the records it added. + + +## How units are matched + +- **Unit types** and **units** are matched by Source ID (same workspace, or the import it [continues](uploading-and-checks#continue)), otherwise by **name**, ignoring case, accents, spaces and punctuation. Deleted units are not matched. +- Two existing records with the same name block the row until you rename one in Resgrid. +- With *Review updates*, a matched unit's VIN, plate number, four-wheel drive and special permit are updated where they differ; its type, station and seats are set only when the unit is created. +- An import never renames a unit type: units and calls refer to types by name, so a rename would break those links. Rename types on the [Types](../types-configuration) screen. + +More rules: + +- A unit's **Type** is a unit type by name — a row in your Unit types file or an existing type. With **Keep as text** on the value matching page the name is stored on the unit as it is; with **Create new** a unit type with that name is created. +- A unit's **Station** refers to a station or group by Source ID or name. +- **Seats** become the unit's riding positions, in the order given. Repeat a name for each seat of that kind: `Officer; Driver; Firefighter; Firefighter` creates four seats. +- A unit type's **Status set** names a set of *unit* statuses — a set in your Statuses file or one that already exists. Empty means the default unit statuses. +- Extra columns can be [kept as custom fields](matching-columns-and-values#custom-fields) on units. +- Units are counted against your plan when they are written; if the plan runs out of room, the remaining units are skipped rather than written. diff --git a/docs/web-app/import-and-migration/uploading-and-checks.md b/docs/web-app/import-and-migration/uploading-and-checks.md new file mode 100644 index 0000000..7edd21b --- /dev/null +++ b/docs/web-app/import-and-migration/uploading-and-checks.md @@ -0,0 +1,136 @@ +--- +sidebar_position: 4 +title: Uploading & Automatic Checks +--- + +# Uploading Files and the Automatic Checks + +**Department menu → Import & Migration → (workspace) → Files & data sets** + +You upload each file once; Resgrid does the rest in the background. Files are sent in pieces, scanned for viruses, split into **data sets** (one per CSV file or workbook sheet), matched to the kind of data they contain, and run through a ladder of checks. You can close the page at any point — the Overview tab shows *Work is running in the background* while something is still being processed, and the counts update by themselves. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +**Files & data sets** tab of a workspace: + +| Panel | Contents | +|---|---| +| **Upload a file** | File picker (CSV, TSV, text, Excel `.xlsx`, JSON, JSON Lines and GeoJSON) and **Upload**. | +| **Data sets** | One row per data set: name, destination (with an *N% sure* chip while it is unconfirmed), status, rows, ready, blocked (links to its issues), **Open** and **Exclude** / **Include**. | +| **Uploaded files** | Each file with its size, upload time and state: *Uploading*, *Received*, *Deleted after retention*, or the reason it was refused. | +| **Resgrid starter workbook** | Templates and current data — see [Starter workbook](starter-workbook). | + + +## Turning it on + +Uploads need the module turned on for your department (`Onboarding.MigrationWizard`), a department administrator, and — on self-hosted installations — the import file store configured. Excel files also need virus scanning on the server. See [Overview → Turning it on](overview#enable). + + +## Uploading + +1. Choose the file and select **Upload**. +2. *Preparing the file…* — your browser computes the file's fingerprint (SHA-256) first. +3. *Uploading… N%* — the file is sent in 8 MiB pieces. Each piece is checked against its own fingerprint as it arrives and stored encrypted. +4. *Finishing the upload…* — the pieces are joined and the whole file is checked against the fingerprint from step 2. A file damaged on the way is refused (*The upload was damaged on the way*). +5. *Uploaded. We're checking the file now; you can close this page.* + +If the connection drops or the page reloads, select the **same file** again and **Upload**: in the same browser tab, the page asks Resgrid where the upload stopped and continues from the next piece. A different file — or the same file changed since (different size or modified time) — starts a fresh upload, and so does an upload that has expired. An upload left unfinished is cleared after 24 hours. Size limits depend on your plan — see [File limits](before-you-start#file-limits); a file over the limit, or one that would take the workspace over its total, is stopped before any of it is sent. + +The original file name is shown to you but never used to store the file, and the file itself is kept only for its [retention period](rollback-and-retention#retention-schedule). + + +## Where your data comes from + +On the Files tab, **Where your data comes from** records the products you are moving from. Choose one under **Add a product** and select **Add product**; remove one with the **×** beside it. You can choose several. The list is grouped by what Resgrid has for each product: + +| Badge | Products | What you get | +|---|---|---| +| **Glossary available** | Active911, Aladtec, D4H Team Manager, DIVERA 24/7, Emergency Reporting, ESO Fire RMS, First Due, GIS layers (ArcGIS, CalTopo), IamResponding, Mark43 CAD, NERIS, NFIRS 5.0, Ontario Standard Incident Report (SIR), PSTrax, UKG TeleStaff, Vector LMS (TargetSolutions), Vector Scheduling (CrewSense) | The product's [glossary](matching-columns-and-values#glossary): what its words are called in Resgrid. Its words for Resgrid's features are suggested on the [Configure tab](configure#suggestions) (for example *Members* for Personnel from Aladtec). | +| **No direct import — use a spreadsheet** | Alpine RedAlert NMX, CentralSquare, Fire Service Rota, Firehouse Software, FireManager, FirstIn, Gartan, Hexagon HxGN OnCall, Motorola PremierOne / Flex, Operative IQ, PageOne, SARCALL, Shiftboard, Station Boss, Tyler New World, When I Work, Who's Responding, ZOLL FireRMS | Nothing beyond a spreadsheet: Resgrid found no reliable public information about these products' exports. Export your data to a spreadsheet or CSV and match its columns ([starter workbook](starter-workbook)). | + +Not listed? Export your data to a spreadsheet or CSV: every file is matched the same way. Resgrid does not read any of these products' files directly yet, and choosing a product changes nothing about how your files are read, matched or recognized on a later import. A product can't be removed while a data set of the import comes from it (*A data set in this import comes from that product, so it can't be removed.*). + + +## Continuing an earlier import + +When the files are a later export from the same system — next month's roster, or the second part of a phased move — tell Resgrid which import they continue. On the Files tab, **Continue an earlier import** lists the department's earlier imports that brought rows in (*Spring roster — 2 data set(s) imported, last on 4/3/2026*). Choose one under **This import continues** and select **Save**: *Saved. This import continues "Spring roster"; we're checking the files again.* + +From then on, for every file in this workspace: + +- a row whose **Source ID** that import already brought in is recognized instead of added again — *Unchanged* with **Add only**, or an update to review with **Review updates** ([write modes](review-and-import#write-modes)); +- another file can refer to that import's records by their Source IDs — for example people pointing at stations imported last time by `ST-1`. + +The choice applies to every file of the workspace and is shown as *Continues "Spring roster".* Choose **No earlier import** and **Save** to stop. Once this workspace has imported rows the choice is locked (*This import has already brought in rows, so it can no longer continue another one.*), because its own Source IDs are recorded under it. Continuing an import that itself continued an earlier one keeps the chain: all three share the first import's Source IDs. Without this choice, a new workspace matches records only by name (people by email). + + +## Virus scan and file safety + +Before anything in a file is read: + +- **Virus scan.** Where the server scans uploads, every file is scanned. A file that fails is never opened (*The file failed the virus scan*). If the scanner is busy, Resgrid keeps trying for up to 24 hours (*Waiting for the virus scan*). Where the server does not scan uploads, only CSV, text and JSON files are accepted. +- **Content over name.** The content must match the type: a CSV must be text, an `.xlsx` must be a real Excel workbook. Macro-enabled, binary, old-format and password-protected workbooks, workbooks with embedded objects and workbooks that link to other files are refused, each with its own explanation. +- **Formulas are never run.** Resgrid reads the values Excel last saved. +- **Size and shape.** Row, column, cell-length and sheet limits are enforced; hidden control characters in a cell are flagged. + +Every refusal has a code and a plain explanation — see [File safety and storage](fixing-issues#issues-file-safety). + + +## From files to data sets + +- A **CSV, TSV, text or JSON** file becomes one data set. +- An **Excel workbook** becomes one data set per visible sheet. Hidden sheets, and the starter workbook's *Instructions* and *Lists* sheets, are skipped. +- The first row holds the column names. Completely blank rows and starter-workbook example rows are skipped. + +**What each data set contains** (its *destination*) is worked out from its column headers: + +| The file is… | Result | +|---|---| +| A **Resgrid starter workbook** sheet or CSV template | Recognized by its `Label [field_key]` headers and the `resgrid:example` column. Destination and column matches are confirmed automatically — 100% sure. | +| **Any other file** | Its headers are compared with every data set's fields and the header names each field is known by (for example *e-mail*, *mail* and *email address* for a person's email). The best fit is proposed with a confidence. When Resgrid is at least 85% sure **and** every required field has a column, the proposal is confirmed automatically; otherwise the data set waits for you as *Needs matching*. | + +Open the data set to confirm or change its destination and its column matches — see [Matching columns and values](matching-columns-and-values). A data set you do not want can be **excluded** (and included again later) from the Data sets table; it is then never imported. + + +## Data set statuses + +| Status | Meaning | +|---|---| +| **Uploading** / **Scanning** / **Checking** | Work in progress. | +| **Needs matching** | Confirm what the file contains, or match a required field. | +| **Needs attention** | Blocking issues are open — see the Issues tab. | +| **Ready** | Everything left is ready to import (warnings accepted, problem rows excluded). | +| **Approved** | Included in an approved import that has not finished yet. | +| **Importing** / **Imported** / **Verified** | Being written; written; written and reconciled. | +| **Excluded** | You left this data set out. | +| **Failed** | The data set could not be read — the reason is on the Issues tab. | + + +## The verification ladder + +Every data set climbs the same ten-level ladder. The early levels run as soon as a file arrives and again after every change you make; the department-level checks run again when you approve and when the import starts, because their answers can change in the meantime. A **blocking** result stops that data set from being approved until you fix it or exclude the rows; a **warning** needs you to accept it. + +| Level | What is checked | Example codes | When | +|---|---|---|---| +| **L0 File safety** | Virus scan, real file type, macros, password protection, embedded objects, external links, size and row/column/cell limits, control characters, encoding. | `IMP-FILE-INFECTED`, `IMP-FILE-SIGNATURE`, `IMP-FILE-MACRO` | Upload | +| **L1 Reading** | Well-formed CSV / Excel / JSON, consistent columns, duplicate column names, empty files. | `IMP-PARSE-COLUMNS`, `IMP-PARSE-HEADER-DUP` | Checking | +| **L2 Shape** | What the file contains is confirmed; every required field has a column; no field matched twice. | `IMP-DETECT-LOW-CONFIDENCE`, `IMP-MAP-REQUIRED-UNMAPPED` | Checking | +| **L3 Type** | Each value converts to its field's type: lengths, number ranges, dates, phone numbers (read with your department's country), emails, coordinates, colours, time zones, languages, choices. | `IMP-TYPE-DATE-AMBIGUOUS`, `IMP-PHONE-UNPARSEABLE`, `IMP-EMAIL-INVALID`, `IMP-CHOICE-UNMAPPED` | Checking, and again after each fix | +| **L4 Row rules** | Required values present; expiry not before issue; latitude and longitude together; sensitive columns dropped. | `IMP-REQUIRED-MISSING`, `IMP-ROW-EXPIRES-BEFORE-ISSUED`, `IMP-EXCLUDED-SENSITIVE` | Checking | +| **L5 File rules** | Unique names, emails and Source IDs within the file; no loops of parent groups. | `IMP-DUP-IN-FILE`, `IMP-DUP-SOURCE-ID`, `IMP-HIERARCHY-CYCLE` | Checking | +| **L6 References** | Every reference finds exactly one row in another file of the workspace or one existing record. | `IMP-REF-UNRESOLVED`, `IMP-REF-AMBIGUOUS` | Checking | +| **L7 Your department** | Matches with existing records, Resgrid accounts that already exist, plan capacity, modules switched on, custom fields. | `IMP-MATCH-EXISTING`, `IMP-PERSON-EXISTING-ACCOUNT`, `IMP-PLAN-CAPACITY`, `IMP-ENTITLEMENT-MISSING` | Preview, approval, import start | +| **L8 Consequences** | What Resgrid will do later because the data exists — expired certifications, status sets your people will see. Each needs your tick. | `IMP-CONSEQUENCE-UNDECIDED` | Preview | +| **L9 Approval** | The data is still exactly what was approved, and the approver is still an administrator. | `IMP-APPROVAL-STALE`, `IMP-APPROVER-NOT-AUTHORIZED` | Import start | +| **L10 Reconciliation** | What was written matches what was approved, every reference is intact, people created by the import are dormant. | `IMP-RECONCILE-MISMATCH` | After the import | + +Checks never put the contents of a cell in an issue: issues name the column, the rows and the code, and the value is looked up only when you open the row. The same file, matches and catalog always produce the same issues. Every code is listed on [Fixing issues](fixing-issues#issue-codes). + + +## Uploading from a script + +Automation can use the v4 API with a department administrator's sign-in: `StartUpload` (file name, size and SHA-256), `UploadChunk` (raw bytes, 1-based part number and the piece's SHA-256), `CompleteUpload`, then poll `GetProgress`. `StartAnalysis` re-runs the checks for a workspace's data sets. Matching, approval and everything after it happen in the web application. See the [technical reference](overview#tech-ref). diff --git a/docs/web-app/import-and-migration/verify-and-activate.md b/docs/web-app/import-and-migration/verify-and-activate.md new file mode 100644 index 0000000..31c270d --- /dev/null +++ b/docs/web-app/import-and-migration/verify-and-activate.md @@ -0,0 +1,130 @@ +--- +sidebar_position: 8 +title: Verify & Activate +--- + +# Verify and Activate + +**Department menu → Import & Migration → (workspace) → Verify & activate** + +After an import, Resgrid checks that what was written matches what you approved. **Verify & activate** shows those results and walks you through going live: confirm who becomes an administrator, invite the people you imported — in small batches, never at night — and sign off. Imported people stay **dormant** until you invite them, so nothing reaches them before you are ready. + +:::note Preview feature +Import & Migration is a **Preview** feature: it is off by default and Resgrid turns it on per department while it is being rolled out. +::: + + +## Where to find it + +The **Verify & activate** tab of a workspace, or **Verify** on an imported data set's card and the **Next step** card (*Check the results of the import*, then *Everything is verified: invite your people and go live*). + +| Area | Contents | +|---|---| +| **Stat tiles** | **People imported**, **Not invited yet**, **Invited**, **Signed in**, **Checks that differ** (opens History). | +| **Activation checklist** | The steps below with *Done*, *Required* or *Recommended* chips, and **Sign off and go live**. | +| **People who will become administrators** | Shown when your file marked people as administrators. | +| **Invite people** | Who to invite and when. | +| **Invitations** | Every invitation with its status, **Resend** and **Revoke**. | + + +## Turning it on + +Part of Import & Migration: the `Onboarding.MigrationWizard` flag on for your department and a department administrator signed in. Signing off needs your second factor. See [Overview → Turning it on](overview#enable). + + +## Verify the result + +Every import ends with a verification run (*Checking* on the History tab). For each kind of data it compares what the import recorded with what is actually in Resgrid: every row it says it wrote exists in your department, every reference points at a record of your department, and every person it created is still dormant unless you invited them. The History tab shows the outcome next to the run — **N checks matched** or **N checks differ** — and data sets that pass become **Verified**. + +Rows the import could not write (`IMP-ROW-WRITE-FAILED`, `IMP-PERSON-ACCOUNT-FAILED`) are not part of that comparison — the import never recorded them as written — so they never show as a difference and they do not stop you signing off. Reconcile the *N added, N updated or linked, N unchanged, N skipped, N failed* counts on the History tab against your source file first, and [ask Resgrid support](getting-help-from-support) about the failed rows: signing off starts the rollback and retention clocks. + +A difference (*The check after the import found a difference*) needs explaining before you can sign off. Compare the counts on the History tab with your file; if they don't add up, [ask Resgrid support](getting-help-from-support) from the run. *Some finishing steps didn't complete* means parent groups, a status button's next statuses or some roles may need setting by hand. + +Spot-check in Resgrid itself too — [Personnel](../personnel), [Units](../units), [Groups & Stations](../groups-stations), [Types](../types-configuration), [Custom Statuses](../custom-statuses), [Mapping](../mapping) — and look at **Setup Report** in [Help & Setup](../help-setup), which counts an import as complete once it is verified. + + +## The activation checklist + +| Item | Chip | Done when | +|---|---|---| +| **Review the import results** | Required | At least one import has finished and no check differs. | +| **Practice: run a Communication Test** | Recommended | Advisory — the link opens [Communication Tests](../communication-tests) in a new tab so you can test paging with a few people you have already invited. It is never ticked automatically. | +| **Confirm administrators** | Recommended | Everyone your file marked as an administrator has been confirmed (or there was nobody). | +| **Invite your people** | Recommended | Nobody is left to invite. | +| **Sign off** | Required | You selected **Sign off and go live**. | + +Activation is a checklist, not a switch: *Each item can be done separately; nothing is switched on all at once.* **Sign off and go live** (with your second factor) is available once at least one import has finished, no check differs and no import or rollback is running. It records your sign-off (*Signed off. Your department is live.*), marks the workspace **Live**, and starts the clock on the [rollback window](rollback-and-retention#rollback-window) and the [retention of checked data](rollback-and-retention#retention-schedule). You can sign off before everyone is invited and keep inviting afterwards. + +For a live department (*Add to a live department*, *Update a live department*, *Continue an earlier import*) the same tab is where you invite the people each import created and record that the work is finished. + + +## Confirm administrators + +People whose **Department administrator** column said *yes* are imported as normal members and listed under **People who will become administrators** — *Your file marked these people as administrators. Confirm each one; until then they're normal members.* Tick the people to promote and select **Make administrators**. Nobody becomes an administrator just because a file said so. + + +## Dormant members + +Every person an import creates starts **dormant**: + +- **They cannot sign in.** A sign-in attempt is refused, and so is a password reset, while their only memberships are dormant. +- **They receive nothing.** No dispatches, messages, notifications, certification reminders, calendar or training notices, or digests — they are left out of every notification sweep, exactly like a disabled member. +- **They count as members.** They appear in your department and use a seat on your plan. + +| State | Tile | Meaning | +|---|---|---| +| **Dormant** | *Not invited yet* | Imported, not invited. | +| **Invited** | *Invited* | An invitation is scheduled or sent. Still dormant: nothing but the invitation reaches them. | +| **Activated** | *Signed in* | They accepted the invitation and set a password. From now on they are a normal member. | + +People your file marked **inactive** are imported disabled and hidden as well as dormant; they are not counted or listed among the people to invite, and inviting skips them. Admin Assist raises a finding when imported people have not been invited for more than two weeks. + + +## Invitations + +**Invite people** — *Imported people can't sign in or receive anything until you invite them. Invitations are sent in small batches, outside night hours in your department's time zone.* + +1. **Invite all N people** is ticked, with everyone not yet invited listed below it. Untick anyone who should not be invited yet — for example a station you are bringing on later. People your file marked inactive are not listed. +2. **Invite N people who already have a Resgrid account to join** is ticked when some of the people in your file already have a Resgrid account in another department (see [below](#existing-accounts)). +3. **Send no earlier than** — a date and time, or leave it empty to send as soon as possible. +4. Select **Schedule invitations**: *N invitations scheduled.* + +How they are sent: + +- In **batches of about 50 a minute**, by Resgrid's background worker. +- **Never between 21:00 and 07:00** in your department's time zone — an invitation due at night waits until 07:00. +- In the person's **language** when your file set one, otherwise the department's. +- A failed send is retried automatically (up to five attempts), then shown as *Failed*. + +The **Invitations** table lists each one with its email, kind (**Account** or **Join with an existing account**) and status: *Scheduled*, *Sent*, *Accepted*, *Failed* or *Revoked*. **Resend** puts an invitation back in the queue for the next batch. **Revoke** cancels it; the person goes back to *Not invited yet* and can be invited again later. + + +## Steps Resgrid staff plan for you + +In a [managed migration](getting-help-from-support#managed), Resgrid staff can also send the invitations, confirm administrators and sign off for you, if your grant allows it. These steps never just happen: + +- **Two Resgrid staff members** sign every step: one requests it, a different one approves it. +- **Your Verify & activate tab shows each planned step** at the top, labelled *Resgrid staff*: *Resgrid staff planned a step on your department's behalf.*, what it does (for example *Invite 312 people.*), and who requested it. +- **Under a contract authorization, every administrator is told 24 hours ahead.** Each one gets a notice like *Resgrid will invite 312 people from "Spring roster" on 2026-11-02 14:00 UTC*. Nothing happens before that time unless an administrator approves sooner. +- **If you asked to approve every step** when you granted access, a step that two staff members approved waits with *Two Resgrid staff members approved this. It starts when an administrator of your department approves it.* and **Approve and start**. + +What you can do with a planned step: + +| It shows | You can | +|---|---| +| *It waits for a second Resgrid staff member to approve it.* | **Cancel it**. You can't approve it before the second staff member has. | +| *Two Resgrid staff members approved this. It starts when an administrator of your department approves it.* | **Approve and start** (confirm with your second factor) or **Cancel it** | +| *Two Resgrid staff members approved it. It is scheduled for (date); you can start it now or cancel it.* | **Start now** (confirm with your second factor), which ends the notice period, or **Cancel it** | + +**Cancel it** stops the step before anything is sent or changed. Every request, approval and cancellation is on the workspace timeline. A step Resgrid staff carry out follows the same rules as yours: people imported as inactive are never invited, invitations respect night hours, and sign-off needs a clean reconciliation. + + +## What invited people see + +**People the import created** get an email with a link. The page says *[Department] has set up a Resgrid account for you. Choose a password to sign in for the first time.*, shows their user name, and asks for a password. **Set password and sign in** activates them, confirms their email and signs them in. From then on they are a normal member and can set up two-factor authentication, the apps and their notification preferences. + + + +**People who already have a Resgrid account** (their email belongs to another department) are never added silently and their profile is never touched. Their invitation says *[Department] has invited you to join with your existing Resgrid account.*; they select **Sign in to accept**, sign in with **that** account, and select **Join [Department]**. Their membership is created only then — and only if your plan still has room. An invitation opened while signed in with a different account shows *This invitation was sent to a different email address. Sign in with the account it was sent to.* + +An invitation that was revoked or already used shows *This invitation can no longer be accepted. Please contact the administrator who invited you.* diff --git a/docs/web-app/incident-back-office/_category_.json b/docs/web-app/incident-back-office/_category_.json new file mode 100644 index 0000000..778319b --- /dev/null +++ b/docs/web-app/incident-back-office/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Incident Back Office", + "position": 22, + "link": { + "type": "generated-index", + "description": "Run the logistics, finance and coordination side of large incidents: activations and operational periods, organization and check-in, resource requests, lodging, feeding, water, services and vendors, procurement, budget, time, cost share, claims, disaster recovery and coordination boards." + } +} diff --git a/docs/web-app/incident-back-office/activation.md b/docs/web-app/incident-back-office/activation.md new file mode 100644 index 0000000..6d8f1af --- /dev/null +++ b/docs/web-app/incident-back-office/activation.md @@ -0,0 +1,51 @@ +--- +sidebar_position: 2 +title: Activation and command +--- + +# Activation and command + +An **activation** says "this department is running the back office for this incident". Everything else in the module hangs off it. + +## Opening an incident + +Go to **Incident Back Office → Incidents → Open an incident** (permission *Manage incident activation*). + +| Field | Notes | +|---|---| +| Kind | **Incident**, **Complex** (a group of incidents managed together), **Planned event** or **EOC activation**. | +| Name and short code | The short code (2–32 letters, digits, `-` or `_`) is printed on badges, request numbers and notices, and must be unique among open incidents. | +| Complexity type | Type 1–5, optional. | +| Exercise | Marks the activation as an exercise everywhere. | +| Dispatch call | Links a call so the back office can read its dispatched people and units and its command board. Links are read-only: the back office never changes the call. | +| Complex | Puts the incident into an open complex. A complex's desks roll up all of its incidents. | +| Time zone, currency, units | Every time on this incident's desks shows in its own time zone — a meal cutoff is local to the incident, not to headquarters. Currency and measurement system default from your settings or your department's country. | +| Authority profile | Which system is the system of record for resource ordering, qualifications, inventory and cache, procurement and finance, mutual aid and the IAP. A snapshot of the profile is kept with the incident. | + +![Open an incident](/img/web-app/incident-back-office/open-incident.png) + +When you open an incident, Resgrid seeds the NIMS core position catalog if your department has none yet, creates the first operational period (length from your settings) and raises the *Incident activation changed* trigger. + +## The activation record + +**Activation record** shows who opened, closed, sealed or reopened the incident and when, its links and complex members. From there you can change the linked call or complex, and move the incident through its lifecycle (permission *Close incident activation*): + +**Preparing → Active → Demobilizing → Closed → Sealed** + +- **Closed** needs every blocking [closeout](finance#closeout) item to be complete or waived. +- **Sealed** freezes the incident: no record of it can change any more. +- **Reopening** a closed or sealed incident needs a reason, which is kept on the record. + +## Command desk + +The command desk opens on the incident's numbers — people and resources on the incident and inbound, open and overdue requests, fills en route, beds held and free tonight, open service tickets and pending demobilizations — each with its *as of* time, plus inbound arrivals and outbound departures by window (next 2, 6, 12 and 24 hours) and who holds which position right now. + +![Command desk](/img/web-app/incident-back-office/command-desk.png) + +The **Operations** desk shows the personnel picture: each participant's **support status** (owned by the back office) next to the position they hold. Operational status stays with dispatch and is never inferred from support status. + +![Operations desk](/img/web-app/incident-back-office/operations.png) + +## Freshness + +A background worker takes an incremental snapshot of every open incident's numbers every minute and a full rebuild every 30 minutes. When the snapshot falls behind your staleness setting, the context bar says the numbers may be out of date and the *Incident snapshot stale* trigger fires (and fires again, resolved, when it catches up). diff --git a/docs/web-app/incident-back-office/coordination.md b/docs/web-app/incident-back-office/coordination.md new file mode 100644 index 0000000..eed40f2 --- /dev/null +++ b/docs/web-app/incident-back-office/coordination.md @@ -0,0 +1,28 @@ +--- +sidebar_position: 6 +title: Coordination +--- + +# Coordination + +Coordination needs the **Coordination boards** module switch (on by default) and the *View coordination boards* permission. + +## Coordination boards + +**Coordination → Coordination boards** holds boards for the department or for one incident. A board is made of **lanes** — a type, a name, a display rule and a staleness window. When a lane's source has not changed within its window and the lane alarms on staleness, *Coordination lane stale* fires (and fires again, resolved, when the lane is fresh again). A board can be frozen or archived. + +To build a board, add the **board** (department scope, or tick **For incident** and pick the incident), then add a **lane** for each part of the picture you want to watch, with its type, name, order and staleness window. Tick **Alarm on stale** for lanes that must not go quiet, such as road closures and shelter capacity. + +![Coordination board lanes](/img/web-app/incident-back-office/boards.png) + +**Share grants** give a partner agency read access to a board or one lane through a link that expires (default from settings) and can be revoked at any time (*Share coordination boards*). + +## Situation + +**Coordination → Situation** holds the incident's situational picture: + +- **Lifeline status** — the community lifelines (safety and security; food, hydration and shelter; health and medical; energy; communications; transportation; hazardous materials; water) by component, colour-coded with the colour written out. *Incident lifeline status changed* fires on each change. Record each component with its status, the time it was true (*as of*) and its source. + +![Lifeline statuses](/img/web-app/incident-back-office/situation.png) +- **Situational features** — road closures, shelters, healthcare facilities, infrastructure and evacuation zones with status and capacity. *Incident situational feature changed* fires on each status change. +- **Open actions** and **decisions** with owners and deadlines. *Incident coordination item due* fires once inside your lead window (or when overdue). diff --git a/docs/web-app/incident-back-office/finance.md b/docs/web-app/incident-back-office/finance.md new file mode 100644 index 0000000..34b426a --- /dev/null +++ b/docs/web-app/incident-back-office/finance.md @@ -0,0 +1,74 @@ +--- +sidebar_position: 5 +title: Finance +--- + +# Finance + +The finance desks need the **Incident finance desks** module switch (on by default). The **Finance desk** shows committed spend and open commitments, yesterday's cost and the cost to date, time waiting to be certified or approved, invoice exceptions, and each budget line against its committed spend. A line past its threshold is highlighted. + +![Finance desk](/img/web-app/incident-back-office/finance-desk.png) + +## Separation of duties + +The finance steps are separate permissions, and the module refuses to let one person do two steps of the same purchase: + +- whoever requested a requisition cannot approve it; +- whoever approved it cannot commit it; +- whoever committed it cannot accept the receipt; +- whoever certified time cannot approve it. + +A small department can turn on **single-person operation** in [settings](settings); Resgrid records who turned it on and when. Once an incident has spending delegations, approving above your delegation threshold is refused (administrators excepted). + +## Procurement + +**Finance → Procurement** holds requisitions, approvals, commitments, purchase receipts, vendor invoice references and payment packages. + +- Requisitions are numbered (`RIDGE-REQ0003`); a micro-purchase that, with the same vendor's other micro-purchases inside your split-purchase window, would cross the micro-purchase threshold is flagged as a possible split purchase. +- A commitment against a requisition needs the requisition approved, and moves it to **Committed**. A commitment without a requisition under a method that needs one fires *Incident unapproved spend detected*. *Incident commitment recorded* fires for every commitment. +- Receipts move their commitment to partially received or received by amount. + +![Commitments](/img/web-app/incident-back-office/procurement.png) +- Invoice references flagged with a match variance, duplicate, unmatched or aged exception fire *Incident invoice exception*; payment packages fire *Incident payment package status changed*. + +## Budget + +**Finance → Budget** holds budgets, budget lines, funding authorizations, spending delegations, funding codes and cost groups. A line's revised amount is **authority, not a number you type**: it starts at the original amount and moves only through funding authorizations — revisions and transfers (which take the amount from the source line). Authorizations cannot be edited or deleted; record a new one. + +To set up a budget, add the **budget** with its original amount and currency, then a **line** for each section, function or cost group you track, with its threshold percentage. Link commitments (and lodging assignments) to a line so the finance desk can show committed spend against it. + +![Budget lines](/img/web-app/incident-back-office/budget.png) *Incident budget authority changed* fires for every authorization and delegation, and *Incident budget threshold* fires when a line's committed spend crosses its threshold (or the default) or its floor. + +## Time and equipment + +**Finance → Time** holds time records, adjustments, equipment use (shift tickets), expenses and rate snapshots. + +- Certified and approved time is **never edited** — record an adjusting record linked by an adjustment, and the original is marked *Adjusted*. +- A span longer than your work/rest rule's shift limit fires *Incident work/rest violation* (it is recorded, not refused). +- Time moves **Draft → Submitted → Certified → Approved**; open a record and use its status buttons. The finance desk counts what is waiting to be certified and approved. +- *Incident time missing* fires when people on the incident have no time for the last completed period; *Incident shift ticket missing* fires for contracted equipment without yesterday's shift ticket; *Incident time approved* fires on certification and approval. + +![Time records](/img/web-app/incident-back-office/time.png) + +## Cost + +Every night a worker posts the day's cost: certified and approved time priced from its rate snapshot, certified and approved shift tickets, and approved expenses — once per source record — then writes the accrual snapshot and a projection. *Incident cost threshold* fires when yesterday's cost is above your daily burn threshold. + +**Cost share**: an active cost-share agreement splits the cost to date by its ordered rules — a percentage split between parties, a direct charge to one party, or an exclusion — by cost category, section, funding code, facility or period. A new apportionment run is recorded only when the costs changed, with input and output checksums, and *Incident cost share apportioned* fires. + +## Claims + +**Finance → Claims** holds compensation, property, vehicle and equipment claims with deadlines. The claimant's details, financials and case notes are protected values (*View claim protected data*). The compensation positions are notified ahead of a claim deadline, and *Incident claim status changed* fires on each move. + +## Disaster recovery and intake + +- **Disaster recovery** holds declarations, recovery projects and obligation deadlines; *Incident recovery deadline approaching* fires inside your lead window. +- **Intake** files documents sent to the incident (receipts, shift tickets, invoices) to the record they belong to; *Incident intake backlog* fires when unfiled items pile up or age past your limits. + +## Closeout + +**Records → Closeout** holds the closeout checklist. The incident cannot be closed while a blocking item is open; completing or waiving an item (waivers need a reason) fires *Incident closeout milestone*. + +Add an item for each piece of closeout work, with its category, the owning position and whether it blocks closing. Open an item and choose **Complete** or **Waived** when it is done. When nothing blocking is open, close the incident from its activation record, then seal it. + +![Closeout checklist](/img/web-app/incident-back-office/closeout.png) diff --git a/docs/web-app/incident-back-office/getting-started.md b/docs/web-app/incident-back-office/getting-started.md new file mode 100644 index 0000000..2e03e9f --- /dev/null +++ b/docs/web-app/incident-back-office/getting-started.md @@ -0,0 +1,117 @@ +--- +sidebar_position: 1.5 +title: Getting started +--- + +# Getting started with Incident Back Office + +This page walks an administrator through setting up Incident Back Office for a department, and then through running a first incident from activation to the first desk check. Each step links to the page that covers it in depth. + +:::note +The screenshots on these pages come from a fictional demo incident, the *Cedar Ridge Fire*. Every person, agency, vendor and amount in them is made up. +::: + +## Set up your department + +:::note The rollout comes first +Incident Back Office is rolled out department by department, on top of the add-on, the module switches and permissions. The **Incident Back Office** rollout opens the module, **Incident Business** the finance desks, and **Incident Coordination** the boards and the situation desk. On the hosted service ask Resgrid to switch on the ones you need; on a self-hosted installation the operator turns them on with the [feature flag](../../reference/feature-flags) console. Without the rollout, buying the add-on and leaving the switches on is not enough. +::: + +### 1. Add the add-on + +The department's managing member adds **Incident Back Office** from **Subscription → Incident Back Office**. Until the department has the add-on, the **Incident Back Office** entry in the sidebar opens the same add-on page, with the price, what is included and a **Buy** button. Incident Back Office is billed monthly per department (USD 250 in the US, EUR 350 in the EU), even if your main subscription is annual. + +### 2. Check the module switches + +Go to **Department → Module Settings** and find the three Incident Back Office switches: + +- **Incident Back Office**: the whole module. +- **Incident finance desks**: procurement, budget, time, cost, recovery, intake and claims. +- **Coordination boards**: boards and the situation desk. + +All three are on by default. Turning one off hides its pages and stops its background work for your department; nothing is deleted. + +![Module settings](/img/web-app/incident-back-office/module-settings.png) + +### 3. Give people permissions + +Under **Department → Security**, Incident Back Office has its own group of permissions. Each one starts from a sensible default (everyone, group and department administrators, or department administrators only), which you can change: + +| Area | Permissions | +|---|---| +| Command and planning | *View Incident Back Office* (everyone), *Manage incident activation*, *Manage incident periods*, *Manage incident positions*, *Manage incident participants*, *Assemble incident IAP* | +| Logistics | *Create*, *Approve*, *Order* and *Receive incident request*; *Manage incident facilities*, *lodging*, *feeding*, *services*, *ground support* and *comms*; *Manage vendor catalog*, *Engage vendor* | +| Finance | *Manage incident procurement*, *Commit incident purchase*, *Accept vendor invoice*, *Manage incident budget*, *Authorize incident funding*, *Enter*, *Certify* and *Approve incident time*, *View* and *Manage incident cost*, *Manage incident claims* | +| Coordination | *View coordination boards* (everyone), *Manage coordination boards*, *Share coordination boards* | +| Protected details | *View participant sensitive data*, *View lodging assignment detail*, *View vendor protected data*, *View claim protected data* | + +The finance steps are separate permissions on purpose. Resgrid also refuses to let one person take two steps of the same purchase or time record (see [Separation of duties](finance#separation-of-duties)), so give the requesting, approving, committing and certifying permissions to different people. A small department can turn on single-person operation in [Settings](settings). + +### 4. Review the department settings + +**Incident Back Office → Department setup → Settings** (administrators) holds the policies the module uses: staleness, the default currency and period length, enrollment mode, who receives each notice, forecast coefficients and thresholds, assignment length and work/rest rules, vendor hold expiry, finance controls and retention. Each policy saves on its own, and an empty value uses the default. See [Settings](settings) for every value and its default. + +![Incident Back Office settings](/img/web-app/incident-back-office/settings.png) + +### 5. Build your position catalog + +**Department setup → Positions** holds the positions incidents are staffed from. Use **Add NIMS core**, **Add NWCG wildland** or **Add CICCS positions** to add the standard catalogs; each adds only the positions you do not have yet and never changes yours. Add your own roles (for example *Radio Technician*) with **New**, and list the qualifications a position needs so assignments can be checked against them. + +![Position catalog](/img/web-app/incident-back-office/positions.png) + +### 6. Set up standing teams (optional) + +If you keep standing teams, such as a county incident management team or an EOC section roster, add them under **Department setup → Incident teams**: the team, its rotations, a **slot** for each position and the **candidates** (primary, alternate and trainee) for each slot. **Team readiness** shows, for a window you choose, whether every slot has a qualified candidate, and **Propose activation** fills an incident's organization from the team in one step. + +![Incident team slots](/img/web-app/incident-back-office/teams.png) + +### 7. Add vendors and a support plan (optional) + +**Department setup → Vendor catalog** extends the vendors you already keep in [Inventory](../inventory) with locations, capabilities and capacity, availability windows and compliance documents. **Department setup → Support plan** ranks vendors by area. Both are covered in [Logistics](logistics#vendors). + +## Run your first incident + +### 1. Open the incident + +Go to **Incident Back Office → Command → Incidents → Open an incident**. Pick the kind (incident, complex, planned event or EOC activation), give it a name and a short code, and optionally link the dispatch call. Check the time zone, currency and measurement system: every time on the incident's desks shows in its own time zone. Leave **Start active** and **Create the first operational period now** ticked to start working straight away. Tick **Exercise** for a drill. + +![Open an incident](/img/web-app/incident-back-office/open-incident.png) + +### 2. Select it + +The **Incidents** page lists open incidents (tick **Include closed** for the rest). The incident you open stays selected on every desk until you switch, and the **context bar** at the top of every page shows its name, short code, status, current operational period, authority profile and how fresh its numbers are. + +![Incidents](/img/web-app/incident-back-office/incidents.png) + +### 3. Staff the organization + +On **Planning → Organization**, **Assign a position** for each role. Pick the position, then the person: a member, a participant, or a placeholder name to fill in later. Resgrid checks the person's qualifications against the position, reports overlapping assignments, and notifies the person in their own language. With a standing team, use **Propose activation** on the team instead. + +![Assign a position](/img/web-app/incident-back-office/assign-position.png) + +### 4. Enroll and check people in + +**Planning → Participants** holds everyone supported by the incident, including mutual-aid personnel and contractors who have no Resgrid account. Use the **Enrollment queue** to add the people and units already dispatched to the linked call, or **Roster import** for a CSV. Then check arrivals in on **Planning → Check-in** by the code on their badge or confirmation, or from the list of people expected. + +![Participants](/img/web-app/incident-back-office/participants.png) + +### 5. Watch the desks + +The **Command desk** now shows the incident's numbers: people and resources on the incident and inbound, requests, fills en route, beds tonight, service tickets and demobilizations, with arrivals and departures by window. Each section has its own desk: + +- [Logistics](logistics): requests and fills, facilities, lodging, feeding and water, services, ground support, communications and vendors. +- [Finance](finance): procurement, budget, time, cost, recovery, intake, claims and closeout. +- [Coordination](coordination): boards, lifelines, open actions, decisions and situational features. + +![Command desk](/img/web-app/incident-back-office/command-desk.png) + +### 6. Close out + +When the incident winds down, work the [demobilization](planning#demobilization) plans and the [closeout](finance#closeout) checklist. Once every blocking closeout item is complete or waived, close the incident, and seal it when nothing should change any more. + +## Tips + +- **Every list exports to CSV** with **Export CSV**; protected columns are left out. +- **Workflows** can react to forty-nine Incident Back Office triggers. See [Automations](overview#automations). +- **Exercises** are labelled on every page, notice and workflow event, and do not notify outside participants or vendors unless your settings allow it. +- **Desk numbers** are computed from the incident's own records. When the background snapshot falls behind, the context bar says so; see [Freshness](activation#freshness). diff --git a/docs/web-app/incident-back-office/logistics.md b/docs/web-app/incident-back-office/logistics.md new file mode 100644 index 0000000..11c09aa --- /dev/null +++ b/docs/web-app/incident-back-office/logistics.md @@ -0,0 +1,63 @@ +--- +sidebar_position: 4 +title: Logistics +--- + +# Logistics + +The **Logistics desk** opens on the section's numbers — open, critical and overdue requests, fills en route, people needing lodging, beds held and free tonight, open service tickets — and the arrivals expected in the next 2, 6, 12 and 24 hours. + +![Logistics desk](/img/web-app/incident-back-office/logistics-desk.png) + +## Requests and fills + +**Logistics → Requests** holds resource requests (permission *Create incident request*). A request gets a number like `RIDGE-R0007` unless you enter a locally issued one. Its lifecycle: + +**Draft → Submitted → Approved → Ordered → Partially filled / Filled → En route → Received → Assigned → Released → Demobilized → Closed** (or **Rejected** / **Cancelled**, which need a reason) + +*Approve incident request* approves and *Order incident request* orders; submitting, approving and ordering are stamped with who and when. Open a request and use its status buttons to move it along; **Rejected** and **Cancelled** ask for the reason. + +![Resource requests](/img/web-app/incident-back-office/requests.png) + +Once a request is ordered, record each **fill** — the provider, apparatus and personnel counts, quantity and ETA. Accepting, moving and arriving fills re-derives the request's status from the accepted quantity, and every move fires *Incident request status changed* with the fill's counts and ETA. When a fill arrives, the receiving positions (Logistics and Operations section chiefs, facilities and ground support unit leaders by default) are notified. *Incident resource arrival due* fires inside your arrival lead window, and again when a resource is late. + +Receipts record what arrived against a request — accepted, rejected and back-ordered quantities and damage — and fire *Incident receiving discrepancy* for shortages, overages, damage, wrong items and rejections. + +## Facilities + +**Logistics → Facilities** holds bases, camps, staging areas, helibases, shelters and the like, each with capacities per service (beds, parking, fuel, showers…), agreements and services. *Incident facility capacity threshold* fires when current use plus reservations reaches the facility's threshold (or the default from settings) and again when it recovers. + +## Lodging + +**Logistics → Lodging** holds properties (hotels or camps), room blocks with cutoffs and rates, units and beds, and lodging assignments. + +- An assignment holds **one bed for each night**. Two assignments can never hold the same bed on the same night — the database enforces it — and an assignment that needs an accessible bed cannot take one that is not. +- Cancelling or a no-show frees every night; checking out frees the nights from today. +- *Incident lodging shortfall* fires when, for tonight or the next two nights, the people who need lodging outnumber the usable beds less your reserve. +- Room labels and confirmation numbers are protected values; rooming lists are versioned. + +To set up lodging for an incident, add the **property** (tick **Is camp** for a camp), then its **units** (rooms, tents or bunkhouses) and the **beds** in each unit. Block-booked hotel rooms go in a **room block** with its cutoff and rate. Then give each person a **lodging assignment**: the bed, the first and last night, and any accessibility or single-occupancy need. + +![Lodging assignments](/img/web-app/incident-back-office/lodging.png) + +## Feeding and water + +**Logistics → Feeding** holds meal plans per site and window with order cutoffs, demand versions, orders and actuals. Every 15 minutes a worker forecasts the next three days of meals from the people on the incident who need meals (not self-sufficient), crews in resources, departures, the unregistered band from the enrollment queue and your contingency percentage; manual overrides are kept with their reason. *Incident meal cutoff approaching* fires inside your lead window when orders are below the forecast. + +**Logistics → Water** holds water plans with storage, reorder and days-of-supply thresholds, stock readings and deliveries. *Incident water below threshold* fires when stock falls below the reorder point or the days of supply (from the population and your litres-per-person coefficient) drop below the threshold. + +## Services, ground support and communications + +- **Services**: service tickets from templates (laundry, sanitation, repair…) with SLA timers, activities and assets; *Incident service request status changed* fires on each move. Add your **service templates** first (a code, a category and a default SLA), then open tickets against them. +![Service requests](/img/web-app/incident-back-office/services.png) + +- **Ground support**: transport requests and movements (shuttles, crew transport, cargo, travel, fuel), travel itineraries and fuel transactions; *Incident transport movement changed* fires on moves and exceptions. +- **Communications**: communications plans and custody of radios, kits and batteries. *Incident accountability exception* fires for lost or damaged items and for items still out after their expected return. + +## Vendors + +**Department setup → Vendor catalog** extends your inventory vendors with locations, capabilities (category, unit, normal and maximum capacity, lead time), availability windows, compliance documents (insurance, licences, food and water safety, tax forms) and protected tax and remittance details. *Incident vendor compliance expiring* fires inside your compliance lead window, and expired documents are marked expired. + +**Logistics → Vendors on incident** holds engagements, quotes and **capacity holds and commitments**. A vendor capability's capacity is shared across all of your department's incidents: a hold or commitment that would take more than the capability's maximum in an overlapping window is refused, unless an administrator overrides it with a reason — the override fires *Incident vendor capacity conflict*. Holds expire automatically (setting) and *Incident hold expiring* fires ahead of the expiry. + +**Department setup → Support plan** holds your emergency support plan: areas and ranked vendor preferences, snapshotted into each incident. diff --git a/docs/web-app/incident-back-office/overview.md b/docs/web-app/incident-back-office/overview.md new file mode 100644 index 0000000..e268a46 --- /dev/null +++ b/docs/web-app/incident-back-office/overview.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 1 +title: Overview +--- + +# Incident Back Office — Overview + +**Incident Back Office** runs the side of a large incident that dispatch and incident command do not: who is on the incident and where they sleep, what has been ordered and when it arrives, what everything costs and who pays for it, and what partner agencies need to see. It is built around the Incident Command System sections — Command, Planning, Logistics and Finance/Administration — and works alongside the Incident Command board and [dispatch calls](../dispatch-calls) without changing them. + +Incident Back Office is a paid add-on: **USD 250 per month** (US, billed through Stripe) or **EUR 350 per month** (EU, billed through Paddle), per department. One add-on covers every part of the module. + +New to the module? Start with [Getting started](getting-started), which walks through setup and a first incident step by step. + +![Command desk](/img/web-app/incident-back-office/command-desk.png) + +## What it covers + +| Area | What you do there | +|---|---| +| [Activation and command](activation) | Open an incident, complex, planned event or EOC activation; link it to a dispatch call; pick who is the system of record for ordering, qualifications, finance and the IAP; see the command desk. | +| [Planning and organization](planning) | Operational periods in the incident's own time zone, the incident action plan, positions, assignments with qualification checks, standing incident management teams, participants, enrollment and check-in. | +| [Logistics](logistics) | Resource requests and fills, arrivals, demobilization, facilities, lodging with bed-night inventory, feeding and water forecasts, service tickets, ground support, communications custody and vendors. | +| [Finance](finance) | Requisitions, commitments and receipts with separation of duties, budget authority, time and equipment records, daily cost, cost share, invoices, claims, disaster recovery and closeout. | +| [Coordination](coordination) | Coordination boards for partner agencies, lifeline status, open actions, decisions and situational features. | +| [Settings](settings) | Department policies: staleness, enrollment, notice routing, forecast coefficients and thresholds, assignment and work/rest rules, vendor holds, finance controls and retention. | + +## Turning it on + +1. The department's managing member buys the add-on from **Subscription → Incident Back Office** (or **Incident Back Office** in the sidebar, which opens the add-on page when the department does not have it yet). +2. An administrator checks **Department → Module Settings**. Three switches control the module: **Incident Back Office** (the whole module), **Incident finance desks** (procurement, budget, time, cost, claims) and **Coordination boards**. All three are on by default. +3. The department needs the rollout as well: **Incident Back Office** for the module, **Incident Business** for the finance desks and **Incident Coordination** for the boards and situation desk. Resgrid switches these on for hosted departments; a self-hosted operator turns them on with the [feature flag](../../reference/feature-flags) console. +4. Give people the permissions they need under **Department → Security**. Every desk has its own *view* and *manage* permissions, and the finance steps (approve, commit, certify, approve time, export cost) are separate permissions so that the same person does not request, approve and pay. + +If the add-on lapses, every incident stays readable but nothing can be changed until it is renewed; a banner says so on every page. + +## Where to find it + +The sidebar has a collapsible **Incident Back Office** group with one entry per ICS section — Command, Planning, Logistics, Finance / Admin, Records, Coordination and Department setup. Each page shows tabs for the desks of its section, and every incident page shows the **context bar**: the incident's name and short code, complex membership, the current operational period in the incident's own time zone, the authority profile, an **EXERCISE** banner where it applies, and how fresh the incident's numbers are. + +The incident you pick on the **Incidents** page stays selected on every desk until you switch. + +## Exercises + +An activation marked as an exercise is labelled on every page and in every notice and workflow event (`incident.is_exercise`), and never notifies external participants or vendors unless your settings allow it. + +## Automations + +Incident Back Office raises workflow triggers for the events that matter — a period starts, a position is assigned, a request changes status, a resource is about to arrive or time out, a facility or budget line crosses its threshold, lodging runs short, a meal cutoff approaches, water runs low, a vendor's insurance is about to expire, and many more. Build [workflows](../workflows) on them to send messages, call webhooks or open tickets. Threshold triggers fire once when the condition starts and once (with `resolved = true`) when it ends. + +Protected values — personal phone numbers and addresses, medical and dietary needs, room numbers, personal rates, claim details, vendor tax and remittance data — never appear in workflow payloads, and are encrypted when your department uses [Advanced Data Protection](../data-protection). diff --git a/docs/web-app/incident-back-office/planning.md b/docs/web-app/incident-back-office/planning.md new file mode 100644 index 0000000..9257d55 --- /dev/null +++ b/docs/web-app/incident-back-office/planning.md @@ -0,0 +1,63 @@ +--- +sidebar_position: 3 +title: Planning and organization +--- + +# Planning and organization + +## Operational periods and the plan + +**Planning → Periods & plan** (permission *Manage incident periods*) lists the incident's operational periods in its own time zone. + +![Periods and plan](/img/web-app/incident-back-office/periods.png) + +- **New period** creates a period for the window you choose; the next window is suggested from the last period. +- **Start** makes a planned period current; the previous current period closes. The *Incident period started* trigger fires. +- **Copy forward** creates the next period with open objectives, organization nodes and running assignments copied; completed work never copies. +- **Freeze and approve** locks the period's plan inputs. +- **Assemble plan** (permission *Assemble IAP*) builds a plan version from the period's IAP records; **Approve plan** approves it, supersedes older versions, snapshots the weather block and fires *Incident plan approved*. + +Objectives and weather blocks are edited from the same desk. + +## Positions and teams + +**Department setup → Positions** holds your position catalog. **Add NIMS core / NWCG wildland / CICCS positions** adds the standard positions you do not have yet; it never changes positions you already have. Each position can list the qualifications it needs. + +![Position catalog](/img/web-app/incident-back-office/positions.png) + +**Department setup → Incident teams** holds standing incident management teams: rotations, slots and candidates. **Team readiness** computes, for a window you choose, whether each slot has a qualified candidate (nothing is stored). **Propose activation** lets you pick the candidate for each slot and activate the team into an incident in one step; a candidate already assigned elsewhere is reported as a conflict, never double-booked. When a team's readiness changes, the *Incident team readiness changed* trigger fires. + +![Incident team slots](/img/web-app/incident-back-office/teams.png) + +## Organization and assignments + +**Planning → Organization** holds the incident's organization nodes (sections, branches, divisions, groups, units) and position assignments. **Assign a position** (permission *Create incident position*): + +- checks the person's qualifications against the position's requirements before saving, using your enforcement mode; +- reports other open assignments that overlap for the same person; +- records trainee, acting, deputy and relief assignments, shift pattern and the operational period; +- fires *Incident position assigned* and notifies the person in their own language. + +![Assign a position](/img/web-app/incident-back-office/assign-position.png) + +Administrators can override a failed qualification check; the assignment is then recorded as *waived* with the note. **End assignment** closes an assignment at the current time, so "who held this position at 14:00 yesterday" always has an answer. + +## Participants, enrollment and check-in + +**Planning → Participants** holds everyone supported by the incident — members, mutual-aid personnel and contractors — with their agency, order and request numbers, payment class, expected arrival, lodging and meal needs. Personal phone, e-mail, address, date of birth and identifiers, and the emergency contact, medical, accessibility and dietary details on the separate sensitive record, are protected values: you see them only with *View participant sensitive data*. + +![Participants](/img/web-app/incident-back-office/participants.png) + +- **Enrollment queue** lists people and units dispatched to the linked call or placed on its command board who have no participant record yet. Enroll them in one step, or as drafts for review. Your enrollment policy decides whether the queue only suggests or drafts automatically, and the *Incident enrollment backlog* trigger fires when the queue grows past your limits. +- **Roster import** stages a CSV (header row; `DisplayName` required; `Agency`, `HomeUnit`, `PositionTitle`, `OrderNumber`, `RequestNumber`, `PaymentClass` and `ExpectedArrival` optional), shows every row with its problems, and commits only the valid rows. Importing the same roster twice skips rows already on the incident. +- **Snapshot qualifications** records the participant's certifications as they stand now. + +**Planning → Check-in** finds a participant by the code on their badge or confirmation (or from the list of people expected) and checks them in; *Incident participant checked in* fires. Resources (crews, equipment, aircraft, supplies), their components, movements, status history and assignment extensions are kept on the same desk. + +![Check-in](/img/web-app/incident-back-office/check-in.png) + +## Demobilization + +![Demobilization](/img/web-app/incident-back-office/demobilization.png) + +**Planning → Demobilization** holds demobilization plans. A new plan gets the standard checklist — role handoff, issued property, vehicle inspection, time and equipment posted, receipts and claims, lodging checkout, travel and evaluation — with the property, vehicle, time, receipt and lodging items **blocking**. Release is refused while a blocking item is open (the *Incident demob blocked* trigger fires a day ahead), and *Incident demob completed* fires when the plan reaches **Departed**. diff --git a/docs/web-app/incident-back-office/settings.md b/docs/web-app/incident-back-office/settings.md new file mode 100644 index 0000000..da04b2b --- /dev/null +++ b/docs/web-app/incident-back-office/settings.md @@ -0,0 +1,44 @@ +--- +sidebar_position: 7 +title: Settings +--- + +# Settings + +**Incident Back Office → Department setup → Settings** (department administrators) holds the module's department policies. Each policy is saved on its own; empty values use the defaults below. Every number is yours to set — nothing in the module hard-codes a threshold. + +![Incident Back Office settings](/img/web-app/incident-back-office/settings.png) + +| Policy | Settings (default) | +|---|---| +| General defaults | Snapshot staleness (15 minutes), default currency and measurement system for new incidents (from your country), operational period length (12 hours), exercises may notify external people (off). | +| Enrollment | Mode — off, suggest or auto-draft (suggest); count unenrolled people in a separate forecast band (on); backlog limits (25 people or 120 minutes). | +| Notice routing | The position codes that receive each notice (assignment, situation report, resources assigned, arrival update, lodging, demobilization, approvals, finance exceptions, claims, closeout, timeouts). The people holding those positions at send time are notified; with no holder, the section chief, then the administrators. | +| Forecasts and thresholds | Meal contingency (10 %), drinking water per person per day (7.5 L), water contingency (15 %), bed reserve (5 %), predicted timeouts reduce forecasts (off), replacement lead (3 days), arrival lead (120 minutes), timeout lead (3 days), meal cutoff lead (180 minutes), facility threshold (90 %), water days of supply (2). | +| Assignment length and work/rest | Rule pack, maximum assignment (14 days), travel days (2), maximum extension (7 days), maximum work hours per shift (16), rest per work hour (0.5). | +| Vendors and capacity holds | Verification interval (365 days), hold expiry (24 hours), compliance lead (30 days), hold lead (6 hours). | +| Self-service links | Link lifetime after the assignment (14 days), one-time code before lodging or travel is shown (on), vendor links only for verified vendor contacts (off). | +| Finance controls | Single-person operation (off; records who turned it on and when), extra intake sender domains, budget threshold (80 %), agreement ceiling threshold (85 %), daily burn threshold (none), intake backlog (50 items or 24 hours), claim deadline lead (7 days), recovery deadline lead (14 days), split-purchase window (3 days), micro-purchase threshold (10,000). | +| Retention | Snapshots after close (90 days), ledgers after close (7 years), self-service links after expiry (30 days). | +| Coordination boards | Default lane staleness (60 minutes), alarm on road closures (on), alarm on shelter capacity (on), share grant length (14 days), item due lead (60 minutes). | + +## Module switches + +**Department → Module Settings** has three switches: **Incident Back Office**, **Incident finance desks** and **Coordination boards**. They are on by default; turning one off hides its pages and stops its workers for your department without deleting anything. + +![Module settings](/img/web-app/incident-back-office/module-settings.png) + +## Background work + +| Worker | What it does | How often | +|---|---|---| +| 74 | Incremental snapshot of every open incident's numbers | Every minute | +| 75 | Full rebuild snapshot (flags drift) | Every 30 minutes | +| 52 | Meal demand forecasts for the next three days | Every 15 minutes | +| 53 | Vendor compliance expiry | Hourly | +| 54 | Capacity hold and lodging block expiry | Every 5 minutes | +| 55 | Evaluated triggers (arrivals, capacity, lodging, meals, water, budgets, time, timeouts, coordination items, backlogs, deadlines) | Every 2 minutes | +| 57 | Daily cost, accruals, projections and cost share | Daily | +| 58 | Snapshot retention after close | Daily | + +Workers never call billing; they skip departments whose module switch is off. diff --git a/docs/web-app/indoor-maps.md b/docs/web-app/indoor-maps.md index 15b0085..1ed7138 100644 --- a/docs/web-app/indoor-maps.md +++ b/docs/web-app/indoor-maps.md @@ -19,6 +19,8 @@ The older `/User/IndoorMaps/*` links still work — they redirect to the equival Read the full guide: [Custom Maps → Managing floors, Managing zones, Using custom maps in dispatch](custom-maps). + + ## Setup examples | Department | Use | diff --git a/docs/web-app/inventory.md b/docs/web-app/inventory.md index 803d457..e67c0e1 100644 --- a/docs/web-app/inventory.md +++ b/docs/web-app/inventory.md @@ -9,6 +9,8 @@ Inventory tracks **what your department owns, where it is kept and who is carryi ![Inventory on hand](/img/web-app/inventory/on-hand.png) + + ## Where to find it **Left menu → Inventory.** The workspace is a set of tabs; three related workspaces are reachable from the toolbar: diff --git a/docs/web-app/mapping.md b/docs/web-app/mapping.md index 31b1f10..951cab4 100644 --- a/docs/web-app/mapping.md +++ b/docs/web-app/mapping.md @@ -7,10 +7,12 @@ title: Mapping The **Mapping** page is the live operational map: every unit and person with a recent location, active calls, stations, hydrants, points of interest and your own map layers. Use it to see who is where, route a unit to a call, and keep reference layers (districts, water sources, staging areas) at hand. -**Left menu → Mapping.** Layers and points of interest are managed from the buttons on the map page; map behaviour (how long a location stays on the map) is under **Department Settings → Mapping**. +**Left menu → Mapping.** Layers and points of interest are managed from the buttons on the map page; map behaviour (how long a location stays on the map) is under **Department Settings → Mapping**. **Map Icon Legend** explains every pin and its colors ([below](#map-icon-legend)). ![Mapping](/img/web-app/mapping/index.png) + + ## Map View The main map view displays an interactive map centered on the department's configured location (GPS coordinates or geocoded department address). @@ -33,6 +35,60 @@ The `GetMapData` endpoint is the primary aggregation endpoint, supporting these Personnel location visibility is controlled by the `CanSeePersonnelLocations` permission. This is configurable per department in the Security settings. ::: +### Icons by status and priority + +Call, unit and personnel pins change with what they are doing, so the map can be read at a glance: + +![Call pins in the colors of their priorities, with labels hidden](/img/web-app/mapping/status-pins.png) + +- a **call** pin takes the color of its **priority**; +- a **unit** pin takes the color of its **status**; +- a **member's** pin takes the color of their **status**. A member *On Unit* takes the color of their unit's status. Staffing levels never change a pin. + +The color comes from the *meaning* of the status or priority, not its name, so built-in and [custom statuses](custom-statuses) and your own call priorities all land on the same colors: + +| Color | Statuses with these meanings | +|---|---| +| Green — *Available* | Available, Cleared, On Patrol, Completed, In Quarters | +| Amber — *Dispatched* | Dispatched | +| Red — *Responding* | Responding, En Route | +| Blue — *On scene* | On Scene, Made Contact, Investigating, At Patient, Searching | +| Purple — *Transporting* | Transporting, Delivering, Loading, At Hospital | +| Teal — *Returning* | Returning | +| Brown — *Staging and standby* | Staging, Standby | +| Slate — *On break* | On Break | +| Charcoal — *Unavailable* | Unavailable, Maintenance, Not Responding | +| Gray — *No meaning or no status* | A status with no meaning whose name suggests none; a unit or member that has set no status | + +![Status colors on the Map Icon Legend](/img/web-app/mapping/status-colors.png) + +Call priorities: **Low** green, **Medium** yellow, **High** orange, **Emergency** red. A status or priority with no meaning set takes the color its name suggests (a priority named *Emergency*, a status named *Out of Service*), the same suggestion the settings pages make; one whose name suggests nothing shows a **gray** pin, as does a unit or member that has set no status. Set meanings on the [Custom Statuses](custom-statuses) and Call Priorities pages to be sure. The guess only colors the pin: everything else still treats the option as having no meaning. + +The built-in pin keeps its picture (the fire, the ambulance, the person) and only its color changes. A type or role with a [custom icon](#custom-map-icons) shows that icon with a small colored badge in its lower right corner, unless an icon was uploaded for that exact status or priority ([status and priority icons](#status-and-priority-icons)). The map redraws a pin within a few seconds of a status or call change. + +## Map icon legend + +**Mapping → Map Icon Legend** shows every icon the map can show for your department, built from your own call types, priorities, unit types, status sets and roles: + +![Map Icon Legend](/img/web-app/mapping/map-icon-legend.png) + +| Section | Shows | +|---|---| +| **How an icon is picked** | The order: an icon uploaded for the exact priority or status, else the type's or role's own icon with a badge, else the built-in pin in the color of the priority or status. | +| **Status colors / Priority colors** | Each color, the meanings it covers, sample unit, person and call pins, and your own unit statuses, personnel statuses and priorities that show in that color. A status or priority listed under gray has no meaning set. | +| **Calls** | One row per call type (and calls with no type), one column per priority. | +| **Units** | One row per unit type (and units with no type) with every status of the type's status set, or the built-in unit statuses. | +| **Personnel** | Members with no role icon, then every role with an icon, in role order, across the department's personnel statuses. | +| **Stations, hydrants and points of interest** | Icons that do not change with status. | + +Hover over an icon to see whether it is an icon uploaded for that status or priority, a type icon with a badge, or a built-in pin. Department administrators get an **Edit icons** button on each call type, unit type and role row, which opens its [status or priority icons](#status-and-priority-icons) page. The legend is open to every member who can open the map. + +Nothing on the legend is fixed: the names are your own call types, priorities, unit types, status sets, statuses and roles, and the icons are what the map draws for them, including the built-in icon a type picked and every uploaded icon. Rename a priority, add a custom status, give a unit type another built-in icon or upload an icon, and the legend shows it the next time it is opened. + +The built-in personnel status **On Unit** is not listed under any color: a member On Unit takes the color of their unit's status, and shows the gray pin only when there is no unit status to follow. Hover its icon on the legend to see this. + +The Responder, Unit and IC apps show the same legend from the **legend** button on their maps ([in the apps](#in-the-apps)); app developers can read it from the [Map Icons API](../api/map-icons). + ## Map Layers Map layers provide custom GeoJSON overlays on the map. @@ -62,7 +118,9 @@ Layers are **soft-deleted** (`IsDeleted = true`) rather than permanently removed ![Points of interest](/img/web-app/mapping/pois.png) -Create categories for points of interest with custom markers and images. +Create categories for points of interest with custom markers and images. A POI type can also have its own [custom icon](#custom-map-icons), set when you add the type or on its **View** page (Information tab); it replaces the marker on the map and in the apps. + +![POI type custom icon](/img/web-app/mapping/poi-type-icon.png) ### Individual POIs @@ -97,20 +155,220 @@ Custom Maps allow departments to upload building floor plans, venue layouts, sch On the main map view, use the **Custom Maps** layer control (alongside Layers, POIs, and Geofences) to toggle custom map overlays. When one or more custom maps are enabled, a **Building Selector** sidebar appears for switching between maps and floors. +## Custom map icons + +Departments can replace the built-in map icons with their own images, so an ambulance, a MUG, a PIT, a first responder car and a bicycle team are told apart at a glance instead of by reading names. Icons can be set for: + +| What | Where you set it | Where the icon shows | +|---|---|---| +| **Unit types** | **Department → Types → Unit Types**, new or edit | Beside units of the type in the Units list, the dispatch dashboard unit grid, New Call and View Call, the Types table, and on unit pins on the map; in the apps' unit lists and pickers and on their map pins | +| **Call types** | **Department → Types → Call Types**, new or edit | Beside the call type in the active and archived call grids and the Types table, and on call pins on the map; in the apps' call cards and call screens and on their map pins | +| **POI types** | **Mapping → Points of Interest**: on **Add POI Type**, or the type's **View** page (Information tab) | On every point of interest of the type on the map, and in the apps' POI lists and map pins | +| **Personnel roles** | **Personnel → Manage Roles**: **Add Role** or **Edit** | On the map pin of each member, by [role order](#personnel-role-icons-and-role-order); beside the role on the Roles page; on personnel cards in the apps | + +A type or role without its own icon keeps what it showed before: the built-in map icon chosen on the type, the POI marker, or the standard person pin. + +### Choosing an image + +The picker lists these rules next to the file input: + +| Rule | Detail | +|---|---| +| Format | PNG, JPEG, GIF or WebP. SVG is not accepted, and an animated GIF uses its first frame | +| File size | Up to 1 MB | +| Dimensions | At least 16 px on the longest edge and at most 4096 px on each edge. A square image of 128 × 128 px or larger looks sharpest | +| Background | Transparent. An image with an opaque background shows as a filled square on the map | +| Design | A bold, simple shape. The map draws the icon at 32 × 32 px and lists at 20 × 20 px, so fine detail and text will not be readable | +| What is stored | Every icon is resized to 128 × 128 px and saved as PNG, with the file's metadata removed. An image that is not square is centered on a transparent square; nothing is cropped | + +### Preview and checks + +As soon as you choose a file, the page checks it and shows a preview of the stored image on a light map and a dark map (with the name label the map shows under a pin), in a list row, and as the saved 128 × 128 image. The previews use the name typed on the form. + +![Custom icon preview](/img/web-app/types/custom-icon-preview.png) + +Some files are accepted with a warning, so you can decide whether to use a better image: + +- the image is smaller than 128 × 128 px and will be enlarged (it may look blurry); +- the image is not square and will be centered on a transparent square; +- the image has no transparent background and will show as a filled square. + +![Warnings for a small, wide, opaque image](/img/web-app/types/custom-icon-warnings.png) + +A file that cannot be used is refused before anything is uploaded, the file input is cleared and the reason is shown under it. The server repeats the same checks when the form is saved, so a file that gets past the browser is still refused with the same message. + +![A refused file](/img/web-app/types/custom-icon-rejected.png) + +| Message | Cause | +|---|---| +| Only PNG, JPEG, GIF and WebP images can be used as icons. | Any other file type, including SVG, BMP, TIFF and HEIC | +| The icon file must be 1 MB or smaller. | The file is over 1 MB (the size of the chosen file is shown) | +| The icon must be at least 16 px on its longest edge. | The image is too small (its size is shown) | +| The icon must be 4096 px or smaller on each edge. | The image is too large (its size is shown) | +| The file could not be read as a PNG, JPEG, GIF or WebP image. | A damaged file, or one whose contents do not match its name | + +The icon is saved together with the rest of the form. Before you save, the preview says *Showing the new icon*; after saving, the edit page shows the current icon and a **Remove the custom icon** box. Ticking it and saving removes the icon, and the type or role goes back to its default. Choosing a new file replaces the old icon. + +### Personnel role icons and role order + +A person can hold several roles, so their map pin uses the icon of **the first role they hold, in the department's role order, that has an icon**. People whose roles have no icon keep the standard person pin. + +Set the order on **Personnel → Manage Roles**: drag the rows, or use the up and down arrows, then click **Save order**. Only department administrators see the order controls. Until a department saves an order, roles are listed by name and that is the order used. A role added after the order was saved goes to the end. + +![Roles with icons and order controls](/img/web-app/personnel/roles.png) + +For example, with the order *Officer*, *Paramedic*, *Firefighter*, where Officer and Paramedic have icons: + +| Member's roles | Map pin | +|---|---| +| Officer, Firefighter | Officer icon | +| Paramedic, Firefighter | Paramedic icon | +| Officer, Paramedic | Officer icon (Officer is first) | +| Firefighter | Standard person pin (Firefighter has no icon) | + +See [Personnel Roles](../configuration/personnel-roles#role-order-and-map-icons). + +### Status and priority icons + +A call type can also have an icon for each **priority**, and a unit type or role an icon for each **status**. While that priority or status holds, the map shows it instead of the type's own icon. Use them when a color alone is not enough, for example an ambulance drawn with its lights on while transporting. + +![The Status map icons button on Edit Unit Type](/img/web-app/types/status-map-icons-link.png) + +Open **Department → Types**, edit a unit type or call type and choose **Status map icons** or **Priority map icons**; for a role, **Personnel → Manage Roles → Edit → Status map icons**. The **Edit icons** buttons on the [Map Icon Legend](#map-icon-legend) open the same page. + +The page lists the type's statuses (the options of the unit type's status set, the built-in unit statuses, or the department's personnel statuses for a role) or the department's priorities, with: + +| Column | Shows | +|---|---| +| **Status** / **Priority** | The option and its own color. | +| **Map color** | The color its meaning gives, or *No meaning or no status* (gray). | +| **Default** | What shows without an upload: the type's own icon with the badge of that color, or the built-in pin in that color. | +| **Uploaded icon** | The icon uploaded for it, if any. | + +![Status map icons of a unit type, with an icon uploaded for Enroute](/img/web-app/mapping/status-icons.png) + +Choose a file and press **Upload** on a row; **Remove** returns that row to the default. The same [image rules](#choosing-an-image) apply. Removing or replacing the type's own icon keeps its status and priority icons; deleting the type removes them all. An icon is tied to the option it was uploaded for: when a unit type moves to another status set, upload icons for the new set's options. + +Unit and call type icons need the permission to edit department types, as on the Types pages; role icons need the permission to edit roles. + +### In the apps + +The Unit, Responder, IC, Dispatch and BigBoard apps draw the same pins as the web map: uploaded icons, status and priority icons, badges, and the built-in pins in the color of the status or priority, on phones and tablets, in the browser and in the desktop (Electron) apps, at the same 32 × 32 px as the web map. If an icon cannot be loaded, the pin falls back to its built-in image. Older app versions keep showing the plain built-in pins and any uploaded status or priority icons. + +The Responder, Unit and IC apps also have the [map icon legend](#map-icon-legend). Tap the round **legend** button (an *i*) on the map to open it as a sheet over the map: + +| App | Where the legend button is | +|---|---| +| Responder | Top right of the Map tab | +| Unit | Bottom right of the main map, above the recenter button | +| IC | Bottom right of the main map, above the layers button, and bottom right of an incident's command map | + +The sheet has the same sections as the web page (status and priority colors with your own statuses and priorities, calls, units, personnel, stations and points of interest), draws every icon exactly as that app's map does, and loads fresh each time it is opened, so it follows any change to your types, statuses, priorities or icons. The Calls, Units and Personnel headings use your [terminology](department-settings#terminology) when you have renamed those modules. A few things follow what the app's map shows: + +- In Responder, members who can't see personal information don't see personnel pins on the map, so their legend leaves out the Personnel section too. +- Hydrants are listed only while the map is showing hydrants. The apps draw hydrants with a generic pin, on the map and in the legend. +- On IC's command map the legend is the whole department's, although that map shows only the incident's resources. Unit and call type icons also show in the apps' unit lists, pickers and call cards, and the Responder, IC and Dispatch personnel lists show each person's role icon. In Dispatch, role icons also show beside each role and person in the dispatch recipient picker and on the role chips of a person's screen. Icons are served from the Resgrid API with a long cache lifetime, so after the first load they show even on a slow connection. + +### Technical reference for custom icons + +| Item | Value | +|---|---| +| Storage | `TypeIcons` (M0285): one row per type or role, `TypeKind` 1 unit type, 2 call type, 3 POI type, 4 personnel role (M0286); the PNG bytes, size and checksum. `IconKey` (an unguessable 32-character key) is copied to `UnitTypes`, `CallTypes`, `POITypes` and `PersonnelRoles`. No foreign keys: type and role deletes and the department purge remove the rows | +| Status and priority icons | `TypeIcons.Variant` (M0289): null for the type's own icon, `p{priority}` on a call type, `s{built-in status}` or `o{custom status option id}` on a unit type or role. Pages `GET /User/Mapping/StatusIcons?kind=&typeId=`, `POST UploadStatusIcon` / `RemoveStatusIcon`; the department's slots are cached and cleared on every change | +| Icon choice | `MapIconResolver` (shared by the v4 map, the legend and the icon pages): the upload for the exact priority or status, else the own icon with a badge, else the built-in pin in the style of the meaning (`MapIconStyles`) | +| Styled pins and badges | Drawn by the server from the built-in artwork: web `GET /TypeIcons/Pins/{base}-{style}`, API `GET /api/v4/TypeIcons/Pins/{base}-{style}` (32 × 37 PNG); a badge is `?s={style}` on an icon URL. Both carry `v=` (the palette version) and are cached for a year | +| Role order | `PersonnelRoles.SortOrder` (M0286, default 0); ties order by name. Saved by `POST /User/Personnel/SetRoleOrder` (department admins, `Role_Update`) through `IPersonnelRolesService.SetRoleOrderAsync`; ids from another department are ignored | +| Icon URLs | Web `GET /TypeIcons/{key}`, API `GET /api/v4/TypeIcons/{key}`: anonymous, `Cache-Control: public, max-age=31536000, immutable`, `ETag`. Every upload gets a new key, so a changed icon gets a new URL | +| Upload rules | `TypeIconRenditions`: PNG, JPEG, GIF (first frame) or WebP; ≤ 1 MB (checked before the file is read); 16 to 4096 px (from the header, before decoding); resized to 128 × 128 on a transparent canvas and re-encoded as PNG without metadata. Rejections are `TypeIconRejections` values with localized messages | +| Pages | Unit and call type new/edit (`TypesController`), POI type add and `SetPOITypeIcon` (`MappingController`), role add/edit and Roles (`PersonnelController`); shared partial `_TypeIconPicker`, scripts `resgrid.types.iconpicker.js` and `resgrid.personnel.roleorder.js` | +| v4 API | `IconUrl` on map markers (`GetMapDataAndMarkers` and `GetUnitMapData`: calls 0, units 1, personnel 3, POIs 4), plus `PinIconUrl` (the styled built-in pin) and `IconStyle` (`available` … `unavailable`, `low` … `emergency`, `unknown`) on call, unit and personnel markers; `ImagePath` stays the plain built-in icon for older apps; `IconUrl` also on call types, POI types, POIs and POI layers; `TypeIconUrl` / `TypeMapIcon` on units, unit statuses, calls, call dispatches and recipients (unit rows; role rows carry the role's icon as `TypeIconUrl`); `RoleIconUrl` on personnel; `IconUrl` and `SortOrder` on roles. `GET /api/v4/Mapping/GetMapIconLegend` returns the legend for the apps: status and priority styles (color, pin URLs, the department's statuses and priorities in each), call, unit and personnel rows (the "none" row first, `Id` null) with each priority's or status's `IconUrl` / `PinIconUrl` / `ImagePath` / `IconStyle` (and `FollowsUnitStatus` on the built-in On Unit status), and the POI types. The web page and the API are built from the same `MapIconLegendBuilder`. See the [Map Icons API](../api/map-icons) | +| Admin Assist | Capabilities *Custom map icons* and *Map icon legend* (mapping area), plus the unit types, call types, POIs and personnel roles entries | + +## Map visualizations + +**Mapping → Visualizations** turns your call history, responses and unit movement into map overlays: call heat maps ("where are our hot zones?"), counts per area, response times by area, calls far from a station, where units and members went, and recorded paths. Start from the built-in library, adjust it, and save your own versions. + + + +**Where to find it:** the **Visualizations** button at the top of the Mapping page, or search "heat map" in the omnibar. Anyone who can view calls can open it. + +### The library + +The library lists ready-made visualizations. Those that match your [operating profile](help-setup#operating-profile) (its sectors, and a volunteer or combination workforce) are shown first; every visualization stays available to every department, and **Show all** lists every one by category. + +| Category | Visualizations | +|---|---| +| **Call demand** | Call hot zones (heat map, 12 months) · Busiest areas (hexagon grid with counts) · Calls by type · Main call type by area · Calls by priority · Call outcomes · Time of day · Weekday vs weekend · Seasonal patterns | +| **Response performance** | Response time by area (90th percentile) · Response time bands · Time to first responding by area · Time committed by area | +| **Coverage** | Calls outside station coverage (distance bands and 1.5 / 2.5 / 5 mile rings) · Workload by station area · Where responders come from | +| **Units and personnel** | Where units go · Demand by unit type · Personnel response footprint | +| **Community risk** | Repeat locations (3+ calls at the same place) · False alarm hot spots | +| **Tracking** | Unit movement (last 24 hours) · Patrol coverage · Search coverage · Incident footprint (one call: paths, status positions and where responders came from) | + +Click a dot to see the call and open it, or **Show this call's footprint** to switch to the Incident footprint for that call. + +### Customizing + +The **Customize** tab changes what the map shows. The map updates as you edit. + +- **When:** a rolling window (last 24 hours to last 5 years) or fixed dates, plus days of the week and hours of the day (in your department's time zone). +- **Which calls:** call types, priorities, outcomes, home station or group, units involved, and a minimum number of calls at the same location. Or pick **one call** to show only that call. +- **Layers** (up to 6, drawn in order): each layer has its **data** (calls, unit responses, personnel responses, responder origins, unit status positions, unit paths, personnel paths), how to **show** it (heat map, dots, hexagon grid, paths), what to **color by** (call type, priority, outcome, home station, time of day, hour, day, weekday or weekend, month, year, unit, unit type, unit's station, person, status, response time band, distance band, repeat count) and a **measure** (count, minutes to first on scene, minutes to first responding, minutes until closed, units dispatched, personnel responded, distance to station, calls at the location). A hexagon grid combines its cells' values with a count, total, average, median, 90th percentile or maximum; colored by a category, each cell shows its most common category. Colors, opacity, heat radius and intensity, cell size and dot size are set per layer. +- **Stations and distances:** show stations, draw coverage rings, choose kilometers or miles, and set the distance and response time bands. + +Below the map: calls in view, how many have a location, median and 90th-percentile time to on scene (when a layer uses response times), a weekday-by-hour chart and the most common call types. **Download CSV** exports the visible layers' points and paths. + +### Saving and sharing + +**Save as new** keeps the current visualization in **My visualizations**, visible only to you. Department admins can tick **Share with the whole department** so it appears under **Shared with the department** for everyone who can view calls; only department admins can change or delete a shared visualization. **Copy link** copies a link that opens the saved visualization (or library entry) directly. + +Only the settings are saved, never the data. Each person who opens a visualization sees it with their own permissions: calls outside their dispatch scope, and members or units whose locations they may not see, are left out (the page says so). + +### What the numbers mean + +- **Response time** is from the call being logged to the first unit setting an on-scene status (custom statuses count through their base type). **First responding** is the first responding or en route status. Calls with no such status are left out of the times. Times over 24 hours are treated as bad data. +- **Distance to station** is straight-line distance to the nearest station with a location (a unit response uses the unit's own station). Rings are straight lines too, not drive times. +- **Repeat locations** group calls within about 11 m of each other. +- **Home station** follows the call summary rules: the station geofence containing the call, otherwise the station that most of the dispatched units and members belong to. + +### Limits + +| Limit | Value | +|---|---| +| Longest date range | About 5 years | +| Calls read for one view | 100,000 (the newest; the page says when more matched) | +| Points per layer | 75,000 | +| Paths | At most 7 days; for one call, from 15 minutes before it was logged to 15 minutes after it closed | +| Status positions and responder origins | At most the last 12 months of the range | +| Saved visualizations | 250 per department | + +### Technical reference for visualizations + +| Item | Value | +|---|---| +| Page | `MapVisualizationsController` (`/User/MapVisualizations`, `Call_View`); query `?id=`, `?template=`, `?callId=`. React element `rg-map-visualizer` (Leaflet, canvas heat and dot layers, client-side hexagon binning) | +| Endpoints | `GET Bootstrap`, `POST Data` (runs a definition), `POST Save`, `POST Delete`, `GET CallDetail`, `GET SearchCalls`; writes need the anti-forgery header | +| Storage | `MapVisualizations` (M0288): name, description, `DefinitionJson`, `TemplateKey`, `IsShared`, creator and updater. No foreign keys; removed by the department purge | +| Definition | `MapVisualizationDefinition` (filters, layers, options) with stable string keys in `MapVisualizationKeys`; `MapVisualizationDefinitionValidator` clamps and repairs every definition on read and save | +| Library | `MapVisualizationLibrary` (25 templates; recommended by operating profile archetype and workforce, never by organization type) | +| Data | `IMapVisualizationService.RunAsync`: thin call read, `ICallGroupAssignmentService` for home stations, `ICallStatusAttributionService` and `CallUnitTimesCalculator` for unit and personnel times (in slices of at most a year and 2,500 calls), unit status history, action logs, and unit and personnel location history (document database; indexes `ix_unitlocations_department_timestamp`, `ix_personnellocations_department_timestamp`) | +| Visibility | `IDispatchScopeService` for calls; `CanUserView{Unit,Person}ViaMatrixAsync` and the location variants for units, members and their locations | +| Admin Assist | Capability *Map visualizations* (mapping area) | + ## Setup examples | Department type | How to set it up | |---|---| -| **Fire** | POI types: Hydrants (or use the Records hydrant layer), Knox boxes, Dry hydrants/draft sites, Staging areas; layers: district boundaries (KML from the county GIS), water main map. | -| **EMS** | POI types: Hospitals (with ED phone numbers in the description), Landing zones, Nursing homes; destinations on calls point at hospital POIs. | -| **SAR** | Layers: trail systems, search segments (GeoJSON from CalTopo/SARTopo), cell coverage; POI types: trailheads, huts, helispots. Location TTL 240+ minutes. | -| **Emergency management** | Layers: flood zones, evacuation zones, shelters; POI types: shelters, PODs, fuel sites, sandbag stations. | -| **Security** | POI types: Client sites, Gates, Cameras; personnel location TTL 15 minutes so stale markers drop. | +| **Fire** | POI types: Hydrants (or use the Records hydrant layer), Knox boxes, Dry hydrants/draft sites, Staging areas; layers: district boundaries (KML from the county GIS), water main map. Visualizations: Call hot zones and Response time by area for standards-of-cover reviews; Calls outside station coverage with 1.5 / 2.5 / 5 mile rings; Weekday vs weekend and Where responders come from for volunteer staffing; share them with the department. | +| **EMS** | POI types: Hospitals (with ED phone numbers in the description), Landing zones, Nursing homes; destinations on calls point at hospital POIs. Custom icons for unit types such as Ambulance, MUG, PIT, First Responder and Bicycle Team, and for roles such as Paramedic and Nurse, with Paramedic ordered above EMT so a paramedic's pin shows the paramedic icon. Visualizations: Response time bands (set the bands to your contract times), Repeat locations for frequent-caller and community paramedicine follow-up, Time committed by area. | +| **SAR** | Layers: trail systems, search segments (GeoJSON from CalTopo/SARTopo), cell coverage; POI types: trailheads, huts, helispots. Location TTL 240+ minutes. Visualizations: Search coverage over the mission window and the Incident footprint of the search call. | +| **Emergency management** | Layers: flood zones, evacuation zones, shelters; POI types: shelters, PODs, fuel sites, sandbag stations. Visualizations: Seasonal patterns, and Call hot zones filtered to weather call types. | +| **Security** | POI types: Client sites, Gates, Cameras; personnel location TTL 15 minutes so stale markers drop. Visualizations: Patrol coverage (7-day unit position heat map) and Repeat locations for problem sites. | | **Delivery / transit** | Depots and customer sites as POIs; routes drawn with the Routes module; vehicle trackers for live positions. | ## Technical reference -`MappingController`; routes `/User/Mapping/{Index,Layers,NewLayer,EditLayer,POIs,AddPOIType,AddPOI,EditPOI,ImportPOIs,LiveRouting,StationRouting}`; data via `api/v4/Mapping/GetMapDataAndMarkers` and `GetMayLayers` (web component `rg-map`). Permissions `CanSeePersonnelLocations`, `CanSeeUnitLocations` (group-lockable). Map provider (Mapbox / Leaflet-OSM / Google) is an installation setting. +`MappingController`; routes `/User/Mapping/{Index,Layers,NewLayer,EditLayer,POIs,AddPOIType,AddPOI,EditPOI,ImportPOIs,LiveRouting,StationRouting}`; data via `api/v4/Mapping/GetMapDataAndMarkers` and `GetMayLayers` (web component `rg-map`). Visualizations: see [Map visualizations](#map-visualizations). Permissions `CanSeePersonnelLocations`, `CanSeeUnitLocations` (group-lockable). Map provider (Mapbox / Leaflet-OSM / Google) is an installation setting; the department picks its Mapbox base map style (day and night) under [Mapping & Big Board settings](department-settings#mapping--big-board-settings). ### Data Endpoints | Endpoint | Purpose | @@ -128,5 +386,5 @@ On the main map view, use the **Custom Maps** layer control (alongside Layers, P | **Units** | Unit positions shown (from GPS tracking); zone-entry notifications triggered | | **Personnel** | Personnel locations shown (permission-controlled); plotted on indoor floors when positioning data available | | **Department** | Map center, zoom, and refresh settings | -| **Security** | Personnel location visibility permission | +| **Security** | Personnel location visibility permission Visualizations: Patrol coverage (7-day unit position heat map) and Repeat locations for problem sites. | | **Custom Maps** | Uploaded floor plans and zone overlays; see [Custom Maps](custom-maps) | diff --git a/docs/web-app/messages.md b/docs/web-app/messages.md index 47b97d9..f5180a5 100644 --- a/docs/web-app/messages.md +++ b/docs/web-app/messages.md @@ -11,6 +11,8 @@ title: Messages ![Inbox](/img/web-app/messages/inbox.png) + + ## Inbox **Authorization:** `Messages_View` policy diff --git a/docs/web-app/navigation.md b/docs/web-app/navigation.md index aab9e22..95e1fbc 100644 --- a/docs/web-app/navigation.md +++ b/docs/web-app/navigation.md @@ -11,7 +11,7 @@ title: Navigation | Region | What is there | |---|---| -| **Left sidebar** | The modules: Home, Calls, Personnel, Units, Contacts, Mapping, Shifts, **Records** (a collapsible group, or Logs), Reports, Documents, Calendar, Notes, Trainings, Inventory, **Readiness** (Work Orders, Checklists) and **Workforce & Business Ops** (Workforce, Certifications, Invoicing, Deployment Finance, Bids, Contracts, Cal OES MARS). Groups expand in place; modules that are switched off or that you lack permission for are hidden. Collapse the sidebar with the hamburger icon on small screens. | +| **Left sidebar** | The modules: Home, Calls, Personnel, Units, Contacts, Mapping, Shifts, **Records** (a collapsible group, or Logs), Reports, Documents, Calendar, Notes, Trainings, Inventory, **Readiness** (Work Orders, Checklists) and **Workforce & Business Ops** (Workforce, Certifications, Invoicing, Deployments, Bids, Contracts, Cal OES MARS). Groups expand in place; modules that are switched off or that you lack permission for are hidden. Collapse the sidebar with the hamburger icon on small screens. | | **Your name (top-left)** | Profile menu: **Profile** (edit your details, contact methods, notification preferences), **Mailbox**, **Chat**, **Your Departments** (switch between departments you belong to), **Two-Factor Authentication**, **Logout**. | | **Top bar** | Unread **messages** and **active calls** icons, the **search box**, the **Department menu**, **Help**, language flag and logout. | | **Department menu (department name, top-right)** | Everything an administrator configures — see below. | @@ -50,7 +50,7 @@ Only administrators (and group administrators for a few items) see this menu. ## Search -The search box finds calls, personnel, units, contacts, notes, documents, records, invoices, bids, contracts, deployments and pages by name or number. Type at least two characters; results open in place. Records narrative search is included when your department's search index allows it. +The search box in the top bar finds calls (and their notes), people, units, contacts, occupancies, messages, notes, documents, deployments, invoices and more by name, number, address or text, and offers **Go to** shortcuts to pages and actions (*New Call*, *Add Person* …). Press **Enter** or pick **Search all results** for the full [Search](search) page, with type and date filters, Records reports and CSV export. ![Search results](/img/web-app/home/search-results.png) diff --git a/docs/web-app/notes.md b/docs/web-app/notes.md index 3618e91..b22ed56 100644 --- a/docs/web-app/notes.md +++ b/docs/web-app/notes.md @@ -11,6 +11,8 @@ title: Notes ![Notes](/img/web-app/notes/index.png) + + ## Note List Displays all notes for the department. diff --git a/docs/web-app/notifications.md b/docs/web-app/notifications.md index c6f2d45..b8818d6 100644 --- a/docs/web-app/notifications.md +++ b/docs/web-app/notifications.md @@ -11,6 +11,8 @@ title: Notifications ![Notifications](/img/web-app/notifications/index.png) + + ## Notification List Displays all configured notification rules with resolved human-readable descriptions of: @@ -53,6 +55,18 @@ Notifications can target: When creating a notification, the system captures the current state of relevant resources (staffing levels, unit states) for comparison when evaluating triggers. + + +### Matching statuses by meaning + +Rules on a personnel status, staffing level or unit status change, and the *current states* an availability alert counts, can pick a specific status or a **meaning**. The meanings are listed after your statuses as *Any "On Scene" status*, *Any "Off Duty" status* and so on. A meaning matches every status with that [meaning](custom-statuses#status-meanings), built-in or your own, in every status set. One rule then covers unit types with different custom statuses, and keeps working when you rename a status or add one with the same meaning. A status with no meaning only matches a rule that names it. + +| Rule | Pick | +|---|---| +| Tell the chief when any unit goes out of service | Unit status changed to *Any "Unavailable" status* (and *Any "Maintenance" status*) | +| Count available engines whatever their set calls it | Current states *Any "Available" status* and *Any "In Quarters" status* | +| Watch members going off duty | Staffing changed to *Any "Off Duty" status* | + ## Deleting Notifications Removes a notification rule by ID. @@ -78,7 +92,7 @@ The notification list performs extensive resolution to display human-readable in ## Technical reference -`NotificationsController`; routes `/User/Notifications/{Index,New,Delete}`; model `DepartmentNotification` (event type, threshold, target group/role/users, channels); evaluated by the notification worker on status/staffing/unit/inventory/checklist events. +`NotificationsController`; routes `/User/Notifications/{Index,New,Delete}`; model `DepartmentNotification` (event type, threshold, target group/role/users, channels); evaluated by the notification worker on status/staffing/unit/inventory/checklist events. Status values in a rule (`BeforeData`, `CurrentData`) are tokens (`StatusMatch`): a status value, `b` + a base type for a meaning (e.g. `b20` Maintenance), or `-1` for any; the editor loads them from the Custom Statuses JSON endpoints with `includeMeanings=true`. ### Interactions with Other Modules | Module | Interaction | diff --git a/docs/web-app/overview.md b/docs/web-app/overview.md index d80b149..5cf2e86 100644 --- a/docs/web-app/overview.md +++ b/docs/web-app/overview.md @@ -11,6 +11,8 @@ The four mobile apps — **Responder**, **Unit**, **Dispatch** and **Incident Co ![Dashboard](/img/web-app/home/dashboard.png) + + ## A map of the modules | Area | Modules | Start here | @@ -19,7 +21,7 @@ The four mobile apps — **Responder**, **Unit**, **Dispatch** and **Incident Co | **People & apparatus** | [Personnel](personnel) · [Units](units) · [Hardware GPS Tracking](unit-tracking) · [Groups & Stations](groups-stations) · [Custom Statuses](custom-statuses) · [Contacts](contacts) · [Shifts](shifts) · [Workshifts](workshifts) · [Calendar](calendar) | *Personnel* | | **Records & reporting** | [Records (RMS)](records/overview) · [Logs (legacy)](logs) · [Reports](reports) · [Documents](documents) · [Notes](notes) · [Trainings](trainings) | *Records overview* | | **Readiness & logistics** | [Checklists](checklists) · [Work Orders](work-orders) · [Inventory](inventory) · [Resource Orders](resource-orders) · [Communication Tests](communication-tests) | *Checklists* | -| **Workforce & Business Ops** | [Overview](business-ops/overview) · [Invoicing](business-ops/invoicing) · [Online Payments](business-ops/online-payments) · [Certifications](business-ops/certifications) · [Deployment Finance](business-ops/deployment-finance) · [Rate Schedules](business-ops/rate-schedules) · [Contracts & Compliance](business-ops/contracts-and-compliance) · [Bids & Deployment Wizard](business-ops/bids-and-deployment-wizard) · [Contractor Billing](business-ops/contractor-billing) · [Cal OES MARS](business-ops/cal-oes-mars) · [Workforce](business-ops/workforce) · [Field Costing](business-ops/field-costing) · [Pay Data Reporting](business-ops/pay-data-reporting) | *Business Ops overview* | +| **Workforce & Business Ops** | [Overview](business-ops/overview) · [Invoicing](business-ops/invoicing) · [Online Payments](business-ops/online-payments) · [Certifications](business-ops/certifications) · [Deployments](business-ops/deployment-finance) · [Rate Schedules](business-ops/rate-schedules) · [Contracts & Compliance](business-ops/contracts-and-compliance) · [Bids & Deployment Wizard](business-ops/bids-and-deployment-wizard) · [Contractor Billing](business-ops/contractor-billing) · [Cal OES MARS](business-ops/cal-oes-mars) · [Workforce](business-ops/workforce) · [Field Costing](business-ops/field-costing) · [Pay Data Reporting](business-ops/pay-data-reporting) | *Business Ops overview* | | **Communication** | [Messages](messages) · [Chat](chat) · [Notifications](notifications) · [Distribution Lists](distribution-lists) · [Connect](connect) | *Messages* | | **Configuration** | [Department Settings](department-settings) · [Types & Configuration](types-configuration) · [Templates](templates) · [Protocols](protocols) · [Forms](forms) · [User Defined Fields](user-defined-fields) · [Workflows](workflows) · [Command Definitions](command-definitions) · [Department Links](department-links) · [Call Check-in Timers](call-checkin-timers) | *Department Settings* | | **Security & account** | [Security & Permissions](security-permissions) · [Advanced Data Protection](data-protection) · [Account Security](account-security) · [Profile & Account](profile-account) · [Subscription & Billing](subscription-billing) · [Help & Setup](help-setup) | *Security & Permissions* | diff --git a/docs/web-app/personnel.md b/docs/web-app/personnel.md index bfeee1a..f52f4d8 100644 --- a/docs/web-app/personnel.md +++ b/docs/web-app/personnel.md @@ -9,6 +9,8 @@ The **Personnel** page is your roster: every member of the department with their ![Personnel](/img/web-app/personnel/index.png) + + ## Where to find it **Left menu → Personnel.** The page lists members grouped by station/group (or sorted by first/last name — see *Department Settings → Sorting*). Use the group tree on the left to filter, the search box to find someone, and the checkboxes to **set status** or **set staffing** for several people at once. @@ -37,6 +39,10 @@ Two ways: New accounts start with every contact method **pending verification**; the member verifies email and phone from their profile before dispatches and messages are sent to those channels ([contact verification](../configuration/contact-verification)). Adding is blocked when the plan's personnel limit is reached. +:::tip Have a spreadsheet? +To bring in a whole roster at once — from a spreadsheet or the system you are leaving — use [Import & Migration](import-and-migration/overview) (**Department menu → Import & Migration**, department administrators, where it is turned on). Every row is checked before anything is saved, and imported people stay dormant until you invite them. See the [People field reference](import-and-migration/people). +::: + ## Viewing and editing a person **View** shows the profile, group, roles, department flags (admin, disabled, hidden), current staffing and status, [certifications](business-ops/certifications) (with expiry, verification and credits), events and — where enabled — the equipment issued to them. **Edit** (or the person's profile page) changes: @@ -69,7 +75,8 @@ From the personnel list (or the [Dashboard](dashboard)) you can set a member's * ![Roles](/img/web-app/personnel/roles.png) -- **Add Role** — name, description and initial members. +- **Add Role** — name, description, initial members and an optional [map icon](mapping#personnel-role-icons-and-role-order). +- **Role order** — department administrators drag the rows or use the arrows and click **Save order**. A person's map pin uses the icon of the first role they hold, in this order, that has one. - **Edit / View Role** — members in role; **Delete** removes the role (assignments are dropped). - **Required certifications** — which [certification](business-ops/certifications) types a member must hold for the role, with any-of groups and a grace period; enforcement (off / warn / enforce) is set under Certifications → Settings. diff --git a/docs/web-app/protected-workflows.md b/docs/web-app/protected-workflows.md index aabee3d..46f6244 100644 --- a/docs/web-app/protected-workflows.md +++ b/docs/web-app/protected-workflows.md @@ -15,6 +15,8 @@ Typical use: a behavioral health agency writes crisis-call outcomes back to its Protected Workflows send decrypted protected data, which may include protected health information, to external systems you configure. Resgrid cannot control how the receiving system stores or uses this data. Only enable a workflow if the recipient is your organization or a party covered by a business associate agreement with your organization, and only release the fields the recipient needs. ::: + + ## Before you start - ADP must be **Enabled** (or Rotating) for your department. diff --git a/docs/web-app/protocols.md b/docs/web-app/protocols.md index 701ee59..604d37a 100644 --- a/docs/web-app/protocols.md +++ b/docs/web-app/protocols.md @@ -9,6 +9,8 @@ Dispatch Protocols define structured response procedures with trigger-based acti ![Protocols](/img/web-app/protocols/index.png) + + ## Protocol List **Authorization:** `Protocol_View` policy diff --git a/docs/web-app/records/analytics.md b/docs/web-app/records/analytics.md index a273caf..8d30057 100644 --- a/docs/web-app/records/analytics.md +++ b/docs/web-app/records/analytics.md @@ -20,7 +20,7 @@ Feature flag: `Records.Analytics`. Menu: **Records → Analytics**. | **Workload** | Records by definition, by person, by unit and by station group; personnel hours and hours per member; training records and hours; median hours to finalize; median review turnaround; return rate. | | **Accreditation** | The figures accreditation bodies (e.g. CFAI) ask for: response-time compliance against targets, training hours, inspections completed on schedule, hydrants tested within 12 months, occupancies inspected within 12 months, CRR audience reached. | | **Readiness** | Composed from Checklists, Work Orders and Inventory (each module authorizes you itself): checklist completion and on-time rate, expected/missed checks by day, unit readiness board, work orders open by priority and age, mean time to repair, safety holds, equipment issued / out for repair / expiring within 30 days, readiness packets captured. | -| **Community risk** | Occupancy risk profile (hazmat on site, no sprinklers, vacant, occupants needing assistance), inspections pass rate and days to correction, open violations by severity, permits issued / denied / expired, hydrants by flow class and tested within 12 months, CRR activities and audience. | +| **Community risk** | Occupancy risk profile (hazmat on site, no sprinklers, vacant, occupants needing assistance), inspections pass rate and days to correction, open violations by severity, permits issued / denied / expired, hydrants by flow class and tested within 12 months, CRR activities and audience, and smoke / CO alarms left by type, reason and month. | ![Response performance](/img/web-app/analytics/response-performance.png) diff --git a/docs/web-app/records/authoring.md b/docs/web-app/records/authoring.md index 5b2e93e..d45c196 100644 --- a/docs/web-app/records/authoring.md +++ b/docs/web-app/records/authoring.md @@ -7,6 +7,8 @@ title: Authoring Records This page covers the day-to-day work of writing, finishing and correcting records: run reports after a call, training records, work and meeting records, unit activity, and any department-designed form. NERIS incident reports have their own page — see [NERIS incident reports](incident-reports). + + ## Creating a record **Records → All records → New Record**, then choose the **definition** (record type). Some types can also be started from elsewhere: diff --git a/docs/web-app/records/community-risk-reduction.md b/docs/web-app/records/community-risk-reduction.md index 6bcf06e..b012a22 100644 --- a/docs/web-app/records/community-risk-reduction.md +++ b/docs/web-app/records/community-risk-reduction.md @@ -5,9 +5,9 @@ title: Community Risk Reduction # Community Risk Reduction (CRR) -Record the outreach and prevention work your department does — smoke-alarm installs, school visits, station tours, public education, car-seat checks, senior fall-prevention visits — so it counts toward accreditation, grant reporting and the community-risk dashboard. +Record the outreach and prevention work your department does — smoke and CO alarm installs, school visits, station tours, public education, car-seat checks, senior fall-prevention visits — so it counts toward accreditation, grant reporting and the community-risk dashboard. -Feature flag: `Records.Prevention.Crr`. Menu: **Records → Community risk reduction**. +Feature flag: `Records.Prevention.Crr`. Menu: **Records → Community risk** and **Records → Alarm requests**. ![CRR activities](/img/web-app/prevention/crr.png) @@ -20,20 +20,70 @@ Feature flag: `Records.Prevention.Crr`. Menu: **Records → Community risk reduc | **Title / Kind** | Smoke alarm installation, public education, station tour, home safety visit, school program, media, other. | | **Occurred on / Location / Coordinates / Occupancy** | Where and when; link to an [occupancy](occupancies) when it was at a tracked property. | | **Audience** | Number of people reached. | +| **Alarms left** | Three counts: **Smoke only**, **CO only** and **Combination (smoke + CO)**. Count each unit you leave. | +| **Alarm reason** | Why the alarms were left: faulty, missing, expired, low battery, new install, other. | +| **Call** | The call the crew was on when they left the alarm, if any (pick it with the call picker). | | **Hours** | Staff hours spent. | | **Staff** | Members who took part. | -| **Smoke alarms installed** | Count. | | **Outcome** | Free text. | ![New CRR activity](/img/web-app/prevention/crr-new.png) -The list shows a **summary for the period** (activities, audience reached, hours, smoke alarms) and feeds the **Community risk** analytics dashboard. +You can also start an activity from: + +- an **occupancy** page (**Record alarm left**), which links the activity to that occupancy; +- a **call** (**Reports → Record alarm left** on the call page), which links the call and fills in its address. + +## Counting alarms for the year + +The list shows a **summary for the period**: activities, audience reached, hours, **alarms left (all types)** with the smoke / CO / combination split, the number of homes and sites served, alarms by reason, and how many alarm requests are still open. Use **This year** or **Last year** next to the date filter to get a calendar-year total. You can also set any date range, for example a grant period. + +The same figures, plus alarms by type, by reason and by month, appear on the **Community risk** analytics dashboard. + +## Alarm requests + +Use **Records → Alarm requests** to track requests that are not handled on the spot, for example when a resident calls about a chirping, faulty or missing smoke or CO alarm. + +![Alarm request queue](/img/web-app/prevention/crr-alarm-requests.png) + +1. **New alarm request**: the date, how it came in (phone, walk-in, during a call, online, referral), the reason, how many smoke / CO / combination units are needed (if known), and the occupancy or address. You can also pick the resident from [Contacts](../contacts), the call it came from, a planned visit date and who is assigned. The request gets a number such as `ALM-2026-0001`. +2. The request stays **Open** in the queue, oldest first. You can filter it by status or to requests assigned to you. +3. After the visit, **Complete request** with the units actually left. This records a CRR activity (kind *Smoke alarm installation*) linked to the request, so the alarms count toward the yearly totals. +4. If no alarm is left, **Decline request** with a reason: unable to contact, resident declined, not eligible, duplicate, other. A declined request can be reopened. + +![Alarm request with the Complete and Decline forms](/img/web-app/prevention/crr-alarm-request.png) + +Notes: + +- To change what was left, edit the recorded activity. +- Deleting the activity reopens its request. +- A completed request cannot be deleted. +- If two people complete the same request at once, the second one is refused, so the alarms are not counted twice. + +Requests are also started from an occupancy page (**New alarm request**) or a call page (**Reports → New alarm request**). + +:::note Resident details +A request stores no resident name or phone number. Pick the resident as a Contact instead: their details stay in Contacts, where the department's protection settings apply. Keep the request notes operational (where the alarm is, access, what to bring). +::: + +## Occupancy page + +An occupancy's details page has a **Smoke and CO alarms** panel. It shows: + +- alarms left per year by type; +- open requests; +- recent CRR activity at that site. + +![Smoke and CO alarms panel on an occupancy](/img/web-app/prevention/crr-occupancy-alarms.png) + +When occupancies are merged, their alarm activity and requests move to the occupancy that is kept. ## Setup examples | Department | Use | |---|---| | **Fire / accreditation (CFAI)** | Log every public-education contact; export the period summary for the CRR standard of cover. | +| **Fire / smoke alarm program** | Take resident calls as alarm requests; crews complete them after the visit. A crew that finds a faulty alarm on a call records it from the call page. Report yearly smoke, CO and combination counts from the **This year** summary. | | **EMS** | Community paramedicine visits and CPR classes as *Public education*. | | **CERT / emergency management** | Preparedness fairs, neighbourhood training, sandbag distribution events. | @@ -41,6 +91,8 @@ The list shows a **summary for the period** (activities, audience reached, hours | Item | Value | |---|---| -| Routes | `/User/RecordCrr/{Index,Edit}` | -| Model | `RmsCrrActivity` | -| Flag / permission | `Records.Prevention.Crr`; `RecordsPreventionAdmin` to create/edit | +| Routes | `/User/RecordCrr/{Index,Edit}`, `/User/RecordAlarmRequests/{Index,Details,Edit}` | +| API | `api/v4/RecordCrr/{List,ForOccupancy,Get,Save,Delete,Summary}`, `api/v4/RecordAlarmRequests/{List,Get,Save,Complete,Decline,Reopen,Delete}` | +| Model | `RmsCrrActivity` (`SmokeAlarmsInstalled` = smoke only, `CoAlarmsInstalled`, `ComboAlarmsInstalled`, `AlarmReason`, `CallId`), `RmsCrrAlarmRequest` | +| Migration | M0284 | +| Flag / permission | `Records.Prevention.Crr`; `RecordsPreventionAdmin` to create, edit, complete or decline | diff --git a/docs/web-app/records/dashboard-and-queue.md b/docs/web-app/records/dashboard-and-queue.md index f83a4c7..d888033 100644 --- a/docs/web-app/records/dashboard-and-queue.md +++ b/docs/web-app/records/dashboard-and-queue.md @@ -5,6 +5,8 @@ title: Dashboard & Work Queue # Records Dashboard & Work Queue + + ## Records dashboard **Records → Records dashboard** is the "what needs doing" page for officers and records staff. @@ -34,8 +36,8 @@ Each tile links to the filtered queue. If a source is unavailable the dashboard | Control | Notes | |---|---| -| **Search records** | Record numbers, summaries and other safe fields. Narrative text is included when the department's search index allows it (it is withdrawn under Advanced Data Protection). | -| **Records for year** | Defaults to the current year; *All years* is available. | +| **Search records** | Record numbers, summaries and other safe fields. Narrative text is included when the department's search index allows it (it is withdrawn under Advanced Data Protection). Numbers are found however they are typed, whatever [format](settings#numbering) the department uses: `RUN26-0001`, `run-26-1`, `26-0001`, `0001` and `RUN` all find `RUN26-0001`. | +| **Records for year** | Defaults to the current year; *All years* is available. The year is the department's numbering year, read in the department's time zone: with a [fiscal year start](settings#fiscal-year-numbering) of November 1, *2027* lists the records numbered 2027, including those from November and December 2026. | | **Type** | A definition (Run, Training, NERIS incident, your own definitions …). | | **State** | Draft, Ready for review, Returned, Approved, Finalized, Amended, Voided, Cancelled, Submitted, Accepted, Rejected. | | **Owner / Group** | Who owes the record; which station/group it is anchored to. | diff --git a/docs/web-app/records/definitions.md b/docs/web-app/records/definitions.md index 4557cc1..35a01f5 100644 --- a/docs/web-app/records/definitions.md +++ b/docs/web-app/records/definitions.md @@ -34,6 +34,8 @@ The **key** (lower-case letters, digits, dots and dashes; may not start with `sy ### Template packs +Every pack is available to every department, whatever [organization type](../department-settings#organization-types) you chose. The *Category* column and the setup examples below are guidance, not a restriction: a multi-discipline organization can use the SAR, CERT, EOC and security templates side by side. The only check when you use a template is that the jurisdiction profile you pick supports it. + | Pack | Templates | Category | |---|---|---| | **Operational report templates** | Security Patrol Log · Security Incident Report · Delivery Run Report · Bus/Route End-of-Day Summary · General Shift/Activity Summary · Job/Service Completion | Security, Delivery, Transit, Operations, Field service | @@ -47,6 +49,8 @@ The **key** (lower-case letters, digits, dots and dashes; may not start with `sy | **Mutual Aid and Deployment Pack** | Deployment (External Order) | Mutual aid | | **Incident Support (ICS Logistics, Finance and Administration)** | ICS 202, 203, 204, 205, 205A, 206, 207, 208, 209, 210, 211, 213, 213RR, 214, 215, 215A, 217A, 218, 219, 220, 221, 225, 260; OF-286, OF-288, OF-294, OF-296, OF-297, OF-315; SF-261; Incident Action Plan package; ICS Canada variants | Incident support / Incident business | +Records of the **Deployment (External Order)** type are created and changed only from [Workforce & Business Ops → Deployments](../business-ops/deployment-finance#external-orders); opening *new* or *edit* for one in Records sends you there, and opening one shows its read-only [deployment report](deployments). + Templates marked **Preview** are usable but still being validated with departments. Each template shows its sources and review date; after you create from one, the editor shows **differences from the template** as it evolves. ## The definition editor diff --git a/docs/web-app/records/deployments.md b/docs/web-app/records/deployments.md index b104d8e..a79c419 100644 --- a/docs/web-app/records/deployments.md +++ b/docs/web-app/records/deployments.md @@ -1,64 +1,91 @@ --- sidebar_position: 15 -title: Deployments & Connectors +title: Deployment Reports --- -# Deployments & External Connectors +# Deployment Reports -**Deployments** track the external resource orders your department fills — a strike team sent on a wildland assignment through IROC, a crew loaned under EMAC, a Canadian request through CIFFC — from the order through mobilization, release and close-out. The ordering system stays authoritative: the order document is stored as an **immutable, checksummed snapshot** and nothing is ever written back. +**Deployment reports** is the read-only history of your department's deployments. Use it for printable reports, roster manifests, daily time reports, documents, and CSV/JSON exports for the strike teams, mutual-aid crews and contract work you sent. It also keeps older external resource orders (IROC, EMAC, CIFFC) readable, including orders that were never linked to a deployment. -To track the **time, expenses and billing** of the crew you send on an order, create a [Deployment Finance](../business-ops/deployment-finance) deployment from it (**Deployment Finance → Create from external order**); the order stays here. +Nothing can be created or changed here. To create a deployment, record an external order, update fills, store a new order snapshot or close out an order, use [Workforce & Business Ops → Deployments](../business-ops/deployment-finance). See [External orders](../business-ops/deployment-finance#external-orders) on that page. -:::note Preview feature -Deployments and connectors are a **Preview** feature. Fixtures were built from published IROC, CIFFC and EMAC documentation, not live integrations. Verify against your ordering system. +:::note Moved from Records +External orders used to be created and edited under **Records → Manage → Deployments**. Old bookmarks to the create page (`/User/RecordDeployments/New`) now open **New external order** in Workforce & Business Ops. The former Records write URLs are no longer accepted. In the Records queue, opening a **Deployment (External Order)** record goes to its read-only report, and *new* or *edit* goes to the deployment workspace. Generic record edits and bulk actions on those records are refused. ::: -Menu: **Records → Manage → Deployments**. +## Where to find it -![Deployments](/img/web-app/records/deployments.png) +- Sidebar: **Records → Deployment reports**. +- **All records → Manage → Deployment reports**. +- From a deployment page in Workforce & Business Ops: the **Deployment reports** header button. -## Recording a deployment +Every department member can open the page. Administrators and holders of *Manage deployments* see every deployment; everyone else sees the deployments they are rostered on. The same department and roster rules apply as in the operational screens. External orders keep their own Records visibility checks. -**New deployment**: +## Turning it on -| Field group | Contents | +Deployment reports needs only the `Records.System` flag. It does **not** require `Operations.Deployments`: if a department turns operational deployments off, its retained reports stay readable. Downloads marked *Export records* below need the **Export records** permission. + +## Deployment reports list + +![Deployment reports](/img/web-app/records/deployment-reports.png) + +The page opens with the notice *Read-only deployment history, reports and exports. Manage deployments in Workforce & Business Ops.* + +| Element | Meaning | +|---|---| +| **Show open only / Show all** | All deployments, including completed and cancelled ones, are listed by default. | +| **Export summary CSV** | *Export records*. One row per deployment, read across every page of results. | +| Deployments table | **Name** (opens the report), **Status**, **Finance mode**, **Incident #**, **Window**. 50 per page. | +| **External orders** | Older external orders that are not linked to a deployment you can see: **Resource order #**, **Name** (incident) and **Status**. Click an order number to open its report. | + +## Deployment report + +![Deployment report](/img/web-app/records/deployment-report.png) + +| Element | Meaning | |---|---| -| **Order** | Order number, incident, country / subdivision, ordering and dispatch offices. | -| **Agencies** | Requesting, receiving and sending agency; the **department role** — *Filling the order*, *Requesting resources* or *Hosting incident*. | -| **Cost** | Cost code, agreement reference, currency / units / time zone. | -| **Order artifact** | Upload the order document (PDF, JSON or CSV) from the source system; stored as a snapshot with source system and version. | -| **First fill (optional)** | Request number, resource, position, trainee, assigned person, home unit, host agency, needed on. | +| **Print report** | Opens a standalone, print-friendly copy (roster, time-report links, expenses grouped by currency, document links). | +| **Export report JSON** | *Export records*. Deployment identifiers, roster, time reports with entries, and expenses. Protected notes and document contents are deliberately left out. | +| **Export time CSV** | *Export records*. Every time entry on the deployment. | +| **Manifest** | Renders the roster manifest without filing it as a new document on the deployment. | +| **Open deployment workspace** | Managers only. Opens the deployment in Workforce & Business Ops. | +| Summary | Status, finance mode, incident #, resource order #, window and a link to the **External order** report. | +| **Roster** | Units with call sign, personnel with certification code, and equipment, each with added → removed (or issued → returned) times. | +| **Time reports** | Report number (opens the rendered DTR), report date and status. | +| **Expenses** | Date, description, amount, currency, with a total per currency. | +| **Files** | The deployment's documents. A download is checked against the owning deployment before any file is returned. | -From the deployment page add further **fills**, update their status (requested → assigned → mobilized → released → returned, or declined with a reason), **record a new snapshot** when the order changes (the previous snapshot is kept and superseded) and finally **close out** (every accepted fill must be *Returned* first). +## External order report -## External connectors +This is the read-only view of an order and its **Fills**. It shows the same order panel and fill table as the workspace order page, without any buttons that change the order. -**Records → Manage → Deployments → External connectors** reads orders automatically from a source that serves the **Resgrid Mutual-Aid Order Feed v1** (JSON). Screen-scraping is not supported. +![External order report](/img/web-app/records/deployment-order-report.png) -| Setting | Notes | +| Element | Meaning | |---|---| -| **Connector name / Feed provider / Source system / Feed root (https)** | Where to read. | -| **Credential kind / header name / credential** | Encrypted at rest, never shown again. | -| **Read authority granted** | Write authority is never granted in this release. | -| **Poll interval (minutes) / Requests per hour** | Request limits. | -| **Source terms** | Acknowledge the source's terms before the connector can be enabled. | -| **Inbound push endpoint / Inbound token** | For sources that push; the token is shown once. | +| **Deployment reports** | Opens the linked deployment's report, when one exists and you can see it. | +| **Export resource CSV** | *Export records*. One row per fill: order, incident, request, resource, position, user, unit, status, and mobilized / checked-in / released / returned times. | +| **Print** | Prints the page. | +| **Order artifact** | Downloads the stored order document. | -Every read lands as a new snapshot; **Reconciliation** lists where the source and your record disagree (source released but a fill not returned, request exists in the source but not locally …) and a coordinator decides — nothing is applied automatically. The **Run log** shows each poll's outcome and counts. +CSV exports protect against spreadsheet formula injection: a cell that starts with `=`, `+`, `-` or `@` is prefixed with an apostrophe. Times are exported in UTC (ISO 8601). ## Setup examples | Department | Use | |---|---| -| **Wildland / type 3 IMT** | One deployment per resource order; fills per crew member; snapshots when IROC updates the order. | -| **State EMA** | Role *Requesting resources* for EMAC missions received; *Hosting incident* for incoming teams. | -| **Municipal fire** | Mutual-aid strike team deployments with cost codes for FEMA reimbursement. | +| **Wildland / type 3 IMT** | Finance/admin unit prints the deployment report and exports the time CSV for the incident cost package after demobilization. | +| **State EMA** | **Export summary CSV** each quarter for the EMAC reimbursement tracker; resource CSV per mission order for the after-action report. | +| **Municipal fire** | Records staff answer reimbursement or public-records questions from the report without needing *Manage deployments*; exports are limited to holders of *Export records*. | +| **Department that stopped using deployments** | Turn `Operations.Deployments` off; the reports and older orders stay readable here. | ## Technical reference | Item | Value | |---|---| -| Routes | `/User/RecordDeployments/{Index,New,Details,Artifact}`, `/User/RecordDeploymentConnectors/{Index,New,Edit}` | -| Model | `RmsExternalOrder`, `RmsExternalOrderFill`, `RmsExternalOrderSnapshot`, `RmsExternalOrderConnector` | -| Feed contract | `docs/architecture/rms-mutual-aid-order-feed-v1.md` (Core repository) | -| Config | Connectors can be switched off per installation (*External connectors are switched off*). | +| Routes | `/User/RecordDeployments/{Index,Report,Print,Details,Manifest,TimeReport,Attachment,Artifact,ForRecord}`; exports `ExportSummary`, `Export` (JSON), `ExportTimeEntries`, `ExportOrders` (resource CSV). GET only, with no POST actions. `New` redirects to `/User/DeploymentOrders/New`. | +| Operational screens | `/User/Deployments/*`, `/User/DeploymentOrders/*`, `/User/RecordDeploymentConnectors/*`; see [Deployments](../business-ops/deployment-finance#technical-reference) | +| Model | `Deployment` and its roster, time reports, expenses and attachments; `RmsExternalOrder`, `RmsExternalOrderFill`, `RmsExternalOrderSnapshot` | +| Permissions | Records view (every member); *Export records* for CSV/JSON; *Manage deployments* (118) to see every deployment instead of only your own, and for **Open deployment workspace** | +| Flag | `Records.System` (reports stay available when `Operations.Deployments` is off) | +| API (read) | `GET api/v4/RecordDeployments/{List,Get,GetForRecord,Artifact}`. External-order commands moved to `POST api/v4/DeploymentOrders/{Create,AddFill,TransitionFill,Snapshot,Closeout}` with the same request/response shapes; the former `RecordDeployments` command URLs are no longer accepted. | diff --git a/docs/web-app/records/hydrants.md b/docs/web-app/records/hydrants.md index 442a42f..df27c74 100644 --- a/docs/web-app/records/hydrants.md +++ b/docs/web-app/records/hydrants.md @@ -11,6 +11,8 @@ Feature flag: `Records.Prevention.Hydrants`. Menu: **Records → Hydrants**. ![Hydrants](/img/web-app/prevention/hydrants.png) + + ## The hydrant list and map The header shows *N hydrants, N out of service, N due for a flow test*. The **Map** colours each hydrant by flow class (black = out of service). Filter, search by number or address, or open one for details. diff --git a/docs/web-app/records/incident-reports.md b/docs/web-app/records/incident-reports.md index 7cf2a5b..0fdf61f 100644 --- a/docs/web-app/records/incident-reports.md +++ b/docs/web-app/records/incident-reports.md @@ -13,9 +13,11 @@ You can still author and finalize incident reports for your own records. Submiss ![Incident reports queue](/img/web-app/incident-reports/index.png) + + ## Where to find it -**Records → All records → Incident reports** (or the *Incident reports* tile on the dashboard). The queue lists reports by year and state: *Incomplete*, *Awaiting review*, *Submitted*, *Accepted*, *Rejected*, *Corrected*. +**Records → All records → Incident reports** (or the *Incident reports* tile on the dashboard). The queue lists reports by year (the department's [numbering year](settings#fiscal-year-numbering) of the call, so a fiscal year's reports stay together) and state: *Incomplete*, *Awaiting review*, *Submitted*, *Accepted*, *Rejected*, *Corrected*. ## Starting a report @@ -91,6 +93,8 @@ For fire and hazmat incidents NERIS takes a separate **incident analysis** (caus Self-hosted operators can switch NERIS off system-wide (*NERIS submission is switched off system-wide*). +A department that does not report to NERIS can turn **Use NERIS workflows** off in [Records settings](settings#neris-reporting). Incident reports are then ordinary department records: they finalize without the NERIS rules, the validate and submit actions are hidden, and this screen redirects to Records settings. The profile and crosswalk are kept for when NERIS is turned back on. + ## Setup examples | Department | Recommended configuration | diff --git a/docs/web-app/records/inspections.md b/docs/web-app/records/inspections.md index 47f7a6d..d541400 100644 --- a/docs/web-app/records/inspections.md +++ b/docs/web-app/records/inspections.md @@ -7,10 +7,12 @@ title: Inspections Fire and life-safety inspections of [occupancies](occupancies): programs that define *what* is inspected and *how often*, code sets the inspection is checked against, the inspection itself with a checklist, and the violations that come out of it with correction windows, notices and re-inspections. -Feature flag: `Records.Prevention.Inspections` (requires occupancies). Menu: **Records → Inspections**. +Feature flag: `Records.Prevention.Inspections` (requires occupancies). Menu: **Records → Inspections**. The list filters by state, program and inspection number (part of it, in the department's [format](settings#other-record-numbers), however it is typed). ![Inspections](/img/web-app/prevention/inspections.png) + + ## Setting up ### Code sets diff --git a/docs/web-app/records/investigations.md b/docs/web-app/records/investigations.md index 17ae118..efe0c52 100644 --- a/docs/web-app/records/investigations.md +++ b/docs/web-app/records/investigations.md @@ -7,10 +7,12 @@ title: Investigations Fire and arson investigations, cause-and-origin work and any other case that needs **restricted, need-to-know access**. A case is visible only to its **members**, every read is written to an **access audit**, evidence items carry an append-only **chain of custody**, and findings must be **approved by someone other than their author** before they can be recommended as an amendment to the incident report. -Feature flag: `Records.Investigations`; requires the *View restricted records* permission **and** case membership. Menu: **Records → Investigations**. +Feature flag: `Records.Investigations`; requires the *View restricted records* permission **and** case membership. Menu: **Records → Investigations**. Your cases can be filtered by a case number or by the number of an evidence item in the case (`EV-2026-0042` finds its case), however the number is typed. ![Investigations](/img/web-app/prevention/investigations.png) + + ## Opening a case **Open case** — you become the **lead investigator**. Give the case a title, kind (fire cause & origin, arson, explosion, fatality, hazmat, other), an optional linked **occupancy** and **call**, jurisdiction and reference number. Add **members** afterwards; only members can read the case. diff --git a/docs/web-app/records/legal-holds-and-disclosures.md b/docs/web-app/records/legal-holds-and-disclosures.md index cd4cab6..fd8286b 100644 --- a/docs/web-app/records/legal-holds-and-disclosures.md +++ b/docs/web-app/records/legal-holds-and-disclosures.md @@ -25,7 +25,7 @@ Holds list who placed and released them; **Release hold** requires the authority ## Records requests (disclosures) -**Records → Manage → Records requests** (requires *Manage record disclosures*). A request carries a statutory clock, so it is tracked here rather than answered ad hoc. +**Records → Manage → Records requests** (requires *Manage record disclosures*). A request carries a statutory clock, so it is tracked here rather than answered ad hoc. The queue filters by state and by request number (part of it, however it is typed: `prr 2027 3` finds `PRR-2027-0003`). ![Records requests](/img/web-app/records/disclosures.png) diff --git a/docs/web-app/records/occupancies.md b/docs/web-app/records/occupancies.md index 66aeacc..bdb6767 100644 --- a/docs/web-app/records/occupancies.md +++ b/docs/web-app/records/occupancies.md @@ -11,6 +11,8 @@ Feature flag: `Records.Prevention.Occupancy`. Menu: **Records → Occupancies**. ![Occupancies](/img/web-app/prevention/occupancies.png) + + ## The occupancy list Search by number, name or address; filter by status, **review overdue** and **hazmat on site**. Each row links to the details page. **New occupancy** opens the editor. @@ -36,9 +38,10 @@ Hazards flagged *Alert crews* are pushed to the apps and the dispatch **alert no - **Hazards** — add / remove hazards. - **Inspections** — schedule an inspection from a program; list of past inspections with result and open violations. - **Permits** — permits issued against the occupancy; **New permit**. +- **Smoke and CO alarms** — alarms left per year (smoke only, CO only, combination), open alarm requests and recent [community risk reduction](community-risk-reduction) activity at the site; **New alarm request** and **Record alarm left** (needs `Records.Prevention.Crr`). - **Linked contacts** — the owner, manager or company from [Contacts](../contacts). - **Mark reviewed** — records the pre-plan review date (the list flags occupancies whose review date has passed). -- **Merge into** — merges a duplicate into a target occupancy; hazards, links and history move and this record becomes a pointer. +- **Merge into** — merges a duplicate into a target occupancy; hazards, links, CRR activity, alarm requests and history move and this record becomes a pointer. - **Delete** — inspections, permits and hazards keep their history but lose the parent. The occupancy also feeds the **Contacts pre-plan summary** and the dispatch projection the apps use. diff --git a/docs/web-app/records/overview.md b/docs/web-app/records/overview.md index f747c37..8596f4a 100644 --- a/docs/web-app/records/overview.md +++ b/docs/web-app/records/overview.md @@ -9,6 +9,8 @@ title: Records Overview ![Records dashboard](/img/web-app/records/dashboard.png) + + ## Who it is for | If you are… | Records gives you… | @@ -32,7 +34,7 @@ When Records is enabled the left menu shows **Records** in place of *Logs* (neve | **Investigations** | Restricted case files (members only). | | **Analytics** | Response performance, workload, executive, accreditation, readiness and community-risk dashboards. | -From **All records** the toolbar offers **Reports** (export this list, saved reports, analytics, accountability, quality review) and **Manage** (records requests, deployments, definitions, report exports, release health, field rollout, settings). +From **All records** the toolbar offers **Reports** (export this list, saved reports, analytics, accountability, quality review) and **Manage** (records requests, deployment reports, definitions, report exports, release health, field rollout, settings). ## Turning it on: activation @@ -91,7 +93,7 @@ NERIS reports additionally: Submitted → Accepted / Rejected → Corrected - [Investigations](investigations) — restricted case files with chain of custody. - [Analytics](analytics) · [Quality review](quality-review) · [Accountability](accountability) - [Saved reports & exports](reports-and-exports) — CSV/JSON, saved reports, report exports for agencies. -- [Deployments & connectors](deployments) — mutual-aid orders your department fills. +- [Deployment reports](deployments) — read-only deployment history, reports and exports; external orders are created and worked in [Workforce & Business Ops → Deployments](../business-ops/deployment-finance#external-orders). - [Legal holds & records requests](legal-holds-and-disclosures) - [Records settings](settings) — numbering, retention, group visibility, print layout, NERIS, disclosure defaults. @@ -118,7 +120,7 @@ Records has its own permission set under **Department → Security & Permissions | Item | Value | |---|---| -| Controllers | `RecordsController`, `RecordDefinitionsController`, `IncidentReportsController`, `IncidentAnalysisController`, `RecordDocumentsController`, `RecordEvidenceController`, `RecordLegalHoldsController`, `DisclosuresController`, `RecordOccupanciesController`, `RecordInspectionsController`, `RecordHydrantsController`, `RecordPermitsController`, `RecordCrrController`, `RecordInvestigationsController`, `RecordsAnalyticsController`, `RecordsQualityController`, `RecordSavedReportsController`, `RecordsExportTemplatesController`, `RecordDeploymentsController`, `RecordDeploymentConnectorsController`, `RecordsHealthController`, `RecordsInventoryController`, `RecordSubmissionsController` | +| Controllers | `RecordsController`, `RecordDefinitionsController`, `IncidentReportsController`, `IncidentAnalysisController`, `RecordDocumentsController`, `RecordEvidenceController`, `RecordLegalHoldsController`, `DisclosuresController`, `RecordOccupanciesController`, `RecordInspectionsController`, `RecordHydrantsController`, `RecordPermitsController`, `RecordCrrController`, `RecordAlarmRequestsController`, `RecordInvestigationsController`, `RecordsAnalyticsController`, `RecordsQualityController`, `RecordSavedReportsController`, `RecordsExportTemplatesController`, `RecordDeploymentsController`, `RecordDeploymentConnectorsController`, `RecordsHealthController`, `RecordsInventoryController`, `RecordSubmissionsController` | | Feature flags | `Records.System`, `Records.Field.{Responder,Unit,IncidentCommand,Dispatch}`, `Records.Prevention.{Occupancy,Inspections,Hydrants,Permits,Crr}`, `Records.Investigations`, `Records.QualityReview`, `Records.Analytics` | | Cutover fact | `RmsDepartmentCutover` (activation is append-only; not a department setting) | | Permissions | `PermissionTypes` 50–67 and 69 (`CreateRecord` … `ReassignRecordDrafts`, `RecordsPreventionAdmin`) | diff --git a/docs/web-app/records/permits.md b/docs/web-app/records/permits.md index 8c7e912..f8c9398 100644 --- a/docs/web-app/records/permits.md +++ b/docs/web-app/records/permits.md @@ -11,6 +11,8 @@ Feature flag: `Records.Prevention.Permits` (requires occupancies). Menu: **Recor ![Permits](/img/web-app/prevention/permits.png) + + ## Permit types **Permits → Permit types** defines what you issue: name, **code**, **validity (days)** used to compute the expiry from the issue date, whether it **requires plan review**, a **conditions template** pre-filled on new permits and a **fee** (reference only — invoicing is recorded, not collected, here). @@ -32,7 +34,7 @@ Feature flag: `Records.Prevention.Permits` (requires occupancies). Menu: **Recor ![Permit details](/img/web-app/prevention/permit-details.png) -The list filters by state, type and **expiring soon**; analytics reports issued / denied / expired / revoked counts and average days from applied to issued. +The list filters by permit number (part of it, in the department's [format](settings#other-record-numbers), however it is typed), state, type and **expiring soon**; analytics reports issued / denied / expired / revoked counts and average days from applied to issued. ## Setup examples diff --git a/docs/web-app/records/settings.md b/docs/web-app/records/settings.md index b85cd47..1eb2b65 100644 --- a/docs/web-app/records/settings.md +++ b/docs/web-app/records/settings.md @@ -18,13 +18,114 @@ title: Records Settings ## Numbering +A record gets its number when it is finalized, so abandoned drafts leave no gaps. One department **number pattern** numbers every built-in record type (Run, Training, Work, Meeting, Coroner, Callback, Unit Activity) and NERIS incident reports. Department definitions have their own prefix, sequence width and per-station or per-incident sequences, set on the [definition](definitions). + +![Record numbering settings](/img/web-app/records/settings-numbering.png) + | Setting | Meaning | |---|---| -| **Include the year in record numbers** | `RUN-2026-000123` vs `RUN-000123`. | -| **Sequence digits** | Zero-padding width. | -| **Separate sequence per station/group** | Each station numbers its own records. | +| **Number pattern** | Literal text around tokens, up to 40 characters. Letters, digits, `-`, `_` and `.` are kept as written. The example next to the box shows a sample number as you type. Default `{PREFIX}-{YYYY}-{SEQ}`, which gives `RUN-2026-0123`. | +| **Sequence digits** | Zero-padding width of the sequence, 3 to 8. `4` gives `0123`. | +| **Numbering year starts** | The month and day your numbering year starts, and which year names it. January 1 (the default) is the calendar year. See [Fiscal year numbering](#fiscal-year-numbering). | +| **Record type prefixes** | What `{PREFIX}` writes for each record type. Leave a box blank to keep the default. See [Record type prefixes](#record-type-prefixes). | +| **Next numbers for *year*** | Each sequence the pattern produces in the current numbering year (with its dates when it is a fiscal year), with the number it issues next. See [Next numbers](#next-numbers). | + +### Pattern tokens + +| Token | Writes | +|---|---| +| `{PREFIX}` | The record type's prefix: the default, or your own from **Record type prefixes**. | +| `{YYYY}` or `{YY}` | The year, `2026` or `26`: the year the record started (an incident report's call was logged), in your department's time zone. With a fiscal year start, the fiscal year's name. | +| `{GROUP}` | The record's station or group as `G` followed by its ID, such as `G12`. Must be followed by `-`, `_` or `.`. A record with no group leaves it out, along with the separator after it. | +| `{SEQ}` | The sequence number. Required, exactly once. | + +Each token can be used once. The sequence restarts whenever the text around `{SEQ}` changes: + +- Including the year restarts the sequence every numbering year: the calendar year, or your fiscal year when you set one. +- Including `{GROUP}` gives each station or group its own sequence. +- Leaving out `{PREFIX}` gives every record type one shared sequence. + +Changing the pattern never renumbers existing records. A pattern that is not valid is not saved, and nothing else under Numbering changes in that save (prefixes and next numbers included). The other settings on the page still save. + +### Fiscal year numbering + +Incident reports often have to match an outside agency's fiscal year, such as a county's or state's, rather than the calendar year. Set **Numbering year starts** to the month and day that year begins. Sequences whose pattern includes `{YYYY}` or `{YY}` then start again at 1 on that day, at midnight in your department's time zone, and the year tokens write the fiscal year's name. Department definitions set to restart yearly follow the same year. + +Choose which year names it: + +- **Named by the year it ends in** (the default, and the usual fiscal-year convention). A year starting November 1, 2026 is 2027. +- **Named by the year it starts in.** The same year is 2026. + +| Year starts | Named by | Incident logged | `{PREFIX}{YY}-{SEQ}` with prefix `EZKT` | +|---|---|---|---| +| January 1 (default) | Calendar year | November 1, 2026 | `EZKT26-…` (2026 continues) | +| November 1 | Year it ends in | October 31, 2026 | `EZKT26-…` (FY2026 continues) | +| November 1 | Year it ends in | November 1, 2026 | `EZKT27-0001` | +| November 1 | Year it ends in | January 15, 2027 | `EZKT27-…` (no restart on January 1) | +| November 1 | Year it starts in | November 1, 2026 | `EZKT26-0001` | -Per-definition prefixes and per-incident sequences are set on the [definition](definitions). +- The year comes from when the record started, not when it was finalized: an October report finalized in November keeps the old fiscal year's number. +- Records request numbers (`PRR-2027-0001`) and prevention numbers follow the same year: occupancies `OCC-`, inspections `INSP-`, permits `PRM-`, investigations `INV-` and evidence `EV-`, each with its own sequence. A request takes the year it was received; the others take the year they were created. Their formats can be changed under [Other record numbers](#other-record-numbers). +- Record numbering and [call numbering](../department-settings#fiscal-year-numbering) each have their own year start, so dispatch can follow the calendar year while reports follow a fiscal year. +- The year filters on the [records queue](dashboard-and-queue#filtering-and-search) and the incident report queue use the same year, so *2027* lists every record numbered 2027. +- February 29 can't be used as a start day, since not every year has one. A year start that isn't valid is not saved, and nothing else under Numbering changes in that save. +- Changing the year start never renumbers records. If the new year's name matches numbers already issued, the sequence continues after the highest of them instead of starting again, so no number is issued twice. +- Next numbers typed in the same save as a year start change are not applied, because they belonged to the old year's sequences. Save the year start first, then raise the numbers on the new rows. + +### Other record numbers + +The **Other record numbers** table sets the numbers Records issues outside the record pattern: **records requests** (`PRR-2026-0001`), **occupancies** (`OCC-`), **inspections** (`INSP-`), **permits** (`PRM-`), **investigations** (`INV-`) and **evidence** (`EV-`). Each row shows its built-in numbers; type a pattern to replace them. + +- Patterns use `{YYYY}` or `{YY}`, `{MM}`, `{DD}` and `{SEQ}`, as call numbers do (not `{PREFIX}` or `{GROUP}`), and follow the numbering year start above. +- Occupancy, inspection, permit, investigation and evidence numbers must fit 32 characters; records request numbers 50. A longer pattern is refused and named in the message. +- A new pattern carries on after any number it would repeat, so `PRM-{YYYY}-{SEQ}` with 5 digits continues after `PRM-2027-0041` as `PRM-2027-00042`. +- For a custom pattern, **Raise next to** carries on numbering from another system. Raises typed in a save that also changes the pattern or the year start are not applied. + +### Record type prefixes + +Each built-in record type has its own prefix, which `{PREFIX}` writes into its numbers. Replace a default to match your department's numbering, for example `FIRE` for Run records and `IR` for incident reports. + +| Record type | Default prefix | +|---|---| +| Run | `RUN` | +| Training | `TRN` | +| Work | `WRK` | +| Meeting | `MTG` | +| Coroner | `COR` | +| Callback | `CBK` | +| Unit Activity | `UNT` | +| Incident reports (NERIS) | `INC` | + +- A prefix is **2 to 6 letters or digits**. Lower case is saved as upper case. Separators such as `-` belong in the pattern, not the prefix. +- Leave a box blank, or enter the default, to go back to the default prefix. +- A new prefix **starts its own sequence**. Records already numbered keep their numbers. Going back to an earlier prefix carries on after the highest number issued with it. +- Record types given the **same prefix share one sequence**. The **Next numbers** table lists them on one row. +- A prefix that is not valid is not saved. That record type keeps the prefix it had, the message names it, and the rest of the settings still save. +- Prefixes are only used when the pattern includes `{PREFIX}`. + +Numbers are not reused: each new number comes after the highest one already issued in its sequence, counting both records and incident reports. + +### Next numbers + +The **Next numbers** table lists every sequence the current pattern and prefixes produce for this year, with the number each will issue next. A department moving to Resgrid part way through a year can carry on its existing numbering: after issuing `2026-0001` through `2026-0152` elsewhere, enter `153` for that sequence. + +- A next number can only be **raised**, never lowered. Saving asks for confirmation first. +- A number below the one the sequence would already issue is refused, and the message lists that sequence. +- If you change the pattern or a prefix in the same save, the next numbers you entered are not applied, because they belonged to the old sequences. Save the new pattern or prefix first, then raise the numbers on the new rows. + +### Setup examples + +| Goal | Pattern | Prefixes | Numbers | +|---|---|---|---| +| Keep the defaults | `{PREFIX}-{YYYY}-{SEQ}` | Defaults | `RUN-2026-0001`, `TRN-2026-0001`, `INC-2026-0001` | +| Different prefixes for Run records and incident reports | `{PREFIX}-{YYYY}-{SEQ}` | Run `FIRE`, Incident reports `IR` | `FIRE-2026-0001`, `IR-2026-0001` | +| Run records and incident reports share one count | `{PREFIX}{YY}-{SEQ}` | Run `FD`, Incident reports `FD` | `FD26-0001`, `FD26-0002` | +| Each station numbers its own records | `{PREFIX}-{GROUP}-{YYYY}-{SEQ}` | Defaults | `RUN-G12-2026-0001` | +| One number series for everything | `{YYYY}-{SEQ}` | Not used | `2026-0001`, `2026-0002` | +| Never restart the sequence | `{PREFIX}-{SEQ}` | Defaults | `RUN-000001` (with 6 sequence digits) | +| Incident reports follow a November fiscal year named by the year it ends in | `{PREFIX}{YY}-{SEQ}`, year starting November 1 | Incident reports `EZKT` | `EZKT27-0001` from November 1, 2026 | + +Moving to Resgrid with Import & Migration? Its Configure tab can set record numbering for you, including the next numbers that continue your old system's ([Configure → Record numbering](../import-and-migration/configure#record-numbering)). ## Retention @@ -62,9 +163,21 @@ How the letterhead renders on record prints. Identity and logo come from the [De Every save is a new layout version stamped in the provenance footer of every print. Per-definition layouts can override this. -## NERIS settings +## NERIS reporting + +| Setting | Meaning | +|---|---| +| **Use NERIS workflows** | On by default. Turn it off if your department does not report to NERIS. | + +Turning NERIS workflows off affects only NERIS: + +- Incident reports finalize without the NERIS rules. Required custom fields and evidence checks still apply. Conditional sections show as suggestions. +- Nothing is validated with or submitted to NERIS. Queued submissions wait, and submission recovery is paused. +- The NERIS settings screen, the NERIS figures on the dashboard and analytics, and the health alert for failed submissions are hidden. + +Everything else in Records keeps working: incident reports and analyses, review, numbering, retention, disclosures, search and printing. The NERIS profile, credential, call-type crosswalk and submission history are kept. When NERIS is turned back on, submission continues from where it stopped. -Covered in [NERIS incident reports](incident-reports#neris-settings): entity ID, environment, credentials, enable / auto-submit, protected egress acknowledgement and the call-type crosswalk. +While NERIS workflows are on, the NERIS profile itself is covered in [NERIS incident reports](incident-reports#neris-settings): entity ID, environment, credentials, enable / auto-submit, protected egress acknowledgement and the call-type crosswalk. ## Public-records disclosure @@ -79,5 +192,7 @@ Covered in [NERIS incident reports](incident-reports#neris-settings): entity ID, | Item | Value | |---|---| | Route | `/User/Records/Settings` | -| Model | `RecordsDepartmentSettings` (department setting 74 holds retention overrides; settings 70–77 belong to the Records settings screen) | +| Model | `RecordsDepartmentSettings` (department setting 74 holds retention overrides; settings 70–77 and 111 `RecordsNerisWorkflowsEnabled` belong to the Records settings screen) | +| Numbering | Department setting 72 `RecordsNumberingConfig`: `Pattern`, `SequenceWidth`, `Floors` (raised next numbers, keyed by sequence), `Prefixes` (per record type, keyed by definition key such as `system.run` or `system.neris-incident`) the numbering year start `YearStartMonth` / `YearStartDay` / `YearLabel` (0 = named by the year it ends in, 1 = the year it starts in; unset = January 1) and `DocumentPatterns` (records request and prevention number patterns; their sequences in `DocumentNumberSequences`, M0268) | +| API | `GET api/v4/Records/Capabilities` lists each record type's `NumberPrefix` with the department's own prefixes applied | | Related | `/User/IncidentReports/Settings` (NERIS), `/User/Department/Profile` (letterhead identity) | diff --git a/docs/web-app/reports.md b/docs/web-app/reports.md index 66aa76d..d286f54 100644 --- a/docs/web-app/reports.md +++ b/docs/web-app/reports.md @@ -123,12 +123,32 @@ All staffing level changes within a date range with custom state resolution. ### Call Summary Report -**Parameters:** Date range +**Parameters:** Date range, group (optional) Comprehensive call analysis: -- Counts by call type +- Summary tiles: total and still-open calls, average time to on scene, average call length, unit and personnel responses +- Counts by call type, with a pie chart - Counts by close state -- Per-call details (personnel count, unit count, first on-scene time) +- Calls by group, with a pie chart (when calls fall in more than one group) +- Per-call details (group, personnel count, unit count, first on-scene time) + +**Group filter.** Each call is counted in exactly one group: + +1. If the call's location falls inside a group's geofence, it belongs to that group. Where geofences overlap, the most deeply nested group wins, then a station over an organizational group, then the smaller geofence. +2. Otherwise (no location, or outside every geofence) it belongs to the group that most of its dispatched units and personnel belong to. Each unit counts for its station group and each person for their group; a dispatched group counts through its members. Ties go to the group with more units, then to the station nearest the call. +3. If nothing with a group was dispatched, the units and personnel that set a status on the call decide it the same way. + +Calls that none of these place show as **Unassigned**. Choosing a group also includes the groups beneath it, so a battalion shows all of its stations' calls. Group membership and unit stations are today's, not as they were when the call ran. + +**Period statistics.** Sections are added when the date range calls for them: + +| Range | Sections added | +|---|---| +| Crosses a month boundary | Monthly statistics: per-month table (calls, year to date, averages, units, personnel), calls by month stacked by call type, call types by month | +| Crosses a quarter boundary | Quarterly statistics: the same per quarter, plus a call type pie for each quarter listing the department's call types with no calls that quarter | +| Covers at least one whole calendar year | Yearly statistics: the same per year, with a trend line when the range spans more than one year | + +Periods the range only partly covers are marked with an asterisk. ### Unit State History Report @@ -157,7 +177,7 @@ Several reports have parameter selection pages that allow filtering: | Staffing History | Group, user, date range | | Unit State History | Group, unit, date range | | Action Logs | Group, user, date range | -| Call Summary | Date range | +| Call Summary | Date range, group (optional) | All parameter pages respect the **visibility matrix** — only showing personnel/groups the user has permission to view. diff --git a/docs/web-app/resource-orders.md b/docs/web-app/resource-orders.md index 969df44..101d52d 100644 --- a/docs/web-app/resource-orders.md +++ b/docs/web-app/resource-orders.md @@ -9,6 +9,8 @@ Resource Orders enable cross-department resource requesting and fulfillment. The ![Resource orders](/img/web-app/orders/index.png) + + ## Overview The resource ordering system allows departments to: diff --git a/docs/web-app/routes.md b/docs/web-app/routes.md index 8e89cee..eab63ec 100644 --- a/docs/web-app/routes.md +++ b/docs/web-app/routes.md @@ -11,6 +11,8 @@ The Routes module provides route planning, execution tracking, and deviation mon **Navigation:** Department Menu → Routes + + ## Overview The Routes system is built around six core concepts that work together to plan and execute routes: diff --git a/docs/web-app/run-cards.md b/docs/web-app/run-cards.md index 29e5261..47c53dc 100644 --- a/docs/web-app/run-cards.md +++ b/docs/web-app/run-cards.md @@ -11,6 +11,8 @@ Feature flag: `Dispatch.RunCards`. Menu: **Department dropdown → Dispatch Sett ![Run cards](/img/web-app/run-cards/index.png) + + ## Department-wide dispatch settings **Department → Dispatch Settings → Run Cards & Automatic Dispatch** sets the defaults every card inherits: @@ -21,11 +23,36 @@ Feature flag: `Dispatch.RunCards`. Menu: **Department dropdown → Dispatch Sett | **Automatically dispatch recommended resources** | On: matched cards dispatch immediately when the call is created (including calls from email/SMS import and the API). Off: recommendations pre-populate the New Call page for dispatcher review. | | **Minimum unit staffing to dispatch** | Units staffed below this level (Partially staffed, Degraded …) are not selected even if their status matches. Units without defined roles always pass. | | **Enable move-up / backfill recommendations** | After selection, check station coverage minimums and recommend relocating resources to depleted stations. | -| **Closest unit response tuning** | Radius and scoring for closest-unit mode. | +| **Closest unit response tuning** | For closest-unit mode: maximum age of a GPS position, maximum radius, whether stale positions may still be used, ordering by driving ETA (and how many candidates get a drive-time lookup), and the two **turnout times** — *In-quarters turnout* and *Mobile turnout* (see below). | | **Station coverage minimums** | Per station: minimum number of each unit type or personnel role that should remain available, a radius for closest-unit mode, enabled flag. | Station response areas come from the **geofences** you draw on [Groups & Stations](groups-stations). +## How closest-unit mode measures a unit + +Closest-unit mode ranks units by **response time**: how long the crew needs to get moving (the *turnout*) plus the travel time to the call. Where a unit is measured from decides which turnout applies: + +![Closest unit response tuning with turnout times](/img/web-app/run-cards/closest-unit-tuning.png) + +| The unit is… | Measured from | Turnout added | +|---|---|---| +| In a status whose **base type is In Quarters** (see [Custom Statuses](custom-statuses)) | Its **station's location**, whatever its GPS says | **In-quarters turnout** | +| In any other available status, with a GPS position | Its **live GPS position** (subject to the maximum location age) | **Mobile turnout** | +| Without any GPS position | Its **station's location** — it is taken to be at home | **In-quarters turnout** | + +- Using the station for an in-quarters unit matters when the GPS comes from a tablet or phone: a device left on a desk, or a crew member's phone that went home, is not where the vehicle is. +- Both turnout times default to **0**, which ranks purely by distance (the behaviour before turnout times existed). Values above 1,800 seconds are capped. +- Travel time is a straight-line estimate unless **Order by driving ETA** is on, in which case the best candidates are re-ranked on turnout plus routed drive time. +- Example: an ambulance at its station 1 km away (2 min turnout + ~2 min travel) is ranked after an ambulance already on the road 1.5 km away (30 s turnout + ~3 min travel). +- A station needs coordinates (or a geofence, or an address that can be geocoded) on [Groups & Stations](groups-stations) for units to be placed there. + +### When the call has no location + +Closest-unit and station-based selection need the call's location. If the call has none, the card's **home station** is used instead and the recommendation says so; without a home station every requirement is reported as a shortfall (*"Call has no usable location"*). + +- On the **New Call** page the recommendation refreshes as soon as the call is placed on the map — by **Find Address**, **What3Words**, clicking the map or dragging the pin. Picking the priority and type first is fine. +- When a call is saved with an address but no map pin (from the web, the apps, the API, email or SMS import), Resgrid geocodes the address (or What3Words) before the run card runs. + ## Building a run card **New Run Card** opens an editor with five tabs. @@ -46,8 +73,9 @@ Station response areas come from the **geofences** you draw on [Groups & Station 2. The best-matching run card is found. Its alarm-level-1 requirements are filled from available resources using the selection mode. 3. If **auto-dispatch** is on, those resources are dispatched immediately; otherwise the New Call page shows the recommendation for the dispatcher to accept or edit. 4. Escalating the call's **alarm level** (from the call page or the apps) fills the next level's requirements. -5. If **move-up** is on and a station drops below its coverage minimum, a recommendation to relocate a unit appears. -6. The decision is recorded and can be captured as **evidence** on a [Record](records/authoring#evidence). +5. **Adding resources** to an active call, on the web [Update Call](dispatch-calls) page or in the [Dispatch app](../apps/dispatch#run-cards-and-recommendations), shows what the call's run card still needs at its current alarm level: the units and people already on the call count toward the requirements first (a unit of the required type, a person holding the required role, each counted once), and only what is missing is recommended. Nothing is dispatched until the dispatcher confirms. +6. If **move-up** is on and a station drops below its coverage minimum, a recommendation to relocate a unit appears. +7. The decision is recorded and can be captured as **evidence** on a [Record](records/authoring#evidence). ## Setup examples @@ -56,6 +84,7 @@ Station response areas come from the **geofences** you draw on [Groups & Station | **Volunteer fire, 2 stations** | *Structure fire* (priority High + type Fire): L1 Engine×2, Tender×1, Chief role×1; L2 adds Engine×1 from the neighbouring station. *Medical*: Rescue×1, EMT role×2. Station-based mode, auto-dispatch off (officer reviews). | | **Career fire, 5 stations** | Cards per type with closest-unit mode, auto-dispatch on, coverage minimums (1 engine per station), move-ups enabled. | | **EMS** | *ALS emergency*: Ambulance×1 + Paramedic role×1; *BLS*: Ambulance×1. Minimum staffing *Fully staffed*. | +| **EMS with recognised turnout times** (e.g. Belgian ambulance / MUG) | Closest-unit mode; *At station* status with base type **In Quarters**; *Available on the road* (radiofonisch) with base type **Available**; In-quarters turnout **120**, Mobile turnout **30**. | | **SAR** | *Missing person*: Team leader role×1, Searcher role×6, K9 role×1 — manual selection (people, not apparatus). | | **Security** | *Alarm response*: Patrol unit×1 closest-unit, auto-dispatch on; *Medical on site*: adds First-aid role×1. | | **Industrial ERT** | *Hazmat release*: Hazmat team×1 + Safety officer role×1 + Fire brigade×1; coverage minimum keeps one crew in the plant. | @@ -64,8 +93,9 @@ Station response areas come from the **geofences** you draw on [Groups & Station | Item | Value | |---|---| -| Routes | `/User/RunCards/{Index,New,Edit,Preview}`, `/User/Dispatch/GetDispatchRecommendation?priority=&type=&latitude=&longitude=&alarmLevel=` | -| Settings | Department settings 58–60 (dispatch mode, auto-dispatch, staffing gate); station coverage rows per group | +| Routes | `/User/RunCards/{Index,New,Edit,Preview}`, `/User/Dispatch/GetDispatchRecommendation?priority=&type=&latitude=&longitude=&alarmLevel=`; v4 `GET RunCards/GetRecommendation` (new call) and `GET RunCards/GetCallRecommendation?callId=&alarmLevel=` and `/User/Dispatch/GetCallDispatchRecommendation?callId=&priority=&type=&latitude=&longitude=` (Update Call; form values override the stored call) (adding resources, both built by `DispatchRecommendationRequest.ForCallInProgress`: `DispatchRecommendationRequest.CountDispatchedTowardRequirements` at the call's current level; a higher level previews Strike Next Alarm, filled in full) | +| Settings | Department settings 58–60 (dispatch mode, auto-dispatch, tuning). Setting 60 is `DispatchRecommendationConfig`: location ages, radius, stale inclusion, routed ETA + shortlist, rest period, staffing gate, move-up, `InQuartersTurnoutSeconds`, `MobileTurnoutSeconds`. Station coverage rows per group | +| Unit placement | `UnitResponseOrigin` (shared with the New Call nearest-units board): In Quarters base type (23) → station, else GPS fix, else station. Results carry `PositionSource`, `TurnoutSeconds`, `ResponseSeconds` (turnout + travel); `EtaSeconds` is travel only | | Model | `RunCard`, `RunCardTrigger`, `RunCardAlarmLevel`, `RunCardUnitRequirement`, `RunCardRoleRequirement`, `RunCardStatusSelection`, `StationCoverageMinimum` | | Feature flag | `Dispatch.RunCards` (seeded by M0116) | | Workflow events | Run-card activation, escalation and move-up events (48–51) are available as triggers | diff --git a/docs/web-app/search.md b/docs/web-app/search.md index 2086350..ecab719 100644 --- a/docs/web-app/search.md +++ b/docs/web-app/search.md @@ -5,55 +5,142 @@ title: Search # Search -The Search module provides a quick navigation command palette for accessing application features. +**Search** finds things across the whole department in one place: calls (including call notes), Records reports, people, units, contacts, occupancies, messages, notes, documents, protocols, trainings, calendar events, shifts, groups and stations, points of interest, legacy logs, deployments and — with Business Ops — invoices, bids, contracts and rate cards. Search by name, number, address or any words in the text. You only ever see results you are allowed to open. + +There are two ways in: + +- **The search box in the top bar** — quick answers while you type, plus **Go to** shortcuts to pages and actions. +- **The Search page** — every match, with type and date filters, sorting, paging and a CSV export. Press **Enter** in the top-bar box (or pick **Search all results**) to open it. + +Search is switched on per department by Resgrid (the `Search.Unified` feature flag). When it is off, the Search page says *Search is not available for your account* and the top-bar box offers only the **Go to** shortcuts. ![Search results](/img/web-app/home/search-results.png) -## How It Works +## The top-bar search box + +Click the box to see **Go to** shortcuts — the pages and actions you are allowed to use, such as *New Call*, *Archived Calls*, *Add Person*, *Manage Invites* or *Two-Factor Authentication*. Start typing and the list narrows to the best shortcuts (up to 8) and the best matching items (up to 10), grouped by type. Pick one to open it. + +- Shortcuts understand everyday words and small typos: *new call*, *invite*, *2fa*, *roster*. +- **Search all results** (always the last row) or **Enter** opens the Search page for what you typed. +- Records reports are not listed in the box — use the Search page for those. +- On phones and small tablets the box is replaced by a **search icon** in the top bar, which opens the Search page. + +## The Search page + +| Control | What it does | +|---|---| +| **Search box** | The words to look for (see [Writing a search](#writing-a-search)). | +| **Search in** | **Everything**, or one type: Calls, Reports (Records), Logs, Personnel, Units, Contacts, Occupancies (Pre-plans), Points of Interest, Groups & Stations, Messages, Notes, Documents, Protocols, Trainings, Calendar, Shifts, Deployments, Invoices, Bids, Contracts, Rate Cards, Certification Types. Only the types you may view are listed. | +| **From / To** | A date range in your department's time zone. Both days are included; a reversed range is swapped. Which date each type uses is listed in [What you can find](#what-you-can-find). | +| **Sort by** | **Best match** (default), **Newest first** or **Oldest first**. | +| **Export CSV** | Downloads the matching results (see below). Shown once there are results. | + +Changing a filter re-runs the search straight away. + +### Reading the results + +Each result shows an icon and type badge, the **title** (click anywhere on the row to open it), then whatever applies: number, date, status and category. Below that is the item's summary and, when the match was found deeper in the text, an excerpt around it. The words you searched for are highlighted. + +Results come 25 to a page with **Previous** / **Next**. + +### How many results -**Authorization:** `Department_View` policy +When Resgrid can prove the exact number of results you are allowed to see, the page says *Showing 1–25 of 140* and shows the page number. When it cannot, the page says *Showing 1–25* and, if there are more, *There are more matches than can be counted here*. -The `GetSearchResults` endpoint returns a curated list of application navigation shortcuts that can be filtered by a search query. +An **Everything** search with no dates looks at the best 200 matches. Choosing a **type** or a **date range** looks at up to **1,000** — narrow the search that way when you need a complete count or list. -### Available Navigation Items +### Export CSV -| Item | URL Target | -|------|-----------| -| Calls | Dispatch dashboard | -| Personnel | Personnel list | -| Units | Units list | -| Mapping | Map view | -| Shifts | Shifts list | -| Logs | Logs list | -| Reports | Reports dashboard | -| Calendar | Calendar view | -| Notes | Notes list | -| Documents | Documents list | -| Trainings | Trainings list | -| Inventory | Inventory overview | -| Inbox | Message inbox | -| Profile | User profile | -| Department Settings | Department settings | -| Security | Security settings | +**Export CSV** downloads every matching result you can open, up to **1,000** rows, with the same type, dates and sort as the page. Columns: *Type, Title, Number, Date, Status, Category, Summary, Match, Link*. Dates are in your department's time zone; *Number* is filled for calls and occupancies; *Match* is the excerpt around the match; *Link* opens the item. The file is named `search--.csv` (`search-all-…` for Everything). -### Conditional Items +## Writing a search -Some items are shown only when the user has appropriate permissions: +| You type | It finds | +|---|---| +| `engine 1` | Results containing **every** word, in any field — title, number, summary or text. | +| `"trouble alarm"` | The exact phrase. Combine phrases and words: `"building 4" sprinkler`. | +| `eng` | The **last word may be unfinished**: names and numbers starting with it match at once (*Engine 1*, *Engineer*); words in the body text match once you have typed 3 letters. | +| `26-1188`, `1HGCM82633A004352` | Numbers and identifiers: call, incident, reference and record numbers, invoice, bid and contract numbers, VIN and plate, member ID, occupancy and parcel numbers. | +| `3125550151` | Phone numbers of callers, contacts and alarm companies — type the digits without spaces or dashes; the start of the number is enough. | +| `110 Main Street` | For calls and occupancies, a street address also finds the same address written differently (*110 Main St*). Address matches come first. | -| Item | Condition | -|------|-----------| -| New Call | User can create calls | -| Add Person | User can add personnel | -| Manage Invites | User can add personnel | +Matching ignores capitals and common English words (*the*, *and*, *of*). Nothing else is special syntax: `AND`, `OR`, `*` and `-` have no special meaning. -### Filtering +**Reports (Records)** are searched in their own index: all words are required, but quotes do not force an exact phrase and the last word is not completed for you. Under **Best match**, reports are listed after the other results. -When a query is provided, results are filtered by matching against the item label and summary text. +## What you can find + +Every result is checked again when you search: you see it only if you could open it from its own page, and only while its module is switched on for the department. + +| Type | What is searched | Who sees it | Opens | Date used | +|---|---|---|---|---| +| **Calls** | Name, number, incident / reference / external numbers, nature, type, address, caller name and number, dispatch notes, closing notes, **every call note**, and custom call fields | Anyone who can view calls; group-limited dispatch applies | The call | Logged on | +| **Reports (Records)** | Record number, summary, call number and the safe fields of the report; the **narrative** when your department's search index includes it (see [Records → Settings](records/settings#search)) | Administrators and members who can view records, within their group visibility; needs Records activated | The report | Occurred on | +| **Logs** | Log type, course, instructors, agencies and units; narrative, location, cause and people fields | Anyone who can view logs | The log | Started on | +| **Personnel** | Name, ID number, group, roles and custom fields. Phone numbers, e-mail and addresses are **never** searched | Members who can view users (respecting *Group only*); you can always find yourself. Deleted, disabled and hidden members never appear | The person | Profile last updated | +| **Units** | Name, type, station, VIN, plate and custom unit fields | Members who can view units (respecting *Group only*) | The unit's edit page if you may edit it, otherwise its events page | When last indexed | +| **Contacts** | Names, company, addresses, e-mail, phone numbers, category, website, other info, contact notes and custom fields | Anyone who can view contacts | The contact | When last indexed | +| **Occupancies (Pre-plans)** | Name, number, parcel id, address, hazards, alarm company and phone, panel location, tactical summary. Gate codes, Knox box locations, emergency contacts and access notes are **never** searched | Members who can view records, with occupancies enabled | The occupancy | Last modified | +| **Points of Interest** | Name, type, address and note | Anyone, when the Mapping module is on | The point of interest | When last indexed | +| **Groups & Stations** | Name and address | Anyone who can view groups | The group's edit page if you may edit it, otherwise its row on the Groups & Stations list | When last indexed | +| **Messages** | Subject and body | **Only the sender and recipients** — administrators included | The message | Sent on | +| **Notes** | Title and body | Anyone who can view notes; admin-only notes to administrators; expired notes are hidden | The note | Added on | +| **Documents** | Name, description, file name, category and type. The **contents of files are not searched** | Anyone who can view documents; admin-only documents to administrators | The document | Added on | +| **Protocols** | Name, code, description and protocol text | Anyone who can view protocols | The protocol | Last updated | +| **Trainings** | Name, description and training text | Anyone who can view trainings | The training | Created on | +| **Calendar** | Title, location and description (one result per recurring series) | Anyone who can view the calendar | The event | Start | +| **Shifts** | Name and code | Anyone who can view shifts | The shift calendar | Start day | +| **Deployments** | Name, status, incident / resource order / request numbers, RMS order id, cost code, point of hire. Notes, time reports and expenses are **never** searched | Administrators, members who can view deployments, and members **on the deployment's roster** | The deployment | Start | +| **Invoices** | Invoice number, status, issue date, currency, linked deployment and contract. Amounts, lines and customer details are **never** searched | Members who can view invoicing, with [Business Ops](business-ops/overview) | The invoice | Issued on | +| **Rate Cards** | Name, status and description | Members who can view invoicing, with Business Ops | The rate card | Added on | +| **Bids** | Bid number and title, status, incident number, requested start | Members who can view bids, with Business Ops | The bid | Added on | +| **Contracts** | Contract number, name, status and term | Members who can view contracts, with Business Ops | The contract | Start | +| **Certification Types** | Name, code, issuing authority and description. Members' certification records are **never** searched | Administrators and members who can view or set up certifications | The type | When last indexed | + +*Custom fields* are searched only when their visibility is **Everyone** and they are not marked sensitive. Very long text is searched up to its first 8,000 characters (32,000 for calls and logs). + +### Advanced Data Protection + +When the department is enrolled in [Advanced Data Protection](data-protection), protected text is not searchable: call details and notes (the call **number** still works), report narratives, log narratives, message subjects and bodies, document names, personnel ID numbers and custom fields. **Contacts** and **calendar events** drop out of search entirely. Names, numbers and everything that is not protected keep working. + +## How up to date it is + +- New and edited items are searchable within about **1–2 minutes**. +- The first time anyone in a department searches, Resgrid builds the department's search index. Until it finishes, the page says *Your department's search index is being built* and results may be incomplete for a few minutes. +- *The search index is not available right now* means the search service is briefly unavailable — try again shortly. +- **Every call** the department has ever logged is searchable, active or closed, however old — on the hosted service, and on any installation that leaves `CallRebuildYears` at 0. An installation that sets it to a positive number indexes only that many recent years and turns the call history backfill off, so calls older than that are not found. + +## Setup examples + +Nothing needs configuring: once search is on, every member can use it within their own permissions. Some ways departments use it: + +| Department type | How they use search | +|---|---| +| **Fire** | Type the street address on the way to a call to see earlier calls there and the occupancy pre-plan; search `standpipe` or `"fire alarm panel"` across pre-plans and call notes. | +| **EMS** | Find a run by incident number; choose **Calls** and a date range, sort **Oldest first** and **Export CSV** for a QA review. | +| **SAR** | Search a trailhead or area name to find past callouts and their notes; find members by role (`K9`, `rope`). | +| **Emergency management** | Find partner agencies in Contacts by company, plans in Documents, and past activations by name. | +| **Security / industrial** | Look up a site by address or alarm company phone; find a unit by plate or VIN. | +| **Contract services** | Find a deployment by resource order or incident number, then its bids, contracts and invoices by number. | ## Technical reference +| Item | Value | +|---|---| +| Routes | `/User/Search` (`Index`: `q`, `type`, `from`, `to`, `sort`, `page`), `/User/Search/Export`, `/User/Search/GetSearchResults?query=` (top-bar box) — all `Department_View` | +| API | `GET api/v4/Search/Search` (`query`, `types`, `skip`, `take` ≤ 100, `fromUtc`, `toUtc`, `sort`), `GET api/v4/Search/Typeahead` (prefix match on titles and identifiers, `take` ≤ 25); administrators: `POST api/v4/Search/Rebuild` (queues a rebuild of the department's index), `GET api/v4/Search/Health` | +| Feature flag | `Search.Unified` (seeded off, M0208); see [Feature flags](../reference/feature-flags) | +| Installation config | `SearchConfig.Enabled` (search host, every process), `IndexPath`, `MaxPageWindow` (1,000), `MaxResults` (200, Records), `CallRebuildYears` (0 = every year; a positive value limits a rebuild to that many recent years and turns the call history backfill off), `CallBackfillBatchSize` (250), `CallBackfillSecondsPerSweep` (20; 0 = off); optional S3 object store `S3Endpoint` / `S3Bucket` / `S3Prefix` (web processes re-read the published index every `ReaderPullSeconds`, 30) | +| Workers | 70 `SearchIndexCommand` — every minute: catches up changed items, rebuilds a department when its index generation changes or a rebuild is requested (up to `MaxRebuildsPerSweep` per run), then spends up to `CallBackfillSecondsPerSweep` on the **call history backfill** — one batch per department per run, newest call first, adding only calls search does not hold (it restores calls that rebuilds before October 2026 left out, without taking any department's results offline); 44 — the Records index | +| Model | `SearchProjections` (one row per searchable item), `SearchIndexStates` (+ `CallBackfillCursor`, `CallBackfillCompletedOn`, M0261), `SearchIndexLeases`; type names in `SearchEntityTypes` | +| Services | `IUnifiedSearchService`, `ISearchProjectionService`, `ISearchIndexMaintenanceService`, `IGlobalSearchService`, `ISystemActionsService` (91 **Go to** shortcuts in `SystemActionCatalog`), `IRecordsSearchService` | +| Limits | 25 results per page; 200 candidates for Everything, 1,000 with a type or dates; export 1,000 rows; query 500 characters | +| Data protection | Protected text is indexed only while Advanced Data Protection is not enforced, and returned only while the department's policy is disabled | + ### Interactions with Other Modules | Module | Interaction | |--------|-------------| -| **All Modules** | Provides navigation shortcuts to all feature areas | -| **Security** | Conditional items based on permissions | +| **Security** | Every type follows the view permission of its own module, including *Group only* for users and units | +| **Department Settings** | A module switched off (Messaging, Documents, Notes, Training, Calendar, Shifts, Logs, Mapping, Business Operations) removes its type from search | +| **Records** | Reports and occupancies come from Records; narrative search status is shown on [Records → Settings](records/settings#search) | +| **Advanced Data Protection** | Withdraws protected text from search | diff --git a/docs/web-app/security-permissions.md b/docs/web-app/security-permissions.md index a22a4fd..6214e6c 100644 --- a/docs/web-app/security-permissions.md +++ b/docs/web-app/security-permissions.md @@ -9,6 +9,8 @@ title: Security & Permissions ![Security and permissions](/img/web-app/security/index.png) + + ## Permission levels Every permission is set to one of four levels. Changes take effect at the member's next login. @@ -77,7 +79,7 @@ All default to *department administrators*. See the [Workforce & Business Ops ov |---|---| | Manage invoicing / View invoicing | Create, edit, send and void invoices, record payments, rate cards and billing profiles / read-only invoices, aging and PDFs. | | Manage certifications / View certifications / Manage certification setup | Other members' certification records, credits and unit records / the expiry dashboard / types, role requirements and settings. Members always see their own records. | -| Manage deployments / Approve time reports | Deployments, rosters, equipment, expenses, files and status; see every deployment / approve and void submitted daily time reports. Rostered members always see their own deployments and file time. | +| Manage deployments / Approve time reports | Deployments, rosters, equipment, expenses, files and status, and external orders (which also need *Create records*); see every deployment / approve and void submitted daily time reports. Rostered members always see their own deployments and file time. | | Manage bids / Manage contracts | Bids and the deployment wizard / service contracts, document requirements and compliance documents. | | Manage Cal OES MARS reimbursement | Agency, F-5, annual rates, agreements, handoff, observed statuses, invoice approval and payment reconciliation. Rostered members prepare their own F-42 and expense drafts without it. | | View internal costs | Aggregate field-cost summaries, resource cost profiles and usage readings (never a person's rate). | @@ -90,6 +92,15 @@ All default to *department administrators*. See the [Workforce & Business Ops ov |---|---| | Manage data protection settings · View / edit protected call data · View protected personnel / contact / operational data · Export protected data · Configure protected data delivery · Emergency break-glass access | See [Advanced Data Protection](data-protection). | +### Import & Migration + +These two are fixed to **department administrators** (and the managing user). They are not listed on this screen and cannot be widened to other members or roles. + +| Permission | Controls | +|---|---| +| **Manage Department Import** (72, `ManageDepartmentImport`) | Everything in [Import & Migration](import-and-migration/overview): upload files, match columns and values, fix issues, approve and run imports, roll them back, activate and invite imported people, and grant or revoke Resgrid support access. | +| **Manage Record Imports** (73, `ManageRecordImports`) | Reserved for importing third-party incident history into [Records](records/overview) and deleting such an import. Kept separate so a configuration import never implies the right to write history into Records; not used by the current release. | + ## Two-factor enforcement **Require 2FA for admins**: *Disabled*, *Department admins + managing user*, or *… + group admins*. You cannot enable it until you and the managing user both have 2FA on your own accounts. Affected members are sent to the setup page at next login. @@ -122,6 +133,19 @@ All default to *department administrators*. See the [Workforce & Business Ops ov ![SSO](/img/web-app/security/sso.png) +## API keys + +`/User/Security/ApiKeys` (the **API Keys** button on the Security page) — keys that let another system call the Resgrid API for the department without a member's login. Department admins only; creating or revoking a key asks for a fresh second factor, so the admin needs [two-factor sign-in](account-security) set up first. + +![API keys](/img/web-app/security/api-keys.png) + +- **Create a key**: a name (what it is for), what it may do (**scopes**: read calls, create calls including pending and scheduled ones, update and dispatch calls, close calls, read reference data, read units), when it expires (30 days to 2 years) and, optionally, the IP addresses or CIDR ranges it may be used from. +- The key (`rgk_…`) is shown **once**, right after it is created. Copy it into the other system then; it cannot be shown again. +- The list shows each key's prefix, scopes, created, expiry and **last used** time, and its status (*Active*, *Expired*, *Revoked*). **Revoke** stops a key at once. +- A department can hold up to 25 active keys. Creating and revoking keys is audit-logged. + +How an integration uses a key, the endpoints each scope opens and the error codes: [API authentication → Department API keys](../api/authentication#department-api-keys). + ## Setup examples | Department | Recommended permission changes | @@ -137,7 +161,8 @@ All default to *department administrators*. See the [Workforce & Business Ops ov | Item | Value | |---|---| -| Controller | `SecurityController` (`Index`, `Audits`, `ViewAudit`, `Sso`, `SsoNew`, `SsoEdit`, `ScimSetup`, `SecurityPolicy`) | +| Controller | `SecurityController` (`Index`, `Audits`, `ViewAudit`, `Sso`, `SsoNew`, `SsoEdit`, `ScimSetup`, `SecurityPolicy`, `ApiKeys`, `CreateApiKey`, `RevokeApiKey`) | +| API keys | Table `DepartmentApiKeys` (migration M0265): name, key prefix, keyed HMAC-SHA256 hash of the key (never the key), scopes, allowed IP ranges, created, expires, last used, revoked. `IDepartmentApiKeysService`; API scheme `DepartmentApiKey` (header `X-Resgrid-ApiKey`) runs only on actions marked `[DepartmentApiKeyScope]`. Config: `SecurityConfig.DepartmentApiKeyPepper` (blank = derived from the encryption key), `DepartmentApiKeyMaxLifetimeDays` (730), `DepartmentApiKeyMaxActivePerDepartment` (25), `DepartmentApiKeyMaxFailuresPerAddress` / `DepartmentApiKeyFailureWindowMinutes` (20 per 10 min). Audit types `DepartmentApiKeyCreated`, `DepartmentApiKeyRevoked`. | | Actions | `SetPermission?type=&level=`, `SetPermissionData?type=` (role ids), `GetRolesForPermission?type=`, `GetAuditLogsList` | | Model | `Permission` (`PermissionType`, `Action` 0–3, `LockToGroup`, `Data` = role ids); `PermissionTypes` enum; `AuditLog` | | Cache | Permission changes raise `SecurityRefreshEvent` to invalidate the authorization matrix; `Resgrid.Console --SecurityRefresh` refreshes it manually | diff --git a/docs/web-app/shifts.md b/docs/web-app/shifts.md index c500da9..e479757 100644 --- a/docs/web-app/shifts.md +++ b/docs/web-app/shifts.md @@ -11,6 +11,8 @@ title: Shifts ![Shifts](/img/web-app/shifts/index.png) + + ## Shift Lifecycle ``` diff --git a/docs/web-app/subscription-billing.md b/docs/web-app/subscription-billing.md index d6b167d..e94a321 100644 --- a/docs/web-app/subscription-billing.md +++ b/docs/web-app/subscription-billing.md @@ -11,6 +11,8 @@ title: Subscription & Billing ![Subscription](/img/web-app/subscription/index.png) + + ## Subscription Dashboard **Authorization:** `Department_Update` + `CanUserManageSubscription` runtime check diff --git a/docs/web-app/templates.md b/docs/web-app/templates.md index c7617a0..5889b9d 100644 --- a/docs/web-app/templates.md +++ b/docs/web-app/templates.md @@ -9,6 +9,8 @@ The Templates module provides call quick templates and call note autofills that ![Call templates](/img/web-app/templates/index.png) + + ## Call Quick Templates ### Template List diff --git a/docs/web-app/trainings.md b/docs/web-app/trainings.md index 26aa749..c17cf58 100644 --- a/docs/web-app/trainings.md +++ b/docs/web-app/trainings.md @@ -11,6 +11,8 @@ title: Trainings ![Trainings](/img/web-app/trainings/index.png) + + ## Training List Displays all trainings for the department. diff --git a/docs/web-app/types-configuration.md b/docs/web-app/types-configuration.md index be73e65..ae9ad70 100644 --- a/docs/web-app/types-configuration.md +++ b/docs/web-app/types-configuration.md @@ -11,6 +11,8 @@ title: Types & Configuration ![Types](/img/web-app/types/index.png) + + ## Unit Types Define categories for units (Engine, Ladder, Ambulance, etc.): @@ -20,8 +22,15 @@ Define categories for units (Engine, Ladder, Ambulance, etc.): | Field | Description | |-------|-------------| | Type Name | Unit type name (required, unique) | +| Class | What kind of unit it is (Engine, Aerial, Ambulance …), see [Classes and meanings](#classes-and-meanings) | | Custom State ID | Associate with a custom unit state set | -| Map Icon Type | Icon used on maps | +| Map Icon Type | Built-in icon used on maps | +| Custom icon | Optional image of your own. Units of this type show it beside their name in lists, pickers and the apps, and on the map in place of the map icon. See [Custom map icons](mapping#custom-map-icons) | +| Status map icons | On Edit: opens the page where you upload an icon for each status of the type's status set, shown on the map while a unit of the type is in that status. See [Status and priority icons](mapping#status-and-priority-icons) | + +The **Custom icon** field shows the image rules next to the file picker and a live preview: how the icon looks on a light map, on a dark map, in a list and as the stored 128 × 128 image. It is labelled with the type name you typed. The file is checked as soon as you choose it, so a file that cannot be used is never uploaded. + +![Custom icon picker with a new icon chosen](/img/web-app/types/custom-icon-preview.png) ### Operations - **Create** — `Department_Update` + `CanUserAddUnitTypeAsync` @@ -39,7 +48,12 @@ Define incident categories (Fire, EMS, MVA, etc.): | Field | Description | |-------|-------------| | Type Name | Call type name (required) | -| Map Icon Type | Icon used on maps | +| Class | What kind of call it is (Fire, Medical, Rescue …), see [Classes and meanings](#classes-and-meanings) | +| Map Icon Type | Built-in icon used on maps | +| Custom icon | Optional image of your own. Calls of this type show it beside the type in the call lists and the apps, and on the map in place of the map icon. See [Custom map icons](mapping#custom-map-icons) | +| Priority map icons | On Edit: opens the page where you upload an icon for each call priority, shown on the map while a call of the type has that priority. See [Status and priority icons](mapping#status-and-priority-icons) | + +Calls remember which call type they were logged with, so **renaming a call type** keeps its old calls linked to it (check-in timer overrides, run cards and protocols keyed on the type still apply to them). Protocol triggers and call templates that name the type are renamed with it. ### Operations - **Create** — `Department_Update` + `CanUserAddCallTypeAsync` @@ -55,6 +69,7 @@ Define urgency levels for calls with visual and audio indicators: | Field | Description | |-------|-------------| | Priority Name | Display name (required, unique) | +| Meaning | Which standard priority it means: Low, Medium, High or Emergency, see [Classes and meanings](#classes-and-meanings) | | Color | Priority color (hex) | | Is Default | Default priority (only one allowed) | | Dispatch Personnel | Whether to auto-dispatch personnel | @@ -72,6 +87,45 @@ Push notification and iOS push sound upload features are currently disabled (cod - **Edit** — Same validations - **Delete** — Soft-deletes (`IsDeleted = true`) +Until you add a priority of your own, calls use the four built-in priorities (Low, Medium, High, Emergency). Once you add one, your priorities replace the built-in ones. + +A priority's meaning also sets the color of its calls' map pins ([icons by status and priority](mapping#icons-by-status-and-priority)): Low green, Medium yellow, High orange, Emergency red, and gray for a priority with no meaning whose name suggests none. The [Map Icon Legend](mapping#map-icon-legend) lists each of your priorities under the color it takes. + + + +## Classes and meanings + +Call types, unit types and call priorities are named however your department likes: *Code 3 Medical*, *Pumper*, *Priority 1*. A **class** (call and unit types) or **meaning** (priorities) tells Resgrid what each one is, the same way a [status meaning](custom-statuses#status-meanings) does for statuses. Resgrid uses it, not the name, for reports, defaults and integrations, and for comparing priorities across departments and apps, such as sorting by urgency. A new or existing type starts with **None**. + +The edit page shows **Suggested from the name: …** under the picker when the name gives a clear hint, for example *Fire* for *STRUCTURE FIRE*. It is only a hint: Resgrid never sets a class for you, so pick it and press **Update** to keep it. + +![Edit Call Type: the Class picker on None with "Suggested from the name: Fire"](/img/web-app/types/call-type-class.png) + +![Edit Unit Type: the Class picker on None with "Suggested from the name: Engine"](/img/web-app/types/unit-type-class.png) + +![Edit Call Priority: the Meaning picker on None with "Suggested from the name: Emergency"](/img/web-app/types/call-priority-meaning.png) + +| List | Choices | +|---|---| +| **Call type class** | Fire, Medical, Rescue, Traffic Collision, Hazardous Materials, Alarm, Service Call, Law Enforcement, Disaster or Weather, Mutual Aid, Non-Emergency Activity (training, drills, standby, planned events), Other | +| **Unit type class** | Engine, Aerial, Rescue, Tanker, Ambulance, Medical Response (non-transporting), Wildland, Hazardous Materials, Command, Support, Watercraft, Aircraft, Patrol, Other | +| **Priority meaning** | Low, Medium, High, Emergency. The built-in priorities are their own meaning. | + +The classes are deliberately broad so they fit any country and discipline. NERIS incident types are mapped separately, on [Records](records/overview) incident reports. + +| Your name | Class or meaning | +|---|---| +| Call type *STRUCTURE FIRE*, *Brush Fire*, *Vehicle Fire* | Fire | +| Call type *MVA*, *TRAFFIC ACCIDENT* | Traffic Collision | +| Call type *Lift Assist*, *Lockout* | Service Call | +| Call type *Fire Alarm* | Alarm | +| Call type *SAR*, *Missing Hiker* | Rescue | +| Unit type *Pumper*, *Quint* | Engine, Aerial | +| Unit type *Medic*, *ALS*, *QRV* | Ambulance, Ambulance, Medical Response | +| Unit type *Brush*, *Tender*, *Utility* | Wildland, Tanker, Support | +| Priority *Code 3*, *Echo* | Emergency | +| Priority *Routine*, *Non-emergency* | Low | + ## Certification Types Define categories for personnel certifications (EMT-B, Paramedic, Firefighter I, etc.): @@ -153,6 +207,16 @@ All operations use: `TypesController` (+ `Department/Types` index page); routes `/User/Types/{NewUnitType,EditUnitType,NewCallType,EditCallType,NewCallPriority,EditCallPriority,NewCertificationType,NewDocumentType,NewNoteType,NewContactNoteType,ListOrdering}`; model `UnitType`, `CallType`, `DepartmentCallPriority` (colour, sound, `IsDefault`, `Tone`, `DispatchPersonnel/Units`), `CertificationType`, `DocumentCategory`, `NoteCategory`, `ContactNoteType`. +| Item | Value | +|---|---| +| Classes and meanings | `CallType.BaseType` (a `CallTypeClasses` value), `UnitType.BaseType` (`UnitTypeClasses`), `DepartmentCallPriority.BaseType` (a `CallPriority` value, 0 Low to 3 Emergency; built-in priorities are their own). -1 = none. A posted value that is not in the enum is saved as -1 | +| Suggestions | `BaseTypeSuggestions.SuggestCallTypeClass`, `SuggestUnitTypeClass`, `SuggestPriority`; shown on the edit pages only while the value is -1, never saved on their own | +| Call type link | `Call.CallTypeId`: the call type a call was logged with (`Call.Type` keeps the name). Worked out from the name when a call is saved (`CallTypeLink`); a call already linked keeps its link after a rename. Null when the name matches no call type | +| Rename | Editing a call type's name also renames it in protocol triggers (`IProtocolsService.RenameCallTypeInTriggersAsync`) and call quick templates (`ITemplatesService.RenameCallTypeInTemplatesAsync`) | +| API | v4 `CallTypes` and `CallPriorities` results include `BaseType`; v4 call results include `TypeId` (the linked call type's id, or null) | +| Custom icons | `UnitType.IconKey` / `CallType.IconKey` point at the type's row in `TypeIcons` (migration M0285). Uploads are read by `TypeIconUploads`, checked and re-encoded by `TypeIconRenditions` (PNG, JPEG, GIF first frame or WebP; at most 1 MB and 4096 px; at least 16 px; stored as a 128 × 128 transparent PNG) and saved after the type's own fields. The picker is the shared partial `_TypeIconPicker` with `resgrid.types.iconpicker.js`. Deleting a type deletes its icon. See [Custom map icons](mapping#technical-reference-for-custom-icons) | +| Migration | M0272 (`M0272_AddListBaseTypes`, PostgreSQL `M0272_AddListBaseTypesPg`): adds `BaseType` (default -1) to `CallTypes`, `UnitTypes` and `DepartmentCallPriorities`, adds `Calls.CallTypeId` and links existing calls to their department's call type of the same name | + ### Interactions with Other Modules | Module | Interaction | |--------|-------------| @@ -163,5 +227,5 @@ All operations use: | **Notes** | Note categories used for filtering | | **Contacts** | Contact note types used for note classification | | **Certifications** | Certification types used in personnel profiles | -| **Mapping** | Map icon types for calls and units | +| **Mapping** | Map icon types, custom icons and status / priority icons for calls and units ([Custom map icons](mapping#custom-map-icons), [Map icon legend](mapping#map-icon-legend)) | | **Dashboard** | Personnel status ordering affects status display | diff --git a/docs/web-app/unit-tracking.md b/docs/web-app/unit-tracking.md index f97bfde..b68cd41 100644 --- a/docs/web-app/unit-tracking.md +++ b/docs/web-app/unit-tracking.md @@ -11,6 +11,8 @@ Units normally report their position from the **Unit app** on a phone or tablet. ![Hardware tracking](/img/web-app/units/tracking-index.png) + + ## Concepts | Term | Meaning | @@ -41,7 +43,7 @@ Then, for HTTPS profiles, **Create credential** (choose the **authentication mod The binding's **Tracking status** shows last received, last valid fix, last error code and delivery health. Department administrators (outside production) can **Send test JSON** to validate a generic payload without authenticating or storing it. **Disable tracking** revokes every credential for the binding. -Positions from hardware trackers flow through the same pipeline as app positions: the unit appears on the Mapping page, in the Dispatch and Big Board apps, feeds closest-unit [run-card](run-cards) selection and can be captured as *Unit tracking fixes* evidence on a [Record](records/authoring#evidence). +Positions from hardware trackers flow through the same pipeline as app positions: the unit appears on the Mapping page, in the Dispatch and Big Board apps, feeds closest-unit [run-card](run-cards) selection and the New Call nearest-units board (except while the unit is in an **In Quarters** status, when its station's location is used instead — see [How closest-unit mode measures a unit](run-cards#how-closest-unit-mode-measures-a-unit)) and can be captured as *Unit tracking fixes* evidence on a [Record](records/authoring#evidence). ## Setup examples diff --git a/docs/web-app/units.md b/docs/web-app/units.md index 6c4f8be..fb38a2c 100644 --- a/docs/web-app/units.md +++ b/docs/web-app/units.md @@ -9,6 +9,8 @@ A **unit** is anything that responds as one thing and has a status of its own: a ![Units](/img/web-app/units/index.png) + + ## Where to find it **Left menu → Units.** Units are listed by station/group with type, current state and timestamp. Buttons: **Events**, **Logs**, **Edit**, **Delete**; select several to **set status** at once (only units sharing the same status set can be selected together). **Unit Staffing** and **New Unit** are in the toolbar. @@ -27,6 +29,10 @@ A **unit** is anything that responds as one thing and has a status of its own: a Adding is blocked when the plan's unit limit is reached. +:::tip Have a spreadsheet? +To add many units and unit types at once — from an apparatus list or the system you are leaving — use [Import & Migration](import-and-migration/overview) (**Department menu → Import & Migration**, department administrators, where it is turned on). Every row is checked and previewed before anything is saved. See the [Units field reference](import-and-migration/units). +::: + ## Unit status Set a unit's status from the list, the [Dashboard](dashboard), the Unit app or the API. Statuses come from the default set — Available, Delayed, Unavailable, Committed, Out of Service — or, more usually, from [custom unit statuses](custom-statuses) defined per unit type (Responding, On Scene, Transporting, At Hospital, Returning …). A status can require a **destination** (a station or an active call) and carries an optional note and location. Statuses drive dispatch availability, the map, Big Board and reports. diff --git a/docs/web-app/user-defined-fields.md b/docs/web-app/user-defined-fields.md index 4dd1e45..7fd9546 100644 --- a/docs/web-app/user-defined-fields.md +++ b/docs/web-app/user-defined-fields.md @@ -15,6 +15,8 @@ The User Defined Fields module allows departments to define, manage, and view cu --- + + ## Overview UDF fields are defined once per entity type and automatically appear in the relevant create/edit/view forms throughout the web application. The system uses a **versioned definition** model — each time a department updates its field configuration, a new version of the definition is created. Existing records remain linked to the version that was active when they were saved, preserving historical data integrity. diff --git a/docs/web-app/voice-audio.md b/docs/web-app/voice-audio.md index b888ac5..ed3296b 100644 --- a/docs/web-app/voice-audio.md +++ b/docs/web-app/voice-audio.md @@ -13,6 +13,8 @@ The Voice module manages VoIP voice channels and audio streams for department co Voice capability is checked at every action via `CanDepartmentUseVoiceAsync`. This feature requires an appropriate subscription plan or PTT addon. ::: + + ## Voice Channels ### Channel List diff --git a/docs/web-app/weather-alerts.md b/docs/web-app/weather-alerts.md index 0c6b263..e16d4e7 100644 --- a/docs/web-app/weather-alerts.md +++ b/docs/web-app/weather-alerts.md @@ -15,6 +15,8 @@ The Weather Alerts module automatically ingests severe weather alerts from gover --- + + ## Overview The Weather Alert system connects to external weather providers, polls for alerts on a configurable schedule, and surfaces them inside Resgrid. The end-to-end flow is: diff --git a/docs/web-app/work-orders.md b/docs/web-app/work-orders.md index eb02215..b971ce7 100644 --- a/docs/web-app/work-orders.md +++ b/docs/web-app/work-orders.md @@ -13,11 +13,13 @@ Work Orders and the preventive-maintenance engine are part of the paid **Readine ![Work orders list](/img/web-app/work-orders/index.png) + + ## Where to find it **Left menu → Work Orders.** The landing page is the filterable list. The toolbar links to **New work order**, **Preventive maintenance** (recurring schedules), **Operations policy**, **Bulk operations**, **Maintenance reports** and **Service history**. -Filters: status, priority, type, target (unit / group / equipment), **Assigned to me**. +Filters: **number**, status, priority, type, target (unit / group / equipment), **Assigned to me**. The number filter finds part of a work order number in the department's own [format](department-settings#document-numbering), however it is typed: `MNT-26-0007`, `mnt26 0007` and `0007` all find `MNT26-0007`. ## Lifecycle of a work order diff --git a/docs/web-app/workflows.md b/docs/web-app/workflows.md index 37ee78c..b9b109b 100644 --- a/docs/web-app/workflows.md +++ b/docs/web-app/workflows.md @@ -15,6 +15,8 @@ title: Workflows **Navigation:** Department Menu → Workflows + + ## Overview Workflows follow an **Event → Transform → Action** pipeline: @@ -113,8 +115,8 @@ Workflows can subscribe to any of the following system events: | Event | Description | |-------|-------------| -| **Call Added** | New call/dispatch created | -| **Call Updated** | Existing call updated | +| **Call Added** | New call/dispatch created. A [pending call](dispatch-calls#pending-and-scheduled-calls) fires it when it is dispatched, not when it is saved | +| **Call Updated** | Existing call updated (also fires when a pending call is saved or edited) | | **Call Closed** | Call closed | | **Unit Status Changed** | Unit status changed | | **Personnel Staffing Changed** | Personnel staffing level changed | diff --git a/docs/web-app/workshifts.md b/docs/web-app/workshifts.md index 921ada7..bdde628 100644 --- a/docs/web-app/workshifts.md +++ b/docs/web-app/workshifts.md @@ -9,6 +9,8 @@ Workshifts (static shifts) provide a simpler scheduling mechanism compared to th ![New workshift](/img/web-app/workshifts/new.png) + + ## Overview Workshifts define fixed time blocks with assigned units, differing from the dynamic signup-based Shifts system. diff --git a/docusaurus.config.js b/docusaurus.config.js index c030931..5afd6e6 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -162,6 +162,12 @@ const config = { {type: 'doc', docId: 'reference/feature-flags', label: 'Feature Flags'}, ], }, + { + href: 'https://academy.resgrid.com/', + label: 'Academy', + position: 'right', + className: 'navbar-external-link', + }, { href: 'https://resgrid.com', label: 'Resgrid.com', @@ -220,6 +226,10 @@ const config = { label: 'Documentation', href: 'https://docs.resgrid.com', }, + { + label: 'Resgrid Academy', + href: 'https://academy.resgrid.com/', + }, { label: 'Blog', href: 'https://blog.resgrid.com', diff --git a/src/components/AcademyVideo/catalog.js b/src/components/AcademyVideo/catalog.js new file mode 100644 index 0000000..a7c2eaa --- /dev/null +++ b/src/components/AcademyVideo/catalog.js @@ -0,0 +1,92 @@ +/* + * Resgrid Academy (https://academy.resgrid.com) video catalog. + * + * Lessons live on the Academy home page and open with `#lesson=`; their + * media sits under /media. Walkthroughs each have their own page under + * /deep-dive/lessons// with media under /deep-dive/media. The Academy is + * served from GitHub Pages with `Access-Control-Allow-Origin: *`, so the + * videos and caption tracks can be played inline from the docs site. + * + * When the Academy adds a video, add it here and reference it from a doc page + * with . + */ + +export const ACADEMY_URL = 'https://academy.resgrid.com/'; +export const ACADEMY_WALKTHROUGHS_URL = `${ACADEMY_URL}deep-dive/`; + +/* [id, topic, title, minutes, audience] */ +const LESSONS = [ + ['00-start', 'Orientation', 'Resgrid: from the first alert to the next shift', 3.0, 'All department roles'], + ['01-people', 'People', 'Build a roster dispatch can use', 2.6, 'Administrators'], + ['02-security', 'Security', 'Configure a department and protect access', 3.7, 'Administrators'], + ['03-units', 'Units', 'Represent apparatus, crews, and GPS devices', 2.4, 'Administrators and dispatchers'], + ['04-apps', 'Apps', 'Put the right Resgrid app on each device', 3.0, 'Members, dispatchers, and commanders'], + ['05-calls', 'Calls', 'Take an incident from intake to closeout', 4.3, 'Dispatchers and administrators'], + ['06-communication', 'Communication', 'Make alerts reach the intended audience', 3.6, 'Administrators, officers, and members'], + ['07-mapping', 'Mapping', 'Make location information useful and current', 3.6, 'Dispatchers and administrators'], + ['08-shifts', 'Shifts', 'Plan coverage and keep dispatch aligned', 2.5, 'Schedulers, dispatchers, and members'], + ['09-training', 'Training', 'Assign learning and track qualifications', 2.7, 'Training officers and members'], + ['10-knowledge', 'Knowledge', 'Give members a dependable reference library', 4.6, 'Officers, dispatchers, and members'], + ['11-checklists', 'Checklists', 'Record routine checks and missed work', 2.3, 'Readiness officers and members'], + ['12-maintenance', 'Maintenance', 'Turn defects into accountable repairs', 4.1, 'Fleet officers and technicians'], + ['13-inventory', 'Inventory', 'Know what is available, issued, and expiring', 3.0, 'Logistics officers and members'], + ['14-records', 'Records', 'Keep incident and prevention records reviewable', 9.4, 'Report writers, reviewers, and records officers'], + ['15-deployments', 'Deployments', 'Keep deployment activity and cost evidence together', 3.2, 'Deployment coordinators and finance officers'], + ['16-business', 'Business', 'Connect service activity to costs and billing', 8.9, 'Finance staff and business administrators'], + ['17-automation', 'Automation', 'Automate a repeatable task with visible outcomes', 2.6, 'Administrators and integration owners'], + ['18-ptt', 'Push-to-talk', 'Set up voice channels for team coordination', 1.9, 'Administrators and field teams'], + ['19-adp', 'Data protection', 'Plan protected-data access and recovery', 2.7, 'Security administrators and records officers'], + ['20-plans', 'Plans', 'Match subscription capacity to the roster', 1.7, 'Managing members and administrators'], + ['21-ai', 'AI', 'Understand AI availability and human review', 2.4, 'Administrators and officers'], + ['22-relay', 'Relay', 'Relay: bring an audio dispatch feed into Resgrid', 1.2, 'System operators and dispatch administrators'], + ['23-self-hosting', 'Self-hosting', 'Self-hosting: configuration and operating responsibilities', 1.5, 'Self-hosted system operators'], +]; + +/* [id, title, minutes] */ +const WALKTHROUGHS = [ + ['01-setup-wizard', 'Set up a department with the nine-step wizard', 7.9], + ['02-department-settings', 'Configure department-wide behavior', 6.7], + ['03-custom-statuses', 'Create statuses with useful operational meaning', 7.1], + ['06-dispatch-settings', 'Control recipient selection and dispatch behavior', 7.7], + ['12-chat', 'Use chat channels, messages and acknowledgements', 5.9], + ['13-assistant', 'Use the Assistant and understand AI prerequisites', 6.0], + ['14-admin-assist', 'Use Admin Assist to review changes and follow up', 6.4], +]; + +const videos = {}; + +LESSONS.forEach(([id, topic, title, minutes, audience]) => { + videos[id] = { + id, + kind: 'lesson', + topic, + title, + minutes, + audience, + page: `${ACADEMY_URL}#lesson=${id}`, + src: `${ACADEMY_URL}media/${id}.mp4`, + poster: `${ACADEMY_URL}media/${id}.jpg`, + captions: `${ACADEMY_URL}media/${id}.vtt`, + }; +}); + +WALKTHROUGHS.forEach(([id, title, minutes]) => { + const page = `${ACADEMY_WALKTHROUGHS_URL}lessons/${id}/`; + videos[id] = { + id, + kind: 'walkthrough', + title, + minutes, + audience: 'Step-by-step in the web app', + page, + src: `${ACADEMY_WALKTHROUGHS_URL}media/${id}.mp4`, + poster: `${page}01-01.jpg`, + captions: `${page}captions.vtt`, + }; +}); + +export const academyLessons = LESSONS.map(([id]) => videos[id]); + +export function getAcademyVideo(id) { + return videos[id]; +} diff --git a/src/components/AcademyVideo/index.js b/src/components/AcademyVideo/index.js new file mode 100644 index 0000000..c381c43 --- /dev/null +++ b/src/components/AcademyVideo/index.js @@ -0,0 +1,81 @@ +import React, {useState} from 'react'; +import clsx from 'clsx'; +import Icon from '@site/src/components/HomepageFeatures/Icons'; +import {getAcademyVideo} from './catalog'; +import styles from './styles.module.css'; + +/* + * A Resgrid Academy video card for doc pages: the poster plays the video + * inline (with captions) on click, and a link opens the lesson on the Academy + * with its chapters and transcript. Available in every .md/.mdx file through + * src/theme/MDXComponents.js: + * + * + */ +export default function AcademyVideo({id, stacked = false}) { + const video = getAcademyVideo(id); + const [playing, setPlaying] = useState(false); + + if (!video) { + if (process.env.NODE_ENV !== 'production') { + console.warn(`AcademyVideo: unknown Resgrid Academy video "${id}"`); + } + return null; + } + + const kindLabel = video.kind === 'walkthrough' ? 'Walkthrough' : 'Video lesson'; + + return ( + + ); +} diff --git a/src/components/AcademyVideo/styles.module.css b/src/components/AcademyVideo/styles.module.css new file mode 100644 index 0000000..ae2f01a --- /dev/null +++ b/src/components/AcademyVideo/styles.module.css @@ -0,0 +1,155 @@ +/* ───────────────────────────────────────────── + Resgrid Academy video card + ───────────────────────────────────────────── */ + +.card { + display: grid; + grid-template-columns: minmax(0, 260px) minmax(0, 1fr); + gap: 1.1rem; + align-items: center; + margin: 1.5rem 0; + padding: 0.85rem; + border: 1px solid var(--docs-color-border); + border-left: 3px solid var(--docs-color-primary); + border-radius: 12px; + background: var(--docs-color-background-100); +} + +.card + .card { + margin-top: -0.5rem; +} + +.stacked { + grid-template-columns: minmax(0, 1fr); + margin: 0; +} + +.media { + position: relative; + aspect-ratio: 16 / 9; + overflow: hidden; + border-radius: 8px; + background: #0b1220; +} + +.poster { + position: absolute; + inset: 0; + display: block; + width: 100%; + height: 100%; + padding: 0; + border: 0; + cursor: pointer; + background: transparent; +} + +.poster img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.25s ease, filter 0.25s ease; +} + +.poster:hover img, +.poster:focus-visible img { + transform: scale(1.03); + filter: brightness(0.85); +} + +.poster:focus-visible { + outline: 3px solid var(--docs-color-primary-100); + outline-offset: -3px; +} + +.playButton { + position: absolute; + top: 50%; + left: 50%; + display: flex; + align-items: center; + justify-content: center; + width: 52px; + height: 52px; + padding-left: 3px; + border-radius: 999px; + color: #ffffff; + background: rgba(33, 96, 253, 0.92); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35); + transform: translate(-50%, -50%); + transition: transform 0.15s ease, background 0.15s ease; +} + +.poster:hover .playButton, +.poster:focus-visible .playButton { + background: #2160fd; + transform: translate(-50%, -50%) scale(1.08); +} + +.duration { + position: absolute; + right: 8px; + bottom: 8px; + padding: 0.1rem 0.45rem; + border-radius: 4px; + font-size: 0.72rem; + font-weight: 600; + color: #ffffff; + background: rgba(0, 0, 0, 0.72); +} + +.video { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + background: #000000; +} + +.body { + min-width: 0; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 0.35rem; + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--docs-color-primary); +} + +:global(html[data-theme='dark']) .eyebrow { + color: var(--docs-color-primary-100); +} + +.title { + margin: 0.3rem 0 0.2rem; + font-size: 1.02rem; + font-weight: 700; + line-height: 1.35; + color: var(--docs-color-text); +} + +.meta { + margin: 0 0 0.55rem; + font-size: 0.82rem; + color: var(--docs-color-text-100); +} + +.link { + display: inline-flex; + align-items: center; + gap: 0.35rem; + font-size: 0.85rem; + font-weight: 600; +} + +@media (max-width: 640px) { + .card { + grid-template-columns: minmax(0, 1fr); + } +} diff --git a/src/components/HomepageFeatures/Icons.js b/src/components/HomepageFeatures/Icons.js index 7e06afd..be1dde2 100644 --- a/src/components/HomepageFeatures/Icons.js +++ b/src/components/HomepageFeatures/Icons.js @@ -186,6 +186,15 @@ const paths = { ), + play: ( + + ), + video: ( + <> + + + + ), github: ( + {/* ── Resgrid Academy ── */} +
+
+
+
+ Resgrid Academy +

Prefer to watch? Learn Resgrid in short videos

+

+ Narrated video lessons with captions, chapters and transcripts, + learning paths for administrators, dispatchers, members and + specialists, and step-by-step configuration walkthroughs in the + web app. Pages in these docs that have a matching video show it + at the top. +

+ + Jump to a lesson + +
+ +
+
+
+ {/* ── Platform features ── */}
diff --git a/src/components/HomepageFeatures/styles.module.css b/src/components/HomepageFeatures/styles.module.css index fd0f248..66223bd 100644 --- a/src/components/HomepageFeatures/styles.module.css +++ b/src/components/HomepageFeatures/styles.module.css @@ -519,6 +519,48 @@ border-color: rgba(255, 255, 255, 0.4); } +/* ───────────────────────────────────────────── + Resgrid Academy panel + ───────────────────────────────────────────── */ + +.sectionAcademy { + padding-top: 0; +} + +.academyPanel { + display: grid; + grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); + gap: 2.5rem; + align-items: center; + padding: 2.25rem; + border-radius: 22px; + border: 1px solid var(--docs-color-border); + background: linear-gradient(135deg, rgba(33, 96, 253, 0.06), rgba(34, 184, 255, 0.05)); +} + +:global(html[data-theme='dark']) .academyPanel { + background: linear-gradient(135deg, rgba(26, 144, 255, 0.1), rgba(94, 63, 255, 0.08)); +} + +.academyPanel .sectionSubtitle { + margin-bottom: 1.25rem; +} + +.academyActions { + display: flex; + flex-wrap: wrap; + gap: 0.6rem; + margin-bottom: 1.5rem; +} + +.academyListLabel { + display: block; + margin-bottom: 0.6rem; + font-size: 0.78rem; + font-weight: 600; + color: var(--docs-color-text-100); +} + /* ───────────────────────────────────────────── Administer / Self-host / Develop ───────────────────────────────────────────── */ @@ -732,7 +774,8 @@ grid-template-columns: repeat(2, 1fr); } - .guidesPanel { + .guidesPanel, + .academyPanel { grid-template-columns: 1fr; gap: 1.75rem; padding: 2rem; diff --git a/src/pages/index.js b/src/pages/index.js index 9f1ca5c..8c2b4da 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -75,6 +75,14 @@ function HomepageHeader() { API + + Video lessons + +