const { Client, Databases, Permission, Role } = require('node-appwrite'); const client = new Client() .setEndpoint('https://appwrite.almeira.com.co/v1') .setProject('69b84df5003bd8957c5c') .setKey('standard_cce3cdb866ea6433888d40cedd24dc45987372308fdc3dd0697de08648c0e5c7e04b02c3bcee271403fd656b00a5820f04c08b51631284a6e8a3582d8aed2aa33234f3c29cc777e9b162eb54810b789251b0d006a9a3b081ebc2da53b9baa94614b124b3508ad849fd9a4187cc6094f506d4b57f409b69d9562a74df594f3ec3'); const dbs = new Databases(client); const DB_ID = 'sneakers_multistore_db'; const COL_ID = 'coupons'; async function wait(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } async function createAttributeSafely(colId, type, key, params = {}) { try { if (type === 'string') { const size = params.size || 255; const req = params.required || false; const def = params.default || null; const isArray = params.array || false; await dbs.createStringAttribute(DB_ID, colId, key, size, req, def, isArray); } else if (type === 'integer') { const req = params.required || false; const min = params.min ?? -999999999; const max = params.max ?? 999999999; const def = params.default ?? null; const isArray = params.array || false; await dbs.createIntegerAttribute(DB_ID, colId, key, req, min, max, def, isArray); } else if (type === 'boolean') { const req = params.required || false; const def = params.default ?? null; const isArray = params.array || false; await dbs.createBooleanAttribute(DB_ID, colId, key, req, def, isArray); } console.log(` + Creado atributo ${key} en ${colId}`); } catch (e) { if (e.message && e.message.includes('already exists')) { console.log(` . Atributo ${key} ya existe en ${colId}`); } else { console.warn(` ! Error creando atributo ${key} en ${colId}:`, e.message); } } } async function main() { console.log('--- Configurando Colección de Cupones en ' + DB_ID + ' ---'); // 1. Crear colección 'coupons' si no existe try { await dbs.getCollection(DB_ID, COL_ID); console.log(`Colección '${COL_ID}' ya existe.`); } catch (e) { console.log(`Creando colección '${COL_ID}'...`); await dbs.createCollection( DB_ID, COL_ID, 'Cupones y Promociones', [ Permission.read(Role.any()), Permission.create(Role.any()), Permission.update(Role.any()), Permission.delete(Role.any()), ], false ); console.log(`Colección '${COL_ID}' creada con éxito.`); } // 2. Crear atributos de 'coupons' console.log('Creando atributos en coupons...'); await createAttributeSafely(COL_ID, 'string', 'code', { size: 50, required: true }); await createAttributeSafely(COL_ID, 'string', 'description', { size: 500, required: false }); await createAttributeSafely(COL_ID, 'string', 'discountType', { size: 20, required: true }); // 'percentage' | 'fixed' await createAttributeSafely(COL_ID, 'integer', 'discountValue', { required: true }); await createAttributeSafely(COL_ID, 'integer', 'minSpend', { required: false, default: 0 }); await createAttributeSafely(COL_ID, 'integer', 'maxDiscount', { required: false, default: 0 }); await createAttributeSafely(COL_ID, 'integer', 'usageLimit', { required: false, default: 0 }); await createAttributeSafely(COL_ID, 'integer', 'usageCount', { required: false, default: 0 }); await createAttributeSafely(COL_ID, 'string', 'expiresAt', { size: 100, required: false }); await createAttributeSafely(COL_ID, 'string', 'startDate', { size: 100, required: false }); await createAttributeSafely(COL_ID, 'boolean', 'isActive', { required: false, default: true }); await createAttributeSafely(COL_ID, 'string', 'applicableCategories', { size: 1000, required: false }); // 3. Crear atributos en 'orders' para cupón console.log('Añadiendo atributos de cupón en orders...'); await createAttributeSafely('orders', 'string', 'couponCode', { size: 50, required: false }); await createAttributeSafely('orders', 'integer', 'discountAmount', { required: false, default: 0 }); // Esperar a que Appwrite procese los atributos console.log('Esperando indexación de atributos...'); await wait(3000); // 4. Sembrar cupones iniciales si está vacía try { const existing = await dbs.listDocuments(DB_ID, COL_ID); if (!existing.documents || existing.documents.length === 0) { console.log('Sembrando cupones promocionales iniciales...'); const in7Days = new Date(); in7Days.setDate(in7Days.getDate() + 7); const in30Days = new Date(); in30Days.setDate(in30Days.getDate() + 30); const INITIAL_COUPONS = [ { code: 'DRIPZONE10', description: '10% de descuento en toda la tienda para nuevos clientes', discountType: 'percentage', discountValue: 10, minSpend: 80000, maxDiscount: 35000, usageLimit: 100, usageCount: 0, expiresAt: in30Days.toISOString(), startDate: new Date().toISOString(), isActive: true, applicableCategories: '', }, { code: 'LANZAMIENTO20K', description: '$20.000 COP de descuento fijo por apertura de temporada', discountType: 'fixed', discountValue: 20000, minSpend: 130000, maxDiscount: 0, usageLimit: 50, usageCount: 0, expiresAt: in7Days.toISOString(), startDate: new Date().toISOString(), isActive: true, applicableCategories: '', }, { code: 'FLASH15', description: 'Campaña relámpago: 15% de descuento por 48 horas', discountType: 'percentage', discountValue: 15, minSpend: 100000, maxDiscount: 45000, usageLimit: 30, usageCount: 0, expiresAt: new Date(Date.now() + 48 * 3600 * 1000).toISOString(), startDate: new Date().toISOString(), isActive: true, applicableCategories: '', } ]; for (const coupon of INITIAL_COUPONS) { const docId = `cup-${coupon.code.toLowerCase()}`; try { await dbs.createDocument(DB_ID, COL_ID, docId, coupon); console.log(` + Cupón ${coupon.code} creado con éxito.`); } catch (e) { console.warn(` ! No se pudo crear cupón ${coupon.code}:`, e.message); } } } else { console.log(`La colección ya cuenta con ${existing.documents.length} cupones.`); } } catch (e) { console.warn('Error verificando/sembrando cupones:', e.message); } console.log('✅ Esquema y Cupones configurados correctamente en Appwrite.'); } main().catch(console.error);