v0.9.63 updated for mobile

This commit is contained in:
2026-03-17 21:17:07 -04:00
parent 85fc75dd19
commit 4602c2e586
12 changed files with 641 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "jama-backend",
"version": "0.9.62",
"version": "0.9.63",
"description": "TeamChat backend server",
"main": "src/index.js",
"scripts": {

View File

@@ -432,6 +432,7 @@ function initDb() {
// Migration: add columns if missing (must run before inserts)
try { db.exec("ALTER TABLE event_types ADD COLUMN is_protected INTEGER NOT NULL DEFAULT 0"); } catch(e) {}
try { db.exec("ALTER TABLE event_types ADD COLUMN default_duration_hrs REAL"); } catch(e) {}
try { db.exec("ALTER TABLE events ADD COLUMN recurrence_rule TEXT"); } catch(e) {}
// Delete the legacy "Default" type — "Event" is the canonical default
db.prepare("DELETE FROM event_types WHERE name = 'Default'").run();
// Seed built-in event types — "Event" is the primary default (1hr, protected, cannot edit/delete)

View File

@@ -36,6 +36,9 @@ function enrichEvent(db, event) {
event.event_type = event.event_type_id
? db.prepare('SELECT * FROM event_types WHERE id = ?').get(event.event_type_id)
: null;
if (event.recurrence_rule && typeof event.recurrence_rule === 'string') {
try { event.recurrence_rule = JSON.parse(event.recurrence_rule); } catch(e) { event.recurrence_rule = null; }
}
event.user_groups = db.prepare(`
SELECT ug.id, ug.name FROM event_user_groups eug
JOIN user_groups ug ON ug.id = eug.user_group_id
@@ -150,15 +153,16 @@ router.get('/:id', authMiddleware, (req, res) => {
// Create event
router.post('/', authMiddleware, teamManagerMiddleware, (req, res) => {
const { title, eventTypeId, startAt, endAt, allDay, location, description, isPublic, trackAvailability, userGroupIds = [] } = req.body;
const { title, eventTypeId, startAt, endAt, allDay, location, description, isPublic, trackAvailability, userGroupIds = [], recurrenceRule } = req.body;
if (!title?.trim()) return res.status(400).json({ error: 'Title required' });
if (!startAt || !endAt) return res.status(400).json({ error: 'Start and end time required' });
const db = getDb();
const r = db.prepare(`INSERT INTO events (title, event_type_id, start_at, end_at, all_day, location, description, is_public, track_availability, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(
const r = db.prepare(`INSERT INTO events (title, event_type_id, start_at, end_at, all_day, location, description, is_public, track_availability, recurrence_rule, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(
title.trim(), eventTypeId || null, startAt, endAt,
allDay ? 1 : 0, location || null, description || null,
isPublic !== false ? 1 : 0, trackAvailability ? 1 : 0, req.user.id
isPublic !== false ? 1 : 0, trackAvailability ? 1 : 0,
recurrenceRule ? JSON.stringify(recurrenceRule) : null, req.user.id
);
const eventId = r.lastInsertRowid;
for (const ugId of (Array.isArray(userGroupIds) ? userGroupIds : []))
@@ -172,12 +176,14 @@ router.patch('/:id', authMiddleware, teamManagerMiddleware, (req, res) => {
const db = getDb();
const event = db.prepare('SELECT * FROM events WHERE id = ?').get(req.params.id);
if (!event) return res.status(404).json({ error: 'Not found' });
const { title, eventTypeId, startAt, endAt, allDay, location, description, isPublic, trackAvailability, userGroupIds } = req.body;
const { title, eventTypeId, startAt, endAt, allDay, location, description, isPublic, trackAvailability, userGroupIds, recurrenceRule } = req.body;
db.prepare(`UPDATE events SET
title = COALESCE(?, title), event_type_id = ?, start_at = COALESCE(?, start_at),
end_at = COALESCE(?, end_at), all_day = COALESCE(?, all_day),
location = ?, description = ?, is_public = COALESCE(?, is_public),
track_availability = COALESCE(?, track_availability), updated_at = datetime('now')
track_availability = COALESCE(?, track_availability),
recurrence_rule = ?,
updated_at = datetime('now')
WHERE id = ?`).run(
title?.trim() || null, eventTypeId !== undefined ? (eventTypeId || null) : event.event_type_id,
startAt || null, endAt || null, allDay !== undefined ? (allDay ? 1 : 0) : null,
@@ -185,6 +191,7 @@ router.patch('/:id', authMiddleware, teamManagerMiddleware, (req, res) => {
description !== undefined ? (description || null) : event.description,
isPublic !== undefined ? (isPublic ? 1 : 0) : null,
trackAvailability !== undefined ? (trackAvailability ? 1 : 0) : null,
recurrenceRule !== undefined ? (recurrenceRule ? JSON.stringify(recurrenceRule) : null) : event.recurrence_rule,
req.params.id
);
if (Array.isArray(userGroupIds)) {