@communecter/cocolight-api-client 1.0.129 → 1.0.131

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/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BaseEntity } from "./api/BaseEntity.js";
2
- import { fromEntityJSON } from "./api/EntityRegistry.js";
2
+ import { fromEntityJSON, reviveEntities } from "./api/EntityRegistry.js";
3
3
  import Api from "./Api.js";
4
4
  import ApiClient from "./ApiClient.js";
5
5
  import * as error from "./error.js";
@@ -33,6 +33,7 @@ const cocolightApiClient = {
33
33
  },
34
34
  helper: {
35
35
  fromEntityJSON,
36
+ reviveEntities,
36
37
  restorePaginationFromJSON: BaseEntity.restorePaginationFromJSON
37
38
  },
38
39
  OfflineClientManager
@@ -8,15 +8,139 @@ import type { ActionItemNormalized } from "./serverDataType/Action.js";
8
8
  * S'instancie via `project.action(...)` plutôt que directement.
9
9
  *
10
10
  * Endpoints utilisés :
11
- * - `get()` : hérité (GET_ELEMENTS_ABOUT via `/co2/element/about/type/actions/id/{id}`)
12
- * - `_add()` : COSTUM_PROJECT_ACTION_REQUEST_NEW (parentId/parentType injectés depuis le parent)
11
+ * - `get()` : hérité (GET_ELEMENTS_ABOUT via `/co2/element/about/type/actions/id/{id}`)
12
+ * - `_add()` : COSTUM_PROJECT_ACTION_REQUEST_NEW (parentId/parentType injectés depuis le parent)
13
+ * - `_update()` : UPDATE_PATH_VALUE field par field via CUSTOM_FIELD_HANDLERS
14
+ * (pas d'endpoint dédié par bloc côté backend — on dispatche chaque champ modifié)
13
15
  */
14
16
  export declare class Action extends BaseEntity<ActionItemNormalized> {
15
17
  static entityType: string;
16
18
  static entityTag: string;
17
19
  static SCHEMA_CONSTANTS: string[];
20
+ /**
21
+ * Schémas virtuels : enregistrent les champs éditables auprès du draft proxy
22
+ * via _composeAllowedFields. Aucun endpoint backend réel — l'update passe par
23
+ * UPDATE_PATH_VALUE field par field.
24
+ */
25
+ static VIRTUAL_SCHEMAS: {
26
+ VIRTUAL_ACTION_EDITABLE: {
27
+ type: string;
28
+ properties: {
29
+ name: {
30
+ type: string;
31
+ };
32
+ credits: {
33
+ type: string;
34
+ };
35
+ min: {
36
+ type: string;
37
+ minimum: number;
38
+ };
39
+ max: {
40
+ type: string;
41
+ minimum: number;
42
+ };
43
+ status: {
44
+ type: string;
45
+ enum: string[];
46
+ };
47
+ tags: {
48
+ type: string;
49
+ items: {
50
+ type: string;
51
+ };
52
+ };
53
+ links: {
54
+ type: string;
55
+ };
56
+ startDate: {
57
+ oneOf: {
58
+ type: string;
59
+ }[];
60
+ };
61
+ endDate: {
62
+ oneOf: {
63
+ type: string;
64
+ }[];
65
+ };
66
+ milestone: {
67
+ oneOf: {
68
+ type: string;
69
+ }[];
70
+ };
71
+ importance: {
72
+ type: string;
73
+ };
74
+ };
75
+ };
76
+ };
18
77
  static ADD_BLOCKS: Map<"COSTUM_PROJECT_ACTION_REQUEST_NEW", "addAction">;
78
+ /**
79
+ * Champs éditables → méthode publique qui réalise l'update (via UPDATE_PATH_VALUE).
80
+ * Même pattern qu'Organization.openingHours : chaque field nom → method name.
81
+ * Les `updateXxx` méthodes ci-dessous délèguent toutes à `_updatePath`.
82
+ */
83
+ static CUSTOM_FIELD_HANDLERS: Map<"name" | "tags" | "startDate" | "endDate" | "links" | "status" | "credits" | "milestone" | "min" | "max" | "importance", {
84
+ readonly updateMethod: "updateName";
85
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
86
+ } | {
87
+ readonly updateMethod: "updateCredits";
88
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
89
+ } | {
90
+ readonly updateMethod: "updateMin";
91
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
92
+ } | {
93
+ readonly updateMethod: "updateMax";
94
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
95
+ } | {
96
+ readonly updateMethod: "updateStatus";
97
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
98
+ } | {
99
+ readonly updateMethod: "updateTags";
100
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
101
+ } | {
102
+ readonly updateMethod: "updateContributors";
103
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
104
+ } | {
105
+ readonly updateMethod: "updateStartDate";
106
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
107
+ } | {
108
+ readonly updateMethod: "updateEndDate";
109
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
110
+ } | {
111
+ readonly updateMethod: "updateMilestone";
112
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
113
+ } | {
114
+ readonly updateMethod: "updateImportance";
115
+ readonly schemaConstant: "VIRTUAL_ACTION_EDITABLE";
116
+ }>;
117
+ /**
118
+ * Champs présents dans le schéma de création (donc writable dans le draft) mais
119
+ * **non modifiables après création** — soit pas exposés en update backend, soit
120
+ * gérés par un autre flow.
121
+ *
122
+ * Si un caller modifie un de ces champs après get() puis save(), `_update` throw
123
+ * avec un message d'aide indiquant la voie alternative. Sans cette garde, le
124
+ * changement serait silencieusement ignoré.
125
+ */
126
+ private static CREATE_ONLY_FIELDS;
127
+ /**
128
+ * Slot UPDATE_BLOCKS vide pour l'instant : aucun endpoint dédié côté backend.
129
+ * Préservé pour cohérence structurelle avec Organization/Project — quand un endpoint
130
+ * `UPDATE_BLOCK_ACTION_XXX` arrivera, il s'ajoutera ici sans toucher au flow.
131
+ */
132
+ static UPDATE_BLOCKS: Map<string, string>;
133
+ /**
134
+ * `parentType` est injecté au payload de création (required par le schéma
135
+ * COSTUM_PROJECT_ACTION_REQUEST_NEW). `_add` ne filtre pas avec removeFields,
136
+ * donc il passe bien à la requête. Reste défensif si AJV `useDefaults` change.
137
+ */
19
138
  defaultFields: Record<string, any>;
139
+ /**
140
+ * Champs techniques exclus du draft writable (set au moment de la création,
141
+ * jamais modifiables ensuite par le caller). Restent accessibles en lecture
142
+ * via `action.serverData.parentId` / `.parentType`.
143
+ */
20
144
  removeFields: string[];
21
145
  _add: (payload: Record<string, any>) => Promise<void>;
22
146
  /**
@@ -24,4 +148,153 @@ export declare class Action extends BaseEntity<ActionItemNormalized> {
24
148
  * Méthode de bas niveau — utiliser `save()` après modification du draft à la place.
25
149
  */
26
150
  addAction(data?: Partial<CostumProjectActionRequestNewData>): Promise<unknown>;
151
+ _update: (payload: Record<string, any>) => Promise<boolean>;
152
+ updateName(value: string): Promise<unknown>;
153
+ /**
154
+ * Met à jour `credits` (entier). `setType: "int"` force le cast côté backend
155
+ * (form-urlencoded transmet en string sinon).
156
+ */
157
+ updateCredits(value: number): Promise<unknown>;
158
+ /** Met à jour `min` (entier ≥ 0). `setType: "int"`. */
159
+ updateMin(value: number): Promise<unknown>;
160
+ /** Met à jour `max` (entier ≥ 0). `setType: "int"`. */
161
+ updateMax(value: number): Promise<unknown>;
162
+ /**
163
+ * Change le statut de l'action via l'endpoint dédié backend `set_status`.
164
+ *
165
+ * **PAS via UPDATE_PATH_VALUE** : utiliser cet endpoint préserve la logique métier
166
+ * critique :
167
+ * - Ajoute une entrée dans `updateStatus[]` (historique des changements)
168
+ * - Auto endDate=now si status="done", auto startDate=now si "tracking"
169
+ * - Auto-purge des tags discuter/totest/next à la transition
170
+ * - Auto-set du tag pour discuter/next/totest (alias de "todo")
171
+ * - Notification Rocket.Chat au projet parent
172
+ *
173
+ * Statuses supportés côté backend : todo, done, tracking, discuter, next, totest, disabled, closed.
174
+ */
175
+ updateStatus(value: "todo" | "done" | "tracking" | "discuter" | "next" | "totest" | "disabled" | "closed"): Promise<unknown>;
176
+ updateTags(value: string[]): Promise<unknown>;
177
+ /**
178
+ * Met à jour `importance` ("low" / "medium" / "high" / autres valeurs custom).
179
+ * Champ simple sans effets de bord backend connus.
180
+ */
181
+ updateImportance(value: string): Promise<unknown>;
182
+ /**
183
+ * Remplace la liste complète des contributeurs via l'endpoint dédié `set_contributors`.
184
+ *
185
+ * **Sécurité** : touche plusieurs users → réservé aux admins du projet parent.
186
+ *
187
+ * Avantages vs UPDATE_PATH_VALUE :
188
+ * - Validation min/max côté backend (refus si hors bornes)
189
+ * - Notification socket aux autres clients (.set-contributors, .cd-int-contributors)
190
+ * - Réponse enrichie avec name/image des contributeurs
191
+ *
192
+ * @param value objet `{ contributors: { userId: {...} } }` — on extrait juste les keys (userIds).
193
+ * Les méta (type, isAdmin, name) sont gérées côté backend (type="citoyens" par défaut).
194
+ * Pour vider : passer `{ contributors: {} }`.
195
+ */
196
+ updateContributors(value: {
197
+ contributors?: Record<string, unknown>;
198
+ }): Promise<unknown>;
199
+ /**
200
+ * Ajoute un user comme contributeur de l'action (mode "join").
201
+ * Préserve les autres contributeurs existants.
202
+ *
203
+ * **Sécurité** :
204
+ * - Sans argument (ou userId = soi-même) → autorisé pour tout user connecté ("je participe")
205
+ * - Avec un autre userId → réservé aux admins du projet parent ("j'ajoute X")
206
+ *
207
+ * @param userId userId à ajouter. Par défaut : l'utilisateur connecté.
208
+ */
209
+ joinContributor(userId?: string): Promise<unknown>;
210
+ /**
211
+ * Retire un user de la liste des contributeurs (mode "quit").
212
+ * Préserve les autres contributeurs existants.
213
+ *
214
+ * **Sécurité** :
215
+ * - Sans argument (ou userId = soi-même) → autorisé pour tout user connecté ("je quitte")
216
+ * - Avec un autre userId → réservé aux admins du projet parent ("je retire X")
217
+ *
218
+ * @param userId userId à retirer. Par défaut : l'utilisateur connecté.
219
+ */
220
+ leaveContributor(userId?: string): Promise<unknown>;
221
+ /**
222
+ * Vérifie que l'utilisateur connecté est admin du projet parent — requis pour les
223
+ * mutations affectant des tiers (replace bulk ou agir sur un autre userId).
224
+ */
225
+ private _assertParentAdminForContributorMutation;
226
+ /**
227
+ * Met à jour ou efface le milestone d'une action.
228
+ * - `{ milestoneId }` : attache (validé via `Project.hasMilestone`).
229
+ * - `null` : détache via `$unset` Mongo côté backend.
230
+ *
231
+ * **Détail technique de l'effacement** :
232
+ * Le backend (`Element::updatePathValue`) fait `$verb = '$unset'` quand `$value === null`.
233
+ * Notre SDK strip les `null` avant l'envoi (`stripNullsInPlace`), donc on contourne en
234
+ * envoyant la chaîne vide `""` : la coercion PHP `(!empty($value) || $value == "0" || $value === false)`
235
+ * la transforme en `null` → `$unset`. Bonus : évite aussi le bug backend
236
+ * `"text" => $_POST["value"]` (accès direct, crash si value absent).
237
+ *
238
+ * NOTE: changer/effacer le milestone peut avoir des effets de bord côté backend non
239
+ * gérés (compteurs par milestone, idParentRoom, statuts dérivés). À utiliser avec discernement.
240
+ */
241
+ updateMilestone(value: {
242
+ milestoneId: string;
243
+ } | null): Promise<unknown>;
244
+ /**
245
+ * Met à jour startDate via l'endpoint dédié `set_date`.
246
+ *
247
+ * Utilise `set_date` plutôt qu'UPDATE_PATH_VALUE car :
248
+ * - Support natif de l'effacement : `null` → envoyer "" → backend fait `$unset`
249
+ * - Parser de date robuste côté backend (vs notre validation client-side)
250
+ *
251
+ * @param value chaîne ISO 8601 ("2026-05-20T08:00:00.000Z") ou null pour effacer.
252
+ */
253
+ updateStartDate(value: string | null): Promise<unknown>;
254
+ /**
255
+ * Met à jour endDate via l'endpoint dédié `set_date`.
256
+ * @param value chaîne ISO 8601 ou null pour effacer.
257
+ */
258
+ updateEndDate(value: string | null): Promise<unknown>;
259
+ /**
260
+ * Vérifie si l'utilisateur connecté est contributeur de CETTE action.
261
+ *
262
+ * Override la version de BaseEntity car la sémantique diffère :
263
+ * - Project : regarde `user.serverData.links.projects[projectId]` (sens user→project)
264
+ * - Action : regarde `action.serverData.links.contributors[userId]` (sens inverse)
265
+ *
266
+ * Pour modifier des données de l'action, c'est `parent.isAdmin()` qui compte
267
+ * (admin du projet parent) — pas cette méthode.
268
+ *
269
+ * @param options.silent si `false`, throw en cas de précondition manquante. Par défaut `true`.
270
+ */
271
+ isContributor(options?: {
272
+ silent?: boolean;
273
+ }): boolean;
274
+ /**
275
+ * Annule l'action via l'endpoint dédié `cancel`.
276
+ * Effets : status=closed + unset tracking + retire le tag "totest".
277
+ */
278
+ cancel(): Promise<unknown>;
279
+ /**
280
+ * Archive l'action via l'endpoint dédié `archive`.
281
+ * Effets : status=disabled + unset tracking.
282
+ */
283
+ archive(): Promise<unknown>;
284
+ /**
285
+ * Helper privé : envoie un UPDATE_PATH_VALUE pour un path donné.
286
+ */
287
+ private _updatePath;
288
+ /**
289
+ * Validation stricte int (refus float, NaN, etc.).
290
+ */
291
+ private _assertInt;
292
+ /**
293
+ * Validation stricte ISO 8601 (refus DD/MM/YYYY, "5 août", etc.). `null` accepté (clear).
294
+ */
295
+ private _assertIsoDate;
296
+ /**
297
+ * Vérifie un format ISO 8601 date-time strict (avec T et option timezone Z ou ±HH:MM).
298
+ */
299
+ private _isIsoDateTime;
27
300
  }
@@ -317,6 +317,23 @@ export declare class BaseEntity<TServerData = any> {
317
317
  * @returns Données mises à jour
318
318
  */
319
319
  refresh(): Promise<Record<string, any>>;
320
+ /**
321
+ * Helper pour les entités enfants : refresh automatique APRÈS une mutation directe
322
+ * (méthode appelée hors flow `save()`). Skip si l'appel vient de `save()` qui refresh
323
+ * lui-même à la fin — détecté via le flag `_calledFromSave`.
324
+ *
325
+ * À appeler dans les méthodes publiques de mutation (ex: `Action.cancel()`,
326
+ * `Organization.updateOpeningHours()`) après l'opération réussie, pour que le caller
327
+ * trouve `entity.serverData` à jour sans avoir à appeler `refresh()` manuellement.
328
+ *
329
+ * @example
330
+ * async myMutation(): Promise<unknown> {
331
+ * const result = await this.endpointApi.someEndpoint({ ... });
332
+ * await this._refreshIfDirect();
333
+ * return result;
334
+ * }
335
+ */
336
+ protected _refreshIfDirect(): Promise<void>;
320
337
  /**
321
338
  * Sauvegarde les modifications locales vers le serveur (add ou update).
322
339
  * @returns Données serveur mises à jour (après éventuel `refresh()`)
@@ -1,5 +1,5 @@
1
1
  import type ApiClient from "../ApiClient.js";
2
- import type { PersonRegisterData, AuthenticateUrlData, RefreshTokenUrlData, PasswordRecoveryData, ServerExchangeTokenData, ChangePasswordData, DeleteAccountData, UpdateSettingsData, UpdateBlockDescriptionData, UpdateBlockInfoData, UpdateBlockSocialData, UpdateBlockLocalityData, UpdateBlockSlugData, CheckData, ProfilImageData, ProfilBannerData, GetElementsAboutData, MulticonnectData, GetNewsData, GetNewsByIdData, AddNewsData, AddImageNewsData, AddFileNewsData, DeleteNewsData, UpdateNewsData, ShareNewsData, GetCommentsData, AddCommentsData, DeleteCommentsData, UpdateCommentsData, SearchTagsData, ShowVoteData, GlobalAutocompleteData, CityAutocompleteData, CityAutocompleteByCountryData, SuggestionInputData, GetProjectsNoAdminData, GetProjectsAdminData, GetPoisNoAdminData, GetPoisAdminData, GetOrganizationsNoAdminData, GetOrganizationsAdminData, GetMembersNoAdminData, GetMembersAdminData, GetFriendsAdminData, GetSubscriptionsData, GetSubscriptionsAdminData, GetSubscribersData, GetSubscribersAdminData, GetContributorsNoAdminData, GetContributorsAdminData, GetBadgesData, GetBadgesFiltersData, ConnectData, DisconnectData, GetElementsKeyData, GetFavorisData, DeleteFavorisData, AddFavorisData, AddOrganizationData, AddProjectData, AddPoiData, AddEventData, DeletePoiData, DeleteEventData, DeleteElementData, AddImageElementData, LinkValidateData, SearchMemberAutocompleteData, GetNotificationsData, GetNotificationsCountData, NotificationUpdateData, MarkNotificationAsReadData, ActivitypubSearchData, ActivitypubLinkData, ActivitypubGetCommunityData, GetBadgeData, AddBadgesData, AssignBadgesData, GetEventsData, ShareEventsData, InviteEventData, FollowData, GetCostumJsonData, GlobalAutocompleteCostumData, CostumEventRequestActorsData, CostumEventRequestSubeventsData, CostumEventRequestElementEventData, CostumEventRequestCategoriesData, CostumEventRequestDatesData, CostumEventRequestEventData, CostumEventRequestLinkTlToEventData, CostumEventRequestLoadContextTagData, GetGalleryData, GetAttendeesNoAdminData, GetAttendeesAdminData, CoformAnswersSearchData, CoformAnswersByIdData, GetCoformByIdData, CoformUploadAnswerFileData, CoformGetAnswerFilesData, SaveCoformAnswerData, AddVoteData, AddReportAbuseData, UpdatePathValueData, DeleteDocumentByContextData, DeleteDocumentByIdData, DemoteAdminData, CostumFilterCoformData, GetCountriesData, SearchZonesData, CoformAnswersByFormsData, GenerateAnswerFromFormData, FundingEnvelopeData, CoremuOperationData, CostumProjectActionRequestNewData, LinkDiscourseAccountData, UnlinkDiscourseAccountData, DiscourseProfileData, DiscourseCheckEmailData, DiscourseDismissLinkData, LinkMediawikiAccountData, UnlinkMediawikiAccountData, GetMediawikiContributionsData, AddClassifiedData } from "./EndpointApi.types.js";
2
+ import type { PersonRegisterData, AuthenticateUrlData, RefreshTokenUrlData, PasswordRecoveryData, ServerExchangeTokenData, ChangePasswordData, DeleteAccountData, UpdateSettingsData, UpdateBlockDescriptionData, UpdateBlockInfoData, UpdateBlockSocialData, UpdateBlockLocalityData, UpdateBlockSlugData, CheckData, ProfilImageData, ProfilBannerData, GetElementsAboutData, MulticonnectData, GetNewsData, GetNewsByIdData, AddNewsData, AddImageNewsData, AddFileNewsData, DeleteNewsData, UpdateNewsData, ShareNewsData, GetCommentsData, AddCommentsData, DeleteCommentsData, UpdateCommentsData, SearchTagsData, ShowVoteData, GlobalAutocompleteData, CityAutocompleteData, CityAutocompleteByCountryData, SuggestionInputData, GetProjectsNoAdminData, GetProjectsAdminData, GetPoisNoAdminData, GetPoisAdminData, GetOrganizationsNoAdminData, GetOrganizationsAdminData, GetMembersNoAdminData, GetMembersAdminData, GetFriendsAdminData, GetSubscriptionsData, GetSubscriptionsAdminData, GetSubscribersData, GetSubscribersAdminData, GetContributorsNoAdminData, GetContributorsAdminData, GetBadgesData, GetBadgesFiltersData, ConnectData, DisconnectData, GetElementsKeyData, GetFavorisData, DeleteFavorisData, AddFavorisData, AddOrganizationData, AddProjectData, AddPoiData, AddEventData, DeletePoiData, DeleteEventData, DeleteElementData, AddImageElementData, LinkValidateData, SearchMemberAutocompleteData, GetNotificationsData, GetNotificationsCountData, NotificationUpdateData, MarkNotificationAsReadData, ActivitypubSearchData, ActivitypubLinkData, ActivitypubGetCommunityData, GetBadgeData, AddBadgesData, AssignBadgesData, GetEventsData, ShareEventsData, InviteEventData, FollowData, GetCostumJsonData, GlobalAutocompleteCostumData, CostumEventRequestActorsData, CostumEventRequestSubeventsData, CostumEventRequestElementEventData, CostumEventRequestCategoriesData, CostumEventRequestDatesData, CostumEventRequestEventData, CostumEventRequestLinkTlToEventData, CostumEventRequestLoadContextTagData, GetGalleryData, GetAttendeesNoAdminData, GetAttendeesAdminData, CoformAnswersSearchData, CoformAnswersByIdData, GetCoformByIdData, CoformUploadAnswerFileData, CoformGetAnswerFilesData, SaveCoformAnswerData, AddVoteData, AddReportAbuseData, UpdatePathValueData, DeleteDocumentByContextData, DeleteDocumentByIdData, DemoteAdminData, CostumFilterCoformData, GetCountriesData, SearchZonesData, CoformAnswersByFormsData, GenerateAnswerFromFormData, FundingEnvelopeData, CoremuOperationData, CostumProjectActionRequestNewData, CostumProjectActionRequestSetStatusData, CostumProjectActionRequestSetDateData, CostumProjectActionRequestSetContributorsData, CostumProjectActionRequestCancelData, CostumProjectActionRequestArchiveData, LinkDiscourseAccountData, UnlinkDiscourseAccountData, DiscourseProfileData, DiscourseCheckEmailData, DiscourseDismissLinkData, LinkMediawikiAccountData, UnlinkMediawikiAccountData, GetMediawikiContributionsData, AddClassifiedData } from "./EndpointApi.types.js";
3
3
  /**
4
4
  * Classe EndpointApi générée automatiquement depuis endpoints-copie.json
5
5
  */
@@ -1181,6 +1181,56 @@ export declare class EndpointApi {
1181
1181
  * @throws {Error} - En cas d'erreur inattendue.
1182
1182
  */
1183
1183
  costumProjectActionRequestNew(data: CostumProjectActionRequestNewData): Promise<any>;
1184
+ /**
1185
+ * Change le statut d'une action (avec logique métier) : Change le status d'une action via l'endpoint dédié backend. Ajoute une entrée à updateStatus[], gère les tags (discuter/totest/next), auto-injecte startDate/endDate selon le status, gère tracking, envoie une notification Rocket.Chat au parent. NE PAS confondre avec UPDATE_PATH_VALUE qui bypass toute cette logique.
1186
+ * Constant : COSTUM_PROJECT_ACTION_REQUEST_SET_STATUS
1187
+ * @param data - Données envoyées à l'API
1188
+ * @returns Les données de réponse.
1189
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1190
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1191
+ * @throws {Error} - En cas d'erreur inattendue.
1192
+ */
1193
+ costumProjectActionRequestSetStatus(data: CostumProjectActionRequestSetStatusData): Promise<any>;
1194
+ /**
1195
+ * Met à jour les dates d'une action : Met à jour startDate et/ou endDate d'une action via l'endpoint dédié. Supporte nativement l'effacement (envoyer chaîne vide → $unset). Parser de date robuste côté backend.
1196
+ * Constant : COSTUM_PROJECT_ACTION_REQUEST_SET_DATE
1197
+ * @param data - Données envoyées à l'API
1198
+ * @returns Les données de réponse.
1199
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1200
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1201
+ * @throws {Error} - En cas d'erreur inattendue.
1202
+ */
1203
+ costumProjectActionRequestSetDate(data: CostumProjectActionRequestSetDateData): Promise<any>;
1204
+ /**
1205
+ * Définit les contributeurs d'une action : Modifie links.contributors d'une action via 3 modes : (A) `contributors` array de userIds = remplace toute la liste ; (B) `contributor` + `participate=1` = ajoute un user ; (C) `contributor` + `participate=0` = retire un user. Valide les bornes `min`/`max` côté backend. Émet `.set-contributors{parentId}` et `.cd-int-contributors` aux clients socket.
1206
+ * Constant : COSTUM_PROJECT_ACTION_REQUEST_SET_CONTRIBUTORS
1207
+ * @param data - Données envoyées à l'API
1208
+ * @returns Les données de réponse.
1209
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1210
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1211
+ * @throws {Error} - En cas d'erreur inattendue.
1212
+ */
1213
+ costumProjectActionRequestSetContributors(data: CostumProjectActionRequestSetContributorsData): Promise<any>;
1214
+ /**
1215
+ * Annule une action : Annule une action : status=closed + unset tracking + retire le tag 'totest'.
1216
+ * Constant : COSTUM_PROJECT_ACTION_REQUEST_CANCEL
1217
+ * @param data - Données envoyées à l'API
1218
+ * @returns Les données de réponse.
1219
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1220
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1221
+ * @throws {Error} - En cas d'erreur inattendue.
1222
+ */
1223
+ costumProjectActionRequestCancel(data: CostumProjectActionRequestCancelData): Promise<any>;
1224
+ /**
1225
+ * Archive une action : Archive une action : status=disabled + unset tracking.
1226
+ * Constant : COSTUM_PROJECT_ACTION_REQUEST_ARCHIVE
1227
+ * @param data - Données envoyées à l'API
1228
+ * @returns Les données de réponse.
1229
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1230
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1231
+ * @throws {Error} - En cas d'erreur inattendue.
1232
+ */
1233
+ costumProjectActionRequestArchive(data: CostumProjectActionRequestArchiveData): Promise<any>;
1184
1234
  /**
1185
1235
  * Interoperabilité Discourse Lié un compte : Lier un compte Discourse
1186
1236
  * Constant : LINK_DISCOURSE_ACCOUNT
@@ -5145,6 +5145,69 @@ export interface CostumProjectActionRequestNewData {
5145
5145
  tags?: string[];
5146
5146
  [k: string]: unknown;
5147
5147
  }
5148
+ export interface CostumProjectActionRequestSetStatusData {
5149
+ /**
5150
+ * ID de l'action
5151
+ */
5152
+ id: string;
5153
+ /**
5154
+ * Nouveau statut. Triggers backend : 'done' set endDate=now, 'tracking' set startDate=now+tracking:true, 'discuter'/'next'/'totest' ajoutent un tag et forcent status='todo', 'todo' unset startDate/endDate, 'closed' purge les tags discuter/totest/next, 'disabled' unset tracking.
5155
+ */
5156
+ status: "todo" | "done" | "tracking" | "discuter" | "next" | "totest" | "disabled" | "closed";
5157
+ /**
5158
+ * Optionnel : userId qui effectue le changement (utilisé pour updateStatus[].author et notification RC). Par défaut session userId.
5159
+ */
5160
+ user?: string;
5161
+ [k: string]: unknown;
5162
+ }
5163
+ export interface CostumProjectActionRequestSetDateData {
5164
+ /**
5165
+ * ID de l'action
5166
+ */
5167
+ id: string;
5168
+ /**
5169
+ * Date de début ISO 8601, ou chaîne vide pour effacer ($unset)
5170
+ */
5171
+ startDate?: string;
5172
+ /**
5173
+ * Date de fin ISO 8601, ou chaîne vide pour effacer ($unset)
5174
+ */
5175
+ endDate?: string;
5176
+ [k: string]: unknown;
5177
+ }
5178
+ export interface CostumProjectActionRequestSetContributorsData {
5179
+ /**
5180
+ * ID de l'action (côté backend lu via $_POST['action'], pas 'id')
5181
+ */
5182
+ action: string;
5183
+ /**
5184
+ * Mode A : remplace la liste complète des contributeurs par cet array de userIds.
5185
+ */
5186
+ contributors?: string[];
5187
+ /**
5188
+ * Mode B/C : userId à ajouter (participate=1) ou retirer (participate=0).
5189
+ */
5190
+ contributor?: string;
5191
+ /**
5192
+ * Mode B/C : 1=join, 0=quit. Couplé avec `contributor`.
5193
+ */
5194
+ participate?: 0 | 1;
5195
+ [k: string]: unknown;
5196
+ }
5197
+ export interface CostumProjectActionRequestCancelData {
5198
+ /**
5199
+ * ID de l'action à annuler
5200
+ */
5201
+ id: string;
5202
+ [k: string]: unknown;
5203
+ }
5204
+ export interface CostumProjectActionRequestArchiveData {
5205
+ /**
5206
+ * ID de l'action à archiver
5207
+ */
5208
+ id: string;
5209
+ [k: string]: unknown;
5210
+ }
5148
5211
  export interface LinkDiscourseAccountData {
5149
5212
  /**
5150
5213
  * Nom d'utilisateur du compte Discourse
@@ -17,6 +17,27 @@ export declare function registerEntity(tag: EntityTag, EntityClass: EntityClass)
17
17
  * Si la collection ou la métadonnée d'entité est absente, renvoie l'objet d'origine.
18
18
  */
19
19
  export declare function fromEntityJSON(json: unknown, parent?: ApiClient | BaseEntity | null): BaseEntity | unknown | null;
20
+ /**
21
+ * Walker récursif : parcourt un objet/tableau et ressuscite toutes les entités
22
+ * sérialisées (marqueurs `__isSerializedEntity` / `__entityTag`) rencontrées.
23
+ *
24
+ * Pensé pour les wrappers non-entité retournés par certains endpoints (ex: `fundingEnvelope`)
25
+ * ou pour réhydrater un état côté client après un transfert JSON (SSR, cache restore).
26
+ *
27
+ * Dates, RegExp et primitives sont préservées. Pour les entités, la chaîne de parents
28
+ * est reconstruite automatiquement depuis les méta embarquées par `toJSON()`.
29
+ *
30
+ * @param obj - L'objet à parcourir (wrapper, array, primitive…)
31
+ * @param parent - Parent racine (typiquement l'ApiClient côté client)
32
+ * @returns L'objet avec toutes les entités revived
33
+ *
34
+ * @example
35
+ * // Côté client SSR : revive l'état dehydraté
36
+ * const apiClient = new ApiClient({ baseURL });
37
+ * const envelope = reviveEntities(window.__INIT__.envelope, apiClient);
38
+ * envelope.projects[0].serverData.actions[0]; // Action instance
39
+ */
40
+ export declare function reviveEntities<T = unknown>(obj: unknown, parent?: ApiClient | BaseEntity | null): T;
20
41
  /**
21
42
  * Crée une instance d'entité basée sur le seul nom de la collection.
22
43
  */
@@ -142,6 +142,14 @@ export declare class Project extends BaseEntity<ProjectItemNormalized> {
142
142
  * Crée une instance de news et la récupère si nécessaire.
143
143
  */
144
144
  news(newsData?: Parameters<BaseEntity<ProjectItemNormalized>["news"]>[0]): Promise<import("./News.js").News>;
145
+ /**
146
+ * Vérifie qu'un milestoneId existe dans `serverData.oceco.milestones[]`.
147
+ * Sert à valider une référence avant d'attacher une entité (Action) à un milestone.
148
+ *
149
+ * @param milestoneId - L'ID du milestone à chercher.
150
+ * @returns `true` si trouvé, `false` sinon (y compris si oceco/milestones absents).
151
+ */
152
+ hasMilestone(milestoneId: string): boolean;
145
153
  /**
146
154
  * {@inheritDoc BaseEntity#action}
147
155
  *