@7365admin1/core 3.51.1-staging.229 → 3.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,78 @@
1
1
  # @iservice365/core
2
2
 
3
+ ## 3.52.0
4
+
5
+ ### Minor Changes
6
+
7
+ - bd4bd88: Add a bulk camera import on the existing guided path.
8
+
9
+ `POST /api/site-cameras/bulk` accepts a site and up to 200 rows from the
10
+ technician survey sheet, derives each camera's relay address from its recorder
11
+ and channel number, and returns a per-row result. `commit: false` previews and
12
+ writes nothing; `commit: true` writes the rows that passed. Rows that are ANPR,
13
+ that carry a hand-written address, or whose channel is outside 1-256 are refused
14
+ by name, and a camera already at the site is reported as a duplicate rather than
15
+ as a write error. Creates `type: "ip"` cameras only and needs the same write
16
+ gate as the single-camera form.
17
+
18
+ ### Patch Changes
19
+
20
+ - 5af369c: Record who added, changed or removed a camera.
21
+
22
+ "Who changed this camera's address, and when" had no answer anywhere in the system: a camera record
23
+ carries `createdAt`/`updatedAt` and no actor, and a write overwrites the previous `host` in place. At
24
+ Seventh Condominium that turned a one-line port correction into nine days.
25
+
26
+ `add`, `updateById` and `deleteById` on site cameras now append a row to the existing append-only
27
+ `console-audit` collection, with the actor from the session, the camera id, and `before`/`after`
28
+ values drawn from a per-action allow-list. No schema changes, no migration, and no new collection.
29
+
30
+ The allow-list is the boundary that matters: a camera document holds a device credential, and
31
+ `username` and `password` are not on it. `loadForWrite` still never reads them.
32
+
33
+ - 16a9105: Decouple the camera health sweep from the wall's tile ceiling.
34
+
35
+ `getSiteHealth` sliced its input to `maxTiles` (9), so a health request covering a 150-camera site
36
+ answered for the first nine cameras and said nothing at all about the other 141 — and did not report
37
+ that it had shortened the list. No client could build a site-wide "which of my cameras is down" view,
38
+ however it asked.
39
+
40
+ Health is now bounded by its own `maxHealthCameras` (`CAMERA_HEALTH_MAX_CAMERAS`, default 200), and a
41
+ request past that cap comes back with `requested` / `returned` / `truncated` instead of a quietly
42
+ partial list. The device fan-out is unchanged: `maxConcurrentProbes` still bounds probes in flight at
43
+ 4, the reachability probe is still cached per recorder, and `probeCamera` still reads a cached device
44
+ probe rather than making a fresh one — so a 150-camera sweep costs a recorder no more than a 9-camera
45
+ one after the first pass.
46
+
47
+ - 398b374: HID Amico: stop silently deriving the credential encryption key from
48
+ ACCESS_TOKEN_SECRET. Reading still accepts the legacy key so existing credentials
49
+ keep working (and now logs an error saying so), but writing a new credential
50
+ refuses with a message naming HID_AMICO_SECRET, so a later rotation of the JWT
51
+ signing secret cannot orphan credentials that were written after this.
52
+ - 8113e31: HID face registration: never retain the captured photo. Identity `metadata` is stripped of
53
+ `photo` and of any inline `data:image/...` value on every write, and reader notification
54
+ payloads (`user_image`, `access_photo`) are redacted of image data before they are persisted
55
+ as audit events. Enrollment state (`facialEnrolled`, `facialEnrolledAt`, `facialData`,
56
+ `imageTimestamp`) is unchanged.
57
+ - b097964: Constrain a site camera's `direction` to a fixed set instead of accepting any string.
58
+
59
+ `Joi.string().allow("entry", "exit", "both", "none")` reads like a whitelist but is not one — on a
60
+ validator that already accepts every non-empty string, `.allow()` only adds permitted values, so the
61
+ field rejected nothing. It is now `.valid()`.
62
+
63
+ The accepted set is `entry | exit | both | none | visitors | residents`: the four values the staging
64
+ collection actually holds (measured read-only across all 22 rows), plus the two extra options
65
+ layer-common's live `CameraForm.vue` offers for ANPR cameras. No stored camera and no reachable form
66
+ is refused. Whether `visitors` and `residents` are directions at all is a product question; dropping
67
+ them later is a zero-row migration.
68
+
69
+ - Visitor list: decide the Guests tab by "every requested status is pre-arrival"
70
+ instead of matching one specific status set, so the tab keeps filtering on the
71
+ expected arrival date for both the approved+pending request sent by
72
+ layer-common `main` and the approved+pending+rejected request sent by
73
+ layer-common `staging` (DV-0080). Extracted as `isPreCheckInStatusOnly` with
74
+ tests pinning each case.
75
+
3
76
  ## 3.51.0
4
77
 
5
78
  ### Minor Changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@7365admin1/core",
3
3
  "license": "MIT",
4
- "version": "3.51.1-staging.229",
4
+ "version": "3.52.0",
5
5
  "author": "7365admin1",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -1,16 +0,0 @@
1
- ---
2
- "@7365admin1/core": patch
3
- ---
4
-
5
- Record who added, changed or removed a camera.
6
-
7
- "Who changed this camera's address, and when" had no answer anywhere in the system: a camera record
8
- carries `createdAt`/`updatedAt` and no actor, and a write overwrites the previous `host` in place. At
9
- Seventh Condominium that turned a one-line port correction into nine days.
10
-
11
- `add`, `updateById` and `deleteById` on site cameras now append a row to the existing append-only
12
- `console-audit` collection, with the actor from the session, the camera id, and `before`/`after`
13
- values drawn from a per-action allow-list. No schema changes, no migration, and no new collection.
14
-
15
- The allow-list is the boundary that matters: a camera document holds a device credential, and
16
- `username` and `password` are not on it. `loadForWrite` still never reads them.
@@ -1,17 +0,0 @@
1
- ---
2
- "@7365admin1/core": patch
3
- ---
4
-
5
- Decouple the camera health sweep from the wall's tile ceiling.
6
-
7
- `getSiteHealth` sliced its input to `maxTiles` (9), so a health request covering a 150-camera site
8
- answered for the first nine cameras and said nothing at all about the other 141 — and did not report
9
- that it had shortened the list. No client could build a site-wide "which of my cameras is down" view,
10
- however it asked.
11
-
12
- Health is now bounded by its own `maxHealthCameras` (`CAMERA_HEALTH_MAX_CAMERAS`, default 200), and a
13
- request past that cap comes back with `requested` / `returned` / `truncated` instead of a quietly
14
- partial list. The device fan-out is unchanged: `maxConcurrentProbes` still bounds probes in flight at
15
- 4, the reachability probe is still cached per recorder, and `probeCamera` still reads a cached device
16
- probe rather than making a fresh one — so a 150-camera sweep costs a recorder no more than a 9-camera
17
- one after the first pass.
@@ -1,9 +0,0 @@
1
- ---
2
- "@7365admin1/core": patch
3
- ---
4
-
5
- HID Amico: stop silently deriving the credential encryption key from
6
- ACCESS_TOKEN_SECRET. Reading still accepts the legacy key so existing credentials
7
- keep working (and now logs an error saying so), but writing a new credential
8
- refuses with a message naming HID_AMICO_SECRET, so a later rotation of the JWT
9
- signing secret cannot orphan credentials that were written after this.
@@ -1,9 +0,0 @@
1
- ---
2
- "@7365admin1/core": patch
3
- ---
4
-
5
- HID face registration: never retain the captured photo. Identity `metadata` is stripped of
6
- `photo` and of any inline `data:image/...` value on every write, and reader notification
7
- payloads (`user_image`, `access_photo`) are redacted of image data before they are persisted
8
- as audit events. Enrollment state (`facialEnrolled`, `facialEnrolledAt`, `facialData`,
9
- `imageTimestamp`) is unchanged.
@@ -1,14 +0,0 @@
1
- ---
2
- "@7365admin1/core": minor
3
- ---
4
-
5
- Add a bulk camera import on the existing guided path.
6
-
7
- `POST /api/site-cameras/bulk` accepts a site and up to 200 rows from the
8
- technician survey sheet, derives each camera's relay address from its recorder
9
- and channel number, and returns a per-row result. `commit: false` previews and
10
- writes nothing; `commit: true` writes the rows that passed. Rows that are ANPR,
11
- that carry a hand-written address, or whose channel is outside 1-256 are refused
12
- by name, and a camera already at the site is reported as a duplicate rather than
13
- as a write error. Creates `type: "ip"` cameras only and needs the same write
14
- gate as the single-camera form.
@@ -1,15 +0,0 @@
1
- ---
2
- "@7365admin1/core": patch
3
- ---
4
-
5
- Constrain a site camera's `direction` to a fixed set instead of accepting any string.
6
-
7
- `Joi.string().allow("entry", "exit", "both", "none")` reads like a whitelist but is not one — on a
8
- validator that already accepts every non-empty string, `.allow()` only adds permitted values, so the
9
- field rejected nothing. It is now `.valid()`.
10
-
11
- The accepted set is `entry | exit | both | none | visitors | residents`: the four values the staging
12
- collection actually holds (measured read-only across all 22 rows), plus the two extra options
13
- layer-common's live `CameraForm.vue` offers for ANPR cameras. No stored camera and no reachable form
14
- is refused. Whether `visitors` and `residents` are directions at all is a product question; dropping
15
- them later is a zero-row migration.
@@ -1,10 +0,0 @@
1
- ---
2
- "@7365admin1/core": patch
3
- ---
4
-
5
- Visitor list: decide the Guests tab by "every requested status is pre-arrival"
6
- instead of matching one specific status set, so the tab keeps filtering on the
7
- expected arrival date for both the approved+pending request sent by
8
- layer-common `main` and the approved+pending+rejected request sent by
9
- layer-common `staging` (DV-0080). Extracted as `isPreCheckInStatusOnly` with
10
- tests pinning each case.