@blazeo.com/appointment-client 1.0.9 → 1.0.10

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.
@@ -1,5 +1,5 @@
1
1
  import { getSnapshot } from "mobx-state-tree";
2
- import { addParticipantToCalendar, saveCalendarOpeningHour } from "./blazeoCalendarRelationMethods.js";
2
+ import { addParticipantToCalendar, saveCalendarOpeningHoursBatch } from "./blazeoCalendarRelationMethods.js";
3
3
  import { createCalendarAsync, updateCalendarAsync, deleteCalendarAsync } from "./createCalendar.js";
4
4
  function isFailureStatus(res) {
5
5
  return res.status !== "success" && res.status !== "Success";
@@ -90,8 +90,10 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar, calendarNode
90
90
  }
91
91
  membersAdded += 1;
92
92
  }
93
- let openingHoursSaved = 0;
94
- for (const oh of calendar.openingHours ?? []) {
93
+ // 2. Save Opening Hours (Plan V2: Grouped by participant with explicit off-days per slot)
94
+ const openingHours = calendar.openingHours ?? [];
95
+ const hoursByParticipant = new Map();
96
+ for (const oh of openingHours) {
95
97
  const participantId = resolveParticipantIdForOpeningHour(oh);
96
98
  if (!participantId) {
97
99
  return {
@@ -99,8 +101,17 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar, calendarNode
99
101
  error: `Opening hour id ${oh.id}: participantId is required.`,
100
102
  };
101
103
  }
102
- for (const day of oh.days ?? []) {
103
- const payload = {
104
+ if (!hoursByParticipant.has(participantId)) {
105
+ hoursByParticipant.set(participantId, []);
106
+ }
107
+ // Plan V2 Logic: For every opening hour object, generate EXACTLY 7 entries (days 0-6).
108
+ // If the day is in oh.days, it's ON. If not, it's OFF.
109
+ const activeDays = oh.days ?? [];
110
+ const openingHourId = oh.openingHourId?.trim() || newOpeningHourId();
111
+ for (let day = 0; day <= 6; day++) {
112
+ const isIncluded = activeDays.includes(day);
113
+ const isOff = isIncluded ? !!oh.off : true; // If not in days array, it's explicitly OFF
114
+ hoursByParticipant.get(participantId)?.push({
104
115
  calendarId: calendarIdStr,
105
116
  participantId,
106
117
  day,
@@ -108,22 +119,28 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar, calendarNode
108
119
  startMinute: oh.startMinute,
109
120
  endHour: oh.endHour,
110
121
  endMinute: oh.endMinute,
111
- off: oh.off,
112
- openingHourId: oh.openingHourId?.trim() || newOpeningHourId(),
122
+ off: isOff,
123
+ openingHourId: openingHourId,
124
+ });
125
+ }
126
+ }
127
+ let openingHoursSaved = 0;
128
+ for (const [participantId, payload] of hoursByParticipant.entries()) {
129
+ if (payload.length === 0)
130
+ continue;
131
+ // Use the batch save method (plural)
132
+ const res = await saveCalendarOpeningHoursBatch(calendarNode, payload);
133
+ if (isFailureStatus(res)) {
134
+ const msg = res.message ??
135
+ (typeof res.data === "string" ? res.data : undefined) ??
136
+ JSON.stringify(res);
137
+ return {
138
+ ok: false,
139
+ error: `saveOpeningHours batch failed for participant ${participantId}: ${msg}`,
140
+ apiResponse: res,
113
141
  };
114
- const res = await saveCalendarOpeningHour(calendarNode, payload);
115
- if (isFailureStatus(res)) {
116
- const msg = res.message ??
117
- (typeof res.data === "string" ? res.data : undefined) ??
118
- JSON.stringify(res);
119
- return {
120
- ok: false,
121
- error: `saveOpeningHour failed (opening hour ${oh.id}, day ${day}): ${msg}`,
122
- apiResponse: res,
123
- };
124
- }
125
- openingHoursSaved += 1;
126
142
  }
143
+ openingHoursSaved += payload.length;
127
144
  }
128
145
  return {
129
146
  ...baseSuccess,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blazeo.com/appointment-client",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -1,5 +1,5 @@
1
1
  import { getSnapshot } from "mobx-state-tree";
2
- import { addParticipantToCalendar, saveCalendarOpeningHour } from "./blazeoCalendarRelationMethods.js";
2
+ import { addParticipantToCalendar, saveCalendarOpeningHour, saveCalendarOpeningHoursBatch } from "./blazeoCalendarRelationMethods.js";
3
3
  import { createCalendarAsync, updateCalendarAsync, deleteCalendarAsync } from "./createCalendar.js";
4
4
 
5
5
  function isFailureStatus(res: any) {
@@ -97,8 +97,11 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar: any, calenda
97
97
  membersAdded += 1;
98
98
  }
99
99
 
100
- let openingHoursSaved = 0;
101
- for (const oh of calendar.openingHours ?? []) {
100
+ // 2. Save Opening Hours (Plan V2: Grouped by participant with explicit off-days per slot)
101
+ const openingHours = calendar.openingHours ?? [];
102
+ const hoursByParticipant = new Map<string, any[]>();
103
+
104
+ for (const oh of openingHours) {
102
105
  const participantId = resolveParticipantIdForOpeningHour(oh);
103
106
  if (!participantId) {
104
107
  return {
@@ -106,8 +109,21 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar: any, calenda
106
109
  error: `Opening hour id ${oh.id}: participantId is required.`,
107
110
  };
108
111
  }
109
- for (const day of oh.days ?? []) {
110
- const payload = {
112
+
113
+ if (!hoursByParticipant.has(participantId)) {
114
+ hoursByParticipant.set(participantId, []);
115
+ }
116
+
117
+ // Plan V2 Logic: For every opening hour object, generate EXACTLY 7 entries (days 0-6).
118
+ // If the day is in oh.days, it's ON. If not, it's OFF.
119
+ const activeDays = oh.days ?? [];
120
+ const openingHourId = oh.openingHourId?.trim() || newOpeningHourId();
121
+
122
+ for (let day = 0; day <= 6; day++) {
123
+ const isIncluded = activeDays.includes(day);
124
+ const isOff = isIncluded ? !!oh.off : true; // If not in days array, it's explicitly OFF
125
+
126
+ hoursByParticipant.get(participantId)?.push({
111
127
  calendarId: calendarIdStr,
112
128
  participantId,
113
129
  day,
@@ -115,23 +131,31 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar: any, calenda
115
131
  startMinute: oh.startMinute,
116
132
  endHour: oh.endHour,
117
133
  endMinute: oh.endMinute,
118
- off: oh.off,
119
- openingHourId: oh.openingHourId?.trim() || newOpeningHourId(),
134
+ off: isOff,
135
+ openingHourId: openingHourId,
136
+ });
137
+ }
138
+ }
139
+
140
+ let openingHoursSaved = 0;
141
+ for (const [participantId, payload] of hoursByParticipant.entries()) {
142
+ if (payload.length === 0) continue;
143
+
144
+ // Use the batch save method (plural)
145
+ const res = await saveCalendarOpeningHoursBatch(calendarNode, payload);
146
+
147
+ if (isFailureStatus(res)) {
148
+ const msg =
149
+ res.message ??
150
+ (typeof res.data === "string" ? res.data : undefined) ??
151
+ JSON.stringify(res);
152
+ return {
153
+ ok: false,
154
+ error: `saveOpeningHours batch failed for participant ${participantId}: ${msg}`,
155
+ apiResponse: res,
120
156
  };
121
- const res = await saveCalendarOpeningHour(calendarNode, payload);
122
- if (isFailureStatus(res)) {
123
- const msg =
124
- res.message ??
125
- (typeof res.data === "string" ? res.data : undefined) ??
126
- JSON.stringify(res);
127
- return {
128
- ok: false,
129
- error: `saveOpeningHour failed (opening hour ${oh.id}, day ${day}): ${msg}`,
130
- apiResponse: res,
131
- };
132
- }
133
- openingHoursSaved += 1;
134
157
  }
158
+ openingHoursSaved += payload.length;
135
159
  }
136
160
 
137
161
  return {