feat: version 4.4.0 -- Calendario de reuniones

Menu Calendario (Mes/Semana/Dia/Agenda) para agendar reuniones con participantes
internos y externos, RSVP, vinculo a proyecto, vencimientos de actividades,
invitaciones iCalendar por correo, recurrencia con excepciones, recordatorios
in-app y aviso de choques. Migracion 034_meetings.sql.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-28 11:04:41 -05:00
parent a6cc41666e
commit 6066f27ba0
34 changed files with 986 additions and 16 deletions
+3 -3
View File
@@ -3,12 +3,12 @@ import { getSmtpConfigInternal } from '../modules/settings/service.js';
// Degradacion a modo dev cuando el SMTP no esta configurado (regla del orquestador): en vez de
// fallar, se loguea el contenido/enlace y el flujo que llamo a esto sigue funcionando.
export async function sendMail({ to, subject, html }) {
export async function sendMail({ to, subject, html, icalEvent }) {
try {
const config = await getSmtpConfigInternal();
if (!config) {
console.log(`[mail:dev] to=${to} subject="${subject}"\n${html}`);
console.log(`[mail:dev] to=${to} subject="${subject}"\n${html}${icalEvent?.content ? `\n[icalEvent]\n${icalEvent.content}` : ''}`);
return { sent: false, dev: true };
}
@@ -22,7 +22,7 @@ export async function sendMail({ to, subject, html }) {
// Nunca dejar que un fallo de envio (SMTP mal configurado, host caido) tumbe al que llama —
// critico para forgot-password, que siempre debe responder generico sin importar el resultado.
await transporter.sendMail({ from: config.from, to, subject, html });
await transporter.sendMail({ from: config.from, to, subject, html, ...(icalEvent ? { icalEvent } : {}) });
return { sent: true, dev: false };
} catch (err) {
console.error('[mail:error]', err.message);