192 lines
4.8 KiB
JavaScript
192 lines
4.8 KiB
JavaScript
/**
|
|
* Helpers pour la manipulation de données Firestore
|
|
*/
|
|
const admin = require("firebase-admin");
|
|
|
|
/**
|
|
* Convertit les Timestamps Firestore en ISO strings pour JSON
|
|
*/
|
|
function serializeTimestamps(data) {
|
|
if (!data) return data;
|
|
|
|
// Éviter la récursion sur les types Firestore spéciaux
|
|
if (data._firestore || data._path || data._converter) {
|
|
// C'est un objet Firestore interne, ne pas le traiter
|
|
if (data.id && data.path) {
|
|
// C'est une DocumentReference
|
|
return data.path;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const result = {...data};
|
|
|
|
for (const key in result) {
|
|
const value = result[key];
|
|
|
|
if (!value) {
|
|
continue;
|
|
}
|
|
|
|
// Gérer les Timestamps Firestore
|
|
if (value.toDate && typeof value.toDate === "function") {
|
|
result[key] = value.toDate().toISOString();
|
|
}
|
|
// Gérer les DocumentReference
|
|
else if (value.path && value.id && typeof value.path === "string") {
|
|
result[key] = value.path;
|
|
}
|
|
// Gérer les GeoPoint
|
|
else if (value.latitude !== undefined && value.longitude !== undefined) {
|
|
result[key] = {
|
|
latitude: value.latitude,
|
|
longitude: value.longitude,
|
|
};
|
|
}
|
|
// Gérer les tableaux
|
|
else if (Array.isArray(value)) {
|
|
result[key] = value.map((item) => {
|
|
if (!item || typeof item !== "object") return item;
|
|
|
|
// DocumentReference dans un tableau
|
|
if (item.path && item.id) {
|
|
return item.path;
|
|
}
|
|
// Timestamp dans un tableau
|
|
if (item.toDate && typeof item.toDate === "function") {
|
|
return item.toDate().toISOString();
|
|
}
|
|
// Objet normal
|
|
return serializeTimestamps(item);
|
|
});
|
|
}
|
|
// Gérer les objets imbriqués (mais pas les objets Firestore)
|
|
else if (typeof value === "object" && !value._firestore && !value._path) {
|
|
result[key] = serializeTimestamps(value);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Convertit les ISO strings en Timestamps Firestore
|
|
*/
|
|
function deserializeTimestamps(data, timestampFields = []) {
|
|
if (!data) return data;
|
|
|
|
const result = {...data};
|
|
|
|
for (const field of timestampFields) {
|
|
if (result[field] && typeof result[field] === "string") {
|
|
result[field] = admin.firestore.Timestamp.fromDate(new Date(result[field]));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Convertit les références DocumentReference en IDs
|
|
*/
|
|
function serializeReferences(data) {
|
|
if (!data) return data;
|
|
|
|
const result = {...data};
|
|
|
|
for (const key in result) {
|
|
if (result[key] && result[key].path && typeof result[key].path === "string") {
|
|
// C'est une DocumentReference
|
|
result[key] = result[key].id;
|
|
} else if (Array.isArray(result[key])) {
|
|
result[key] = result[key].map((item) => {
|
|
if (item && item.path && typeof item.path === "string") {
|
|
return item.id;
|
|
}
|
|
return item;
|
|
});
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Masque les champs sensibles selon les permissions
|
|
*/
|
|
function maskSensitiveFields(data, canViewSensitive) {
|
|
if (canViewSensitive) return data;
|
|
|
|
const masked = {...data};
|
|
|
|
// Masquer les prix si pas de permission manage_equipment
|
|
delete masked.purchasePrice;
|
|
delete masked.rentalPrice;
|
|
|
|
return masked;
|
|
}
|
|
|
|
/**
|
|
* Pagination helper
|
|
*/
|
|
function paginate(query, limit = 50, startAfter = null) {
|
|
let paginatedQuery = query.limit(limit);
|
|
|
|
if (startAfter) {
|
|
paginatedQuery = paginatedQuery.startAfter(startAfter);
|
|
}
|
|
|
|
return paginatedQuery;
|
|
}
|
|
|
|
/**
|
|
* Filtre les événements annulés
|
|
*/
|
|
function filterCancelledEvents(events) {
|
|
return events.filter((event) => event.status !== "CANCELLED");
|
|
}
|
|
|
|
/**
|
|
* Convertit les IDs en DocumentReference pour maintenir la compatibilité avec l'ancien format
|
|
* @param {Object} data - Données de l'événement
|
|
* @return {Object} - Données avec DocumentReference
|
|
*/
|
|
function convertIdsToReferences(data) {
|
|
if (!data) return data;
|
|
|
|
const result = {...data};
|
|
|
|
// Convertir EventType (ID → DocumentReference)
|
|
if (result.EventType && typeof result.EventType === "string" && !result.EventType.includes("/")) {
|
|
result.EventType = admin.firestore().collection("eventTypes").doc(result.EventType);
|
|
}
|
|
|
|
// Convertir customer (ID → DocumentReference)
|
|
if (result.customer && typeof result.customer === "string" && !result.customer.includes("/")) {
|
|
result.customer = admin.firestore().collection("customers").doc(result.customer);
|
|
}
|
|
|
|
// Convertir workforce (IDs → DocumentReference)
|
|
if (Array.isArray(result.workforce)) {
|
|
result.workforce = result.workforce.map((item) => {
|
|
if (typeof item === "string" && !item.includes("/")) {
|
|
return admin.firestore().collection("users").doc(item);
|
|
}
|
|
return item;
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
module.exports = {
|
|
serializeTimestamps,
|
|
deserializeTimestamps,
|
|
serializeReferences,
|
|
maskSensitiveFields,
|
|
paginate,
|
|
filterCancelledEvents,
|
|
convertIdsToReferences,
|
|
};
|
|
|