feat: add reminders schema management for Appwrite integration
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
const sdk: any = require('node-appwrite');
|
||||
import type Amayo from '../client';
|
||||
import { getDatabases, isAppwriteConfigured, APPWRITE_COLLECTION_REMINDERS_ID, APPWRITE_DATABASE_ID } from './appwrite';
|
||||
import { ensureRemindersSchema } from './remindersSchema';
|
||||
|
||||
export type ReminderDoc = {
|
||||
$id?: string;
|
||||
@@ -23,9 +24,20 @@ export type ReminderRow = ReminderDoc & {
|
||||
$databaseId?: string;
|
||||
};
|
||||
|
||||
let schemaEnsured = false;
|
||||
async function ensureSchemaOnce() {
|
||||
if (schemaEnsured) return;
|
||||
try {
|
||||
await ensureRemindersSchema();
|
||||
} finally {
|
||||
schemaEnsured = true;
|
||||
}
|
||||
}
|
||||
|
||||
export async function scheduleReminder(doc: ReminderDoc): Promise<string> {
|
||||
const db = getDatabases();
|
||||
if (!db || !isAppwriteConfigured()) throw new Error('Appwrite no está configurado');
|
||||
await ensureSchemaOnce();
|
||||
const data = {
|
||||
userId: doc.userId,
|
||||
guildId: doc.guildId ?? null,
|
||||
@@ -41,6 +53,7 @@ export async function scheduleReminder(doc: ReminderDoc): Promise<string> {
|
||||
async function fetchDueReminders(limit = 25): Promise<ReminderRow[]> {
|
||||
const db = getDatabases();
|
||||
if (!db || !isAppwriteConfigured()) return [];
|
||||
try { await ensureSchemaOnce(); } catch {}
|
||||
const nowIso = new Date().toISOString();
|
||||
try {
|
||||
const list = await db.listDocuments(APPWRITE_DATABASE_ID, APPWRITE_COLLECTION_REMINDERS_ID, [
|
||||
|
||||
56
src/core/api/remindersSchema.ts
Normal file
56
src/core/api/remindersSchema.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const sdk: any = require('node-appwrite');
|
||||
import { getDatabases, isAppwriteConfigured, APPWRITE_COLLECTION_REMINDERS_ID, APPWRITE_DATABASE_ID } from './appwrite';
|
||||
|
||||
export async function ensureRemindersSchema() {
|
||||
if (!isAppwriteConfigured()) return;
|
||||
const db = getDatabases();
|
||||
if (!db) return;
|
||||
|
||||
const databaseId = APPWRITE_DATABASE_ID;
|
||||
const collectionId = APPWRITE_COLLECTION_REMINDERS_ID;
|
||||
|
||||
// 1) Asegurar colección
|
||||
try {
|
||||
await db.getCollection(databaseId, collectionId);
|
||||
} catch {
|
||||
try {
|
||||
await db.createCollection(databaseId, collectionId, collectionId, [
|
||||
// Permisos por defecto: accesible solo por server via API Key
|
||||
]);
|
||||
// Nota: No añadimos permisos de lectura pública para evitar fuga de datos
|
||||
} catch (e) {
|
||||
console.warn('No se pudo crear la colección de recordatorios (puede existir ya):', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Asegurar atributos requeridos
|
||||
const createIfMissing = async (fn: () => Promise<any>) => {
|
||||
try { await fn(); } catch (e: any) {
|
||||
const msg = String(e?.message || e);
|
||||
if (!/already exists|attribute_already_exists/i.test(msg)) {
|
||||
// Otros errores se muestran
|
||||
console.warn('No se pudo crear atributo:', msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await createIfMissing(() => db.createStringAttribute(databaseId, collectionId, 'userId', 64, true));
|
||||
await createIfMissing(() => db.createStringAttribute(databaseId, collectionId, 'guildId', 64, false));
|
||||
await createIfMissing(() => db.createStringAttribute(databaseId, collectionId, 'channelId', 64, false));
|
||||
await createIfMissing(() => db.createStringAttribute(databaseId, collectionId, 'message', 2048, true));
|
||||
await createIfMissing(() => db.createDatetimeAttribute(databaseId, collectionId, 'executeAt', true));
|
||||
await createIfMissing(() => db.createDatetimeAttribute(databaseId, collectionId, 'createdAt', true));
|
||||
|
||||
// 3) Índice por executeAt para consultas por vencimiento
|
||||
try {
|
||||
//@ts-ignore
|
||||
await db.createIndex(databaseId, collectionId, 'idx_executeAt_asc', 'key', ['executeAt'], ['ASC']);
|
||||
} catch (e: any) {
|
||||
const msg = String(e?.message || e);
|
||||
if (!/already exists|index_already_exists/i.test(msg)) {
|
||||
console.warn('No se pudo crear índice executeAt:', msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user