diff --git a/.env.example b/.env.example index 39752c4..b12f551 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,7 @@ PROJECT_NAME=jama # Image version to run (set by build.sh, or use 'latest') -JAMA_VERSION=0.9.36 +JAMA_VERSION=0.9.37 # App port — the host port Docker maps to the container PORT=3000 diff --git a/backend/package.json b/backend/package.json index 30d4f2c..7fb144a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "jama-backend", - "version": "0.9.36", + "version": "0.9.37", "description": "TeamChat backend server", "main": "src/index.js", "scripts": { diff --git a/backend/src/models/db.js b/backend/src/models/db.js index ba64527..1421885 100644 --- a/backend/src/models/db.js +++ b/backend/src/models/db.js @@ -320,6 +320,14 @@ function initDb() { db.exec("ALTER TABLE groups ADD COLUMN is_multi_group INTEGER NOT NULL DEFAULT 0"); console.log('[DB] Migration: added is_multi_group column to groups'); } catch (e) { /* already exists */ } + // Back-fill feature_schedule_manager for installs that registered before this setting existed + try { + const appType = db.prepare("SELECT value FROM settings WHERE key = 'app_type'").get(); + if (appType && appType.value === 'JAMA-Team') { + db.prepare("INSERT INTO settings (key, value) VALUES ('feature_schedule_manager', 'true') ON CONFLICT(key) DO UPDATE SET value = 'true' WHERE value = 'false'").run(); + } + } catch(e) {} + // Back-fill is_multi_group for any existing multi-group DM groups try { db.exec("UPDATE groups SET is_multi_group = 1 WHERE id IN (SELECT dm_group_id FROM multi_group_dms WHERE dm_group_id IS NOT NULL)"); diff --git a/backend/src/routes/usergroups.js b/backend/src/routes/usergroups.js index 62d0ece..c2ce0c9 100644 --- a/backend/src/routes/usergroups.js +++ b/backend/src/routes/usergroups.js @@ -46,6 +46,13 @@ function getUserIdsForGroup(db, userGroupId) { return db.prepare('SELECT user_id FROM user_group_members WHERE user_group_id = ?').all(userGroupId).map(r => r.user_id); } +// ── Current user's group memberships (no admin required) ──────────────────────── +router.get('/me', authMiddleware, (req, res) => { + const db = getDb(); + const groupIds = db.prepare('SELECT user_group_id FROM user_group_members WHERE user_id = ?').all(req.user.id).map(r => r.user_group_id); + res.json({ groupIds }); +}); + // ── MULTI-GROUP DMs — must come before /:id ─────────────────────────────────── router.get('/multigroup', authMiddleware, adminMiddleware, (req, res) => { diff --git a/build.sh b/build.sh index d468520..b786c62 100644 --- a/build.sh +++ b/build.sh @@ -13,7 +13,7 @@ # ───────────────────────────────────────────────────────────── set -euo pipefail -VERSION="${1:-0.9.36}" +VERSION="${1:-0.9.37}" ACTION="${2:-}" REGISTRY="${REGISTRY:-}" IMAGE_NAME="jama" diff --git a/frontend/package.json b/frontend/package.json index cf8443d..0c71276 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "jama-frontend", - "version": "0.9.36", + "version": "0.9.37", "private": true, "scripts": { "dev": "vite", diff --git a/frontend/src/pages/Chat.jsx b/frontend/src/pages/Chat.jsx index f34813e..7a68d0a 100644 --- a/frontend/src/pages/Chat.jsx +++ b/frontend/src/pages/Chat.jsx @@ -69,32 +69,30 @@ export default function Chat() { useEffect(() => { loadGroups(); }, [loadGroups]); - // Load feature flags on mount - useEffect(() => { + // Load feature flags + current user's group memberships on mount + const loadFeatures = useCallback(() => { api.getSettings().then(({ settings }) => { - setFeatures({ - branding: settings.feature_branding === 'true', - groupManager: settings.feature_group_manager === 'true', - scheduleManager: settings.feature_schedule_manager === 'true', - appType: settings.app_type || 'JAMA-Chat', + setFeatures(prev => ({ + ...prev, + branding: settings.feature_branding === 'true', + groupManager: settings.feature_group_manager === 'true', + scheduleManager: settings.feature_schedule_manager === 'true', + appType: settings.app_type || 'JAMA-Chat', teamGroupManagers: JSON.parse(settings.team_group_managers || '[]'), teamScheduleManagers: JSON.parse(settings.team_schedule_managers || '[]'), - }); + })); }).catch(() => {}); - const handler = () => api.getSettings().then(({ settings }) => { - setFeatures({ - branding: settings.feature_branding === 'true', - groupManager: settings.feature_group_manager === 'true', - scheduleManager: settings.feature_schedule_manager === 'true', - appType: settings.app_type || 'JAMA-Chat', - teamGroupManagers: JSON.parse(settings.team_group_managers || '[]'), - teamScheduleManagers: JSON.parse(settings.team_schedule_managers || '[]'), - }); + api.getMyUserGroups().then(({ groupIds }) => { + setFeatures(prev => ({ ...prev, userGroupMemberships: groupIds || [] })); }).catch(() => {}); - window.addEventListener('jama:settings-changed', handler); - return () => window.removeEventListener('jama:settings-changed', handler); }, []); + useEffect(() => { + loadFeatures(); + window.addEventListener('jama:settings-changed', loadFeatures); + return () => window.removeEventListener('jama:settings-changed', loadFeatures); + }, [loadFeatures]); + // Register / refresh push subscription useEffect(() => { if (!('serviceWorker' in navigator) || !('PushManager' in window)) return; diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index 4c9f0aa..7960394 100644 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -105,6 +105,7 @@ export const api = { updateTeamSettings: (body) => req('PATCH', '/settings/team', body), // User groups (Group Manager) + getMyUserGroups: () => req('GET', '/usergroups/me'), getUserGroups: () => req('GET', '/usergroups'), getUserGroup: (id) => req('GET', `/usergroups/${id}`), createUserGroup: (body) => req('POST', '/usergroups', body),