backend-agent
Handles backend/API/database work for Unite-Hub. Implements Next.js API routes, Supabase database operations, RLS policies, authentication, and third-party integrations (Gmail, Stripe).
DeepseekModel
Curated skill
Quality Excellent · 78
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=aiskillstore-marketplace-skills-cleanexpo-backend-agent-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name backend-agent description Handles backend/API/database work for Unite-Hub. Implements Next.js API routes, Supabase database operations, RLS policies, authentication, and third-party integrations (Gmail, Stripe). Backend Agent Skill Overview The Backend Agent is responsible for all server-side work in Unite-Hub: Next.js API route development (serverless functions) Supabase database operations (queries, mutations, RLS) Authentication and authorization (NextAuth.js, Supabase Auth) Third-party integrations (Gmail API, Stripe, Claude AI) Database schema management (migrations, indexes) API security and performance (rate limiting, caching) How to Use This Agent Trigger User says: "Create new API endpoint", "Fix database query", "Update RLS policies", "Implement Gmail integration" What the Agent Does 1. Understand the Request Questions to Ask : What's the API endpoint purpose? What database tables are involved? What's the expected input/output format? What authentication is required? What's the priority (P0/P1/P2)? 2. Analyze Current Implementation Step A: Locate Files # Find API routes find src/app/api -name "route.ts" | grep -i "contacts" # Find database utilities find src/lib -name "*.ts" | grep -i "db" Step B: Read Current Code // Use text_editor tool text_editor. view ( "src/app/api/contacts/route.ts" ) text_editor. view ( "src/lib/db.ts" ) Step C: Identify Dependencies What database tables are queried? What authentication is required? What external APIs are called? What error handling exists? 3. Implement Changes Step A: Create API Route All API routes in Unite-Hub follow this pattern: // src/app/api/example/route.ts import { NextRequest , NextResponse } from "next/server" ; import { createClient } from "@/lib/supabase" ; export async function POST ( request : NextRequest ) { try { // 1. Parse request body const body = await request. json (); const { workspaceId, action, ...params } = body; // 2. Validate input if (!workspaceId) { return NextResponse . json ( { error : "workspaceId is required" }, { status : 400 } ); } // 3. Get Supabase client const supabase = createClient (); // 4. Check authentication (if needed) const { data : { user }, error : authError } = await supabase. auth . getUser (); if (authError || !user) { return NextResponse . json ( { error : "Unauthorized" }, { status : 401 } ); } // 5. Perform database operation const { data, error } = await supabase . from ( "contacts" ) . select ( "*" ) . eq ( "workspace_id" , workspaceId) // CRITICAL: Workspace filter . eq ( "organization_id" , user. organization_id ); // CRITICAL: Org filter if (error) { console . error ( "Database error:" , error); return NextResponse . json ( { error : "Database query failed" }, { status : 500 } ); } // 6. Return success response return NextResponse . json ({ success : true , data, count : data. length }); } catch (error) { console . error ( "API error:" , error); return NextResponse . json ( { error : "Internal server error" }, { status : 500 } ); } } // Support OPTIONS for CORS export async function OPTIONS ( request : NextRequest ) { return NextResponse . json ({}, { status : 200 }); } Step B: Database Operations All database operations MUST use workspace filtering: // ❌ BAD - No workspace filter const { data } = await supabase . from ( "contacts" ) . select ( "*" ); // ✅ GOOD - Workspace filtered const { data } = await supabase . from ( "contacts" ) . select ( "*" ) . eq ( "workspace_id" , workspaceId) . eq ( "organization_id" , orgId); Required filters for data isolation : .eq("workspace_id", workspaceId) - Workspace scope .eq("organization_id", orgId) - Organization scope (top-level) Step C: Update src/lib/db.ts Wrapper The db.ts wrapper provides consistent database access: // src/lib/db.ts import { createClient } from "@/lib/supabase" ; export const db = { contacts : { async listByWorkspace ( workspaceId : string ) { const supabase = createClient (); const { data, error } = await supabase . from ( "contacts" ) . select ( "*" ) . eq ( "workspace_id" , workspaceId) . order ( "created_at" , { ascending : false }); if (error) throw error; return data || []; }, async getById ( contactId : string , workspaceId : string ) { const supabase = createClient (); const { data, error } = await supabase . from ( "contacts" ) . select ( "*" ) . eq ( "id" , contactId) . eq ( "workspace_id" , workspaceId) . single (); if (error) throw error; return data; }, async create ( contact : ContactInput , workspaceId : string ) { const supabase = createClient (); const { data, error } = await supabase . from ( "contacts" ) . insert ([{ ...contact, workspace_id : workspaceId }]) . select () . single (); if (error) throw error; return data; }, async update ( contactId : string , updates : Partial < ContactInput >, workspaceId : string ) { const supabase = createClient (); const { data, error } = await supabase . from ( "contacts" ) . update (updates) . eq ( "id" , contactId) . eq ( "workspace_id" , workspaceId) . select () . single (); if (error) throw error; return data; } }, // Similar patterns for campaigns, emails, etc. }; CRITICAL FIX for V1 : Add missing import in src/lib/db.ts:58 // Line 1 - Add import import { createClient, getSupabaseServer } from "./supabase" ; // Line 58 - Fix usage const supabaseServer = getSupabaseServer (); const { data : workspace, error } = await supabaseServer . from ( "workspaces" ) . select ( "*" ) . eq ( "id" , workspaceId) . single (); 4. Implement Authentication Pattern 1: Client-Side Auth (Browser) import { createClient } from "@/lib/supabase" ; export async function GET ( request : NextRequest ) { const supabase = createClient (); const { data : { user }, error } = await supabase. auth . getUser (); if (error || !user) { return NextResponse . json ({ error : "Unauthorized" }, { status : 401 }); } // User is authenticated, proceed } Pattern 2: Server-Side Auth (API Routes) import { getSupabaseServer } from "@/lib/supabase" ; export async function POST ( request : NextRequest ) { const supabase = getSupabaseServer (); const { data : { session }, error } = await supabase. auth . getSession (); if (error || !session) { return NextResponse . json ({ error : "Unauthorized" }, { status : 401 }); } // Session is valid, proceed } CRITICAL for V1 : Re-enable authentication on all API routes Many routes currently have: // TODO: Re-enable authentication in production // const { auth } = await import("@/lib/auth"); // const session = await auth(); Action Required : Remove TODO comments and re-enable auth checks. 5. Row Level Security (RLS) Policies All Supabase tables MUST have RLS policies: -- Enable RLS on table ALTER TABLE contacts ENABLE ROW LEVEL SECURITY; -- Policy: Users can only see contacts in their workspace CREATE POLICY "Users can view workspace contacts" ON contacts FOR SELECT USING ( workspace_id IN ( SELECT w.id FROM workspaces w JOIN user_organizations uo ON uo.organization_id = w.organization_id WHERE uo.user_id = auth.uid() ) ); -- Policy: Users can insert contacts in their workspace CREATE POLICY "Users can create workspace contacts" ON contacts FOR INSERT WITH CHECK ( workspace_id IN ( SELECT w.id FROM workspaces w JOIN user_organizations uo ON uo.organization_id = w.organization_id WHERE uo.user_id = auth.uid() ) ); -- Policy: Users can update contacts in their workspace CREATE POLICY "Users can update workspace contacts" ON contacts FOR UPDATE USING ( workspace_id IN ( SELECT w.id FROM workspaces w JOIN user_organizations uo ON uo.organization_id = w.organization_id WHERE uo.user_id = auth.uid() ) ); CRITICAL for V1 : Verify RLS policies exist for: contacts campaigns drip_campaigns emails generated_content campaign_enrollments 6. Third-Party Integrations Gmail API Integration // src/lib/integrations/gmail.ts import { google } from "googleapis" ; export async function getGmailClient ( accessToken : string ) { const oauth2Client = new google. auth . OAuth2 ( process. env . GOOGLE_CLIENT_ID , process. env . GOOGLE_CLIENT_SECRET , process. env . GOOGLE_CALLBACK_URL ); oauth2Client. setCredentials ({ access_token : accessToken }); return google. gmail ({ version : "v1" , auth : oauth2Client }); } export async function fetchEmails ( gmail : any , maxResults = 50 ) { const res = await gmail. users . messages . list ({ userId : "me" , maxResults, q : "is:unread" , // Only unread emails }); const messages = res. data . messages || []; const emails = []; for ( const message of messages) { const email = await gmail. users . messages . get ({ userId : "me" , id : message. id , }); emails. push (email. data ); } return emails; } Claude AI Integration // src/lib/integrations/claude.ts import Anthropic from "@anthropic-ai/sdk" ; const client = new Anthropic ({ apiKey : process. env . ANTHROPIC_API_KEY , }); export async function generateContent ( { contactName, contactCompany, interactionHistory, contentType, }: { contactName: string ; contactCompany: string ; interactionHistory: string ; contentType: "followup" | "proposal" | "case_study" ; } ) { const message = await client. messages . create ({ model : "claude-opus-4-5-20251101" , max_tokens : 2000 , thinking : { type : "enabled" , budget_tokens : 7500 , }, messages : [ { role : "user" , content : `Generate a personalized ${contentType} email for ${contactName} at ${contactCompany} . Interaction history: ${interactionHistory} Generate a professional, personalized email that references their previous interactions.` , }, ], }); return message. content [ 0 ]. type === "text" ? message. content [ 0 ]. text : null ; } 7. Error Handling and Logging Structured Error Responses : // Error response format return NextResponse . json ( { error : "Error message for user" , code : "ERROR_CODE" , details : isDev ? error. message : undefined , // Only in development }, { status : 500 } ); Audit Logging : // Log all important actions await supabase. from ( "auditLogs" ). insert ({ organization_id : orgId, user_id : userId, action : "contact_created" , resource_type : "contact" , resource_id : contact. id , context : { contact_email : contact. email , source : "api" , }, ip_address : request. headers . get ( "x-forwarded-for" ), user_agent : request. headers . get ( "user-agent" ), created_at : new Date (). toISOString (), });
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.