Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Quick Reference: Top 5 actionable improvements that can be implemented immediately
1. 🔴 Fix Push Notification Security Issue (30 min)
Critical: Multi-tenancy vulnerability in push subscriptions.
Fix:
-- Migration: Fix endpoint uniqueness constraint
ALTER TABLE pf_push_subscriptions
DROP CONSTRAINT IF EXISTS pf_push_subscriptions_endpoint_key;
ALTER TABLE pf_push_subscriptions
ADD CONSTRAINT pf_push_subscriptions_user_endpoint_unique
UNIQUE (user_id, endpoint);
-- Add UPDATE RLS policy
CREATE POLICY "pf_push_subscriptions_update" ON pf_push_subscriptions
FOR UPDATE USING (user_id = auth.uid());
Update edge function:
// supabase/functions/save-push-subscription/index.ts
.upsert({...}, {
onConflict: 'user_id,endpoint', // Composite key
})
2. 🔴 Complete Push Notification Implementation (4-6 hours)
Current: TODO in send-push-notification function.
Add to edge function:
import { webpush } from 'https://deno.land/x/webpush@v1.0.0/mod.ts';
// Replace TODO section with:
const subscription = {
endpoint: sub.endpoint,
keys: { p256dh: sub.p256dh_key, auth: sub.auth_key },
};
await webpush.sendNotification(subscription, payload, {
vapidDetails: {
subject: VAPID_SUBJECT,
publicKey: VAPID_PUBLIC_KEY,
privateKey: VAPID_PRIVATE_KEY,
},
});
Add service worker handler:
// In VitePWA service worker or public/sw.js
self.addEventListener('push', (event) => {
const data = event.data?.json() || {};
event.waitUntil(
self.registration.showNotification(data.title, {
body: data.body,
icon: data.icon || '/icons/icon-192x192.png',
badge: '/icons/badge-72x72.png',
data: { url: data.action_url || '/' },
})
);
});
self.addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data?.url || '/')
);
});
3. 🟠 Add Notification Quick Actions (2-3 hours)
Enhancement: Allow users to approve/reject directly from notification.
Implementation:
// src/platform/notifications/utils/notificationActions.ts
export const getNotificationActions = (type: notification_type) => {
const actions: Record<notification_type, Action[]> = {
approval_request: [
{ label: 'Approve', action: 'approve', icon: CheckCircle },
{ label: 'Reject', action: 'reject', variant: 'destructive' },
],
// ... other types
};
return actions[type] || [];
};
Add to NotificationItem:
{actions.length > 0 && (
<div className="flex gap-2 mt-2">
{actions.map((action) => (
<Button
key={action.action}
size="sm"
variant={action.variant}
onClick={() => handleAction(action.action)}
>
{action.label}
</Button>
))}
</div>
)}
4. 🟠 Add Notification Grouping (3-4 hours)
Enhancement: Group related notifications (e.g., 5 form submissions in 5 minutes).
Implementation:
// src/platform/notifications/utils/notificationGrouping.ts
export const groupNotifications = (
notifications: Notification[],
timeWindowMinutes = 5
): NotificationGroup[] => {
const groups = new Map<string, Notification[]>();
notifications.forEach((notif) => {
const key = `${notif.type}-${notif.data?.entity_id || 'none'}`;
const existing = groups.get(key) || [];
if (existing.length > 0) {
const latest = new Date(existing[0].created_at);
const current = new Date(notif.created_at);
const diffMinutes = (current.getTime() - latest.getTime()) / 60000;
if (diffMinutes > timeWindowMinutes) {
groups.set(`${key}-${notif.id}`, [notif]);
return;
}
}
existing.unshift(notif);
groups.set(key, existing);
});
return Array.from(groups.entries()).map(([key, group]) => ({
id: group[0].id,
type: group[0].type,
title: group[0].title,
count: group.length,
notifications: group,
}));
};
5. 🟡 Add App Badge Updates (1 hour)
Enhancement: Show unread count on app icon.
Implementation:
// src/platform/notifications/useNotifications.ts
useEffect(() => {
if ('setAppBadge' in navigator && unreadCount !== undefined) {
if (unreadCount > 0) {
navigator.setAppBadge(unreadCount);
} else {
navigator.clearAppBadge();
}
}
}, [unreadCount]);
Priority Order
- Security Fix (P0) - Do immediately
- Complete Push (P0) - Critical for production
- Quick Actions (P1) - High user value
- Grouping (P1) - Reduces inbox clutter
- App Badge (P2) - Nice UX enhancement
Total Estimated Time: 1-2 days for all 5 items
See full recommendations for complete details.