skills/ballee/bulk-support-message/SKILL.md
Send bulk messages to dancers via Ballee Support chat. Use when sending apology messages, system updates, or personalized notifications to users.
npx skillsauth add javeedishaq/ai-workflow-orchestrator bulk-support-messageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Send bulk messages to dancers via the Ballee Support chat system. Messages are sent as direct messages from Ballee Support, which triggers email notifications to recipients.
Use this skill when:
Query the production database to get the list of affected users:
SELECT DISTINCT
p.id as profile_id,
p.first_name,
p.last_name,
u.email
FROM profiles p
JOIN auth.users u ON p.id = u.id
WHERE p.id IN ('uuid1', 'uuid2', ...);
For each recipient, find or create a support conversation:
-- Find existing support conversation
SELECT c.id as conversation_id
FROM conversations c
JOIN conversation_participants cp1 ON c.id = cp1.conversation_id
JOIN conversation_participants cp2 ON c.id = cp2.conversation_id
WHERE cp1.user_id = '<dancer_id>'
AND cp2.user_id = '00000000-0000-0000-0000-000000000001' -- Ballee Support ID
AND c.is_direct = true
AND c.deleted_at IS NULL;
-- Or create a new conversation if none exists
INSERT INTO conversations (is_direct, created_by)
VALUES (true, '00000000-0000-0000-0000-000000000001')
RETURNING id;
INSERT INTO conversation_participants (conversation_id, user_id, is_active)
VALUES
('<new_conv_id>', '<dancer_id>', true),
('<new_conv_id>', '00000000-0000-0000-0000-000000000001', true);
Insert messages as Ballee Support:
INSERT INTO messages (conversation_id, sender_id, content, content_type)
VALUES (
'<conversation_id>',
'00000000-0000-0000-0000-000000000001', -- Ballee Support
'Your message here',
'text'
);
The chat system's database triggers will automatically:
last_message_atunread_count for recipient-- Bulk insert apology messages for affected dancers
WITH support_user AS (
SELECT '00000000-0000-0000-0000-000000000001'::uuid AS id
),
affected_dancers AS (
-- List of affected dancer profile IDs
SELECT unnest(ARRAY[
'9a7c53d9-b132-497c-ab93-1b45f2dc07a9',
'd18108c8-f639-4d17-8c94-f334535c10c1'
-- ... more IDs
]::uuid[]) AS profile_id
),
dancer_conversations AS (
SELECT
ad.profile_id,
c.id as conversation_id
FROM affected_dancers ad
JOIN conversation_participants cp1 ON cp1.user_id = ad.profile_id
JOIN conversation_participants cp2 ON cp2.conversation_id = cp1.conversation_id
JOIN conversations c ON c.id = cp1.conversation_id
CROSS JOIN support_user su
WHERE cp2.user_id = su.id
AND c.is_direct = true
AND c.deleted_at IS NULL
)
INSERT INTO messages (conversation_id, sender_id, content, content_type)
SELECT
dc.conversation_id,
(SELECT id FROM support_user),
'Hi! Earlier today, you may have received an email with the subject "Performance tomorrow". Please disregard this email — it was sent by mistake due to a technical issue. Your actual event date has not changed and we will send you a proper reminder closer to that date. We sincerely apologize for any confusion. — The Ballee Team',
'text'
FROM dancer_conversations dc;
00000000-0000-0000-0000-000000000001automation_scheduled_notifications systemtools
# Test Patterns Testing patterns for reliable, maintainable, and fast tests. > **Template Usage:** Customize for your test framework (Vitest, Jest, Playwright, etc.) and assertion library. ## Test Structure ```typescript // user.test.ts import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { userService } from '@/services/user.service'; import { createTestUser, cleanupTestData } from '@/tests/helpers'; describe('UserService', () => { let testUserId: string; befor
tools
# State Management Patterns Client-side state management patterns for modern applications. > **Template Usage:** Customize for your state library (React Query, Zustand, Jotai, Redux, etc.). ## State Categories | Type | Description | Solution | |------|-------------|----------| | **Server State** | Data from API/database | React Query, SWR | | **Client State** | UI state, user preferences | Zustand, Jotai, useState | | **Form State** | Form inputs, validation | React Hook Form, Formik | | **U
development
# Service Patterns Service layer patterns for clean architecture with proper error handling, logging, and type safety. > **Template Usage:** Customize for your ORM (Prisma, Drizzle, TypeORM, etc.) and logging solution. ## Result Type Pattern Never throw exceptions from services. Always return a Result type. ```typescript // lib/result.ts export type Result<T, E = Error> = | { success: true; data: T } | { success: false; error: E }; export function ok<T>(data: T): Result<T, never> { r
testing
# Row-Level Security Patterns Database security patterns for multi-tenant and user-scoped data. > **Template Usage:** Customize for your database (PostgreSQL, Supabase, etc.) and auth system. ## RLS Fundamentals ### Enable RLS on Tables ```sql -- Enable RLS (required before policies take effect) ALTER TABLE users ENABLE ROW LEVEL SECURITY; ALTER TABLE posts ENABLE ROW LEVEL SECURITY; ALTER TABLE comments ENABLE ROW LEVEL SECURITY; -- Force RLS for table owners too (recommended) ALTER TABLE