Files
musicland/functions/src/helpers/orders.js
T
2025-11-05 15:39:15 +01:00

93 lines
2.0 KiB
JavaScript

const admin = require("firebase-admin");
const { FieldValue } = require("firebase-admin/firestore");
const ORDER_TYPES = {
GIFT: "GIFT",
SONG: "SONG",
COINS: "COINS",
SUBSCRIPTION: "SUBSCRIPTION",
};
const ORDER_STATUS = {
PENDING: "PENDING",
APPLIED: "APPLIED",
REJECTED: "REJECTED",
};
const ORDERS_COLLECTION = "orders";
const isFiniteNumber = (value) => {
if (typeof value === "number" && Number.isFinite(value)) {
return true;
}
if (typeof value === "string") {
const parsed = Number(value);
return Number.isFinite(parsed);
}
return false;
};
const normalizeAmount = (amount) => {
if (!isFiniteNumber(amount)) {
return null;
}
return Number(amount);
};
const createOrderDocument = async ({
userId,
type,
amount,
songId = null,
createdBy = "system",
metadata = {},
orderId = null,
}) => {
if (!userId || typeof userId !== "string") {
throw new Error("[orders] Missing userId when creating order");
}
if (!Object.values(ORDER_TYPES).includes(type)) {
throw new Error(`[orders] Invalid order type "${type}"`);
}
const normalizedAmount = normalizeAmount(amount);
if (normalizedAmount === null || normalizedAmount === 0) {
throw new Error("[orders] Invalid order amount");
}
const payload = {
userId,
type,
amount: normalizedAmount,
songId: type === ORDER_TYPES.SONG ? songId || null : null,
createdAt: FieldValue.serverTimestamp(),
createdBy: createdBy || "system",
status: ORDER_STATUS.PENDING,
metadata: metadata || {},
};
const collectionRef = admin.firestore().collection(ORDERS_COLLECTION);
const orderRef = orderId ? collectionRef.doc(orderId) : collectionRef.doc();
if (orderId) {
const existingSnapshot = await orderRef.get();
if (existingSnapshot.exists) {
return { orderRef, orderId: orderRef.id };
}
}
await orderRef.set(payload);
return { orderRef, orderId: orderRef.id };
};
module.exports = {
ORDER_TYPES,
ORDER_STATUS,
ORDERS_COLLECTION,
createOrderDocument,
normalizeAmount,
};