@7365admin1/layer-common 4.61.1 → 4.62.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,11 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 4.62.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a9c14d5: Inventory Record Usage: a before photo and an after photo are required (owner decision 2026-09-27). Save is refused with "Add a before photo and an after photo to record usage." until both are added; the API enforces the same rule.
8
+
3
9
  ## 4.61.1
4
10
 
5
11
  ### Patch Changes
@@ -1673,11 +1679,11 @@
1673
1679
  `utils/console-tier.ts` + `composables/useConsoleTier.ts` mirror the server's
1674
1680
  own rule from two endpoints the console already calls, unprojected:
1675
1681
 
1676
- GET /api/members/user/:user/app/admin the Seven365 staff membership
1677
- GET /api/roles/id/:role that membership's role document
1682
+ GET /api/members/user/:user/app/admin the Seven365 staff membership
1683
+ GET /api/roles/id/:role that membership's role document
1678
1684
 
1679
- owner = member.type === "admin" && role.type === "admin" && role.default === true
1680
- staff = member.type === "admin" && role.type === "admin"
1685
+ owner = member.type === "admin" && role.type === "admin" && role.default === true
1686
+ staff = member.type === "admin" && role.type === "admin"
1681
1687
 
1682
1688
  `role.default` is the marker because it is the only property of a platform
1683
1689
  staff role no API caller can set - `role.controller.ts` validates create and
@@ -72,14 +72,15 @@
72
72
 
73
73
  <v-row dense>
74
74
  <v-col cols="12" sm="6">
75
- <InputLabel title="Photo before (optional)" class="mb-1" />
75
+ <InputLabel title="Photo before" required class="mb-1" />
76
76
  <InventoryPhotoInput v-model="photosBefore" :max="3" />
77
77
  </v-col>
78
78
  <v-col cols="12" sm="6">
79
- <InputLabel title="Photo after (optional)" class="mb-1" />
79
+ <InputLabel title="Photo after" required class="mb-1" />
80
80
  <InventoryPhotoInput v-model="photosAfter" :max="3" />
81
81
  </v-col>
82
82
  </v-row>
83
+ <div v-if="photoError" class="text-error text-body-2 mt-1" role="alert">{{ photoError }}</div>
83
84
 
84
85
  <InputLabel title="Date used" class="mb-1 mt-3" />
85
86
  <v-text-field v-model="date" type="date" :max="today" density="comfortable" style="max-width: 200px" />
@@ -128,6 +129,8 @@ const reportedBy = ref("");
128
129
  const date = ref(today);
129
130
  const photosBefore = ref<string[]>([]);
130
131
  const photosAfter = ref<string[]>([]);
132
+ const photoError = ref("");
133
+ const USAGE_PHOTOS_REQUIRED = "Add a before photo and an after photo to record usage.";
131
134
 
132
135
  const siteChoices = computed(() =>
133
136
  props.sites.length ? props.sites : props.store.sites.map((_id) => ({ _id, name: _id === props.siteId ? "This property" : "Other property" })),
@@ -158,7 +161,9 @@ async function loadAreas() {
158
161
 
159
162
  async function save() {
160
163
  const { valid } = await form.value.validate();
161
- if (!valid || !props.holding) return;
164
+ // Owner decision 2026-09-27: a before AND an after photo on every usage record (the API refuses without).
165
+ photoError.value = photosBefore.value.length && photosAfter.value.length ? "" : USAGE_PHOTOS_REQUIRED;
166
+ if (!valid || photoError.value || !props.holding) return;
162
167
  saving.value = true;
163
168
  try {
164
169
  await api.recordUsage(props.store._id, {
@@ -190,8 +195,13 @@ watch(site, () => {
190
195
  loadAreas();
191
196
  });
192
197
 
198
+ watch([photosBefore, photosAfter], () => {
199
+ if (photosBefore.value.length && photosAfter.value.length) photoError.value = "";
200
+ });
201
+
193
202
  watch(show, (open) => {
194
203
  if (!open) return;
204
+ photoError.value = "";
195
205
  photosBefore.value = [];
196
206
  photosAfter.value = [];
197
207
  qty.value = 1;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "4.61.1",
5
+ "version": "4.62.0",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",