Add Stripe notifications, messaging improvements, and code cleanup

Stripe Notifications:
- Add periodic task to check Stripe Connect accounts for requirements
- Create in-app notifications for business owners when action needed
- Add management command to setup Stripe periodic tasks
- Display Stripe notifications with credit card icon in notification bell
- Navigate to payments page when Stripe notification clicked

Messaging Improvements:
- Add "Everyone" option to broadcast message recipients
- Allow sending messages to yourself (remove self-exclusion)
- Fix broadcast message ID not returned after creation
- Add real-time websocket support for broadcast notifications
- Show toast when broadcast message received via websocket

UI Fixes:
- Remove "View all" button from notifications (no page exists)
- Add StripeNotificationBanner component for Connect alerts
- Connect useUserNotifications hook in TopBar for app-wide websocket

Code Cleanup:
- Remove legacy automations app and plugin system
- Remove safe_scripting module (moved to Activepieces)
- Add migration to remove plugin-related models
- Various test improvements and coverage additions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-22 15:35:53 -05:00
parent 28d6cee207
commit f1b1f18bc5
86 changed files with 21364 additions and 19708 deletions

View File

@@ -181,13 +181,26 @@ const Messages: React.FC = () => {
},
});
// All available target roles (excluding 'everyone' which is a meta-option)
const allRoles = ['owner', 'staff', 'customer'];
// Handlers
const handleRoleToggle = (role: string) => {
setSelectedRoles((prev) =>
prev.includes(role) ? prev.filter((r) => r !== role) : [...prev, role]
);
if (role === 'everyone') {
// Toggle all roles on/off
setSelectedRoles((prev) =>
prev.length === allRoles.length ? [] : [...allRoles]
);
} else {
setSelectedRoles((prev) =>
prev.includes(role) ? prev.filter((r) => r !== role) : [...prev, role]
);
}
};
// Check if all roles are selected (for "Everyone" tile)
const isEveryoneSelected = allRoles.every(role => selectedRoles.includes(role));
const handleAddUser = (user: RecipientOption) => {
if (!selectedUsers.find(u => u.id === user.id)) {
setSelectedUsers((prev) => [...prev, user]);
@@ -253,6 +266,7 @@ const Messages: React.FC = () => {
{ value: 'owner', label: 'Owners', icon: Users, description: 'Business owners' },
{ value: 'staff', label: 'Staff', icon: Users, description: 'Employees' },
{ value: 'customer', label: 'Customers', icon: Users, description: 'Clients' },
{ value: 'everyone', label: 'Everyone', icon: Users, description: 'All users' },
];
const deliveryMethodOptions = [
@@ -425,7 +439,7 @@ const Messages: React.FC = () => {
label={role.label}
icon={role.icon}
description={role.description}
selected={selectedRoles.includes(role.value)}
selected={role.value === 'everyone' ? isEveryoneSelected : selectedRoles.includes(role.value)}
onClick={() => handleRoleToggle(role.value)}
/>
))}