🚀 Clausify: Technical Implementation

Showcasing Clean Architecture & Modern Development Practices

TS
Vector Similarity Search with pgvector
// lib/db/queries.ts export async function findSimilarClauses( embedding: number[], clauseType: ClauseType, limit: number = 5 ): Promise<SimilarClause[]> { const { data, error } = await supabase .rpc('match_clauses', { query_embedding: embedding, match_threshold: 0.7, match_count: limit, clause_type_filter: clauseType }) if (error) throw new Error(`Query failed: ${error.message}`) return data.map((clause) => ({ ...clause, similarity: 1 - clause.distance // Convert distance to similarity })) }
AI
Prompt Engineering for Contract Analysis
// lib/ai/prompts.ts export const CONTRACT_ANALYSIS_PROMPT = `You are a contract analysis expert helping freelancers. Analyze the following contract and identify problematic clauses. CONTRACT TEXT: \${contractText} Respond with JSON in this exact format: { "contract_type": "NDA" | "Service Agreement" | "Employment Contract", "overall_risk": "high" | "medium" | "low", "risk_score": 0-100, "flagged_clauses": [ { "clause_text": "exact text from contract", "clause_type": "termination" | "payment" | "liability" | "ip_rights", "risk_level": "high" | "medium" | "low", "explanation": "why this concerns freelancers", "suggestion": "alternative language or negotiation point" } ] } Focus on freelancer-specific risks: - Unfair payment terms - Excessive liability exposure - IP rights transfers - Restrictive non-compete clauses Return ONLY valid JSON, no additional text.`
🔒
Row-Level Security with Supabase
-- Database RLS Policy CREATE POLICY "Users can view their own contracts" ON contracts FOR SELECT USING (auth.uid() = user_id); CREATE POLICY "Users can insert their own contracts" ON contracts FOR INSERT WITH CHECK (auth.uid() = user_id); -- Vector similarity search function CREATE FUNCTION match_clauses( query_embedding vector(1536), match_threshold float, match_count int, clause_type_filter text ) RETURNS TABLE ( id uuid, clause_text text, explanation text, distance float ) AS $$ SELECT id, clause_text, explanation, embedding <=> query_embedding AS distance FROM standard_clauses WHERE clause_type = clause_type_filter AND embedding <=> query_embedding < match_threshold ORDER BY distance LIMIT match_count; $$ LANGUAGE sql;
⚙️
Environment Setup Automation
// scripts/setup-env.js const questions = [ { key: 'GROQ_API_KEY', prompt: '🔹 Groq API Key (gsk_...): ', required: true, validate: (val) => val.startsWith('gsk_') } ] function createEnvFile() { let content = '# Clausify Environment Variables\n' content += `# Generated: ${new Date().toISOString()}\n\n` Object.entries(envVars).forEach(([key, value]) => { content += `${key}=${value}\n` }) fs.writeFileSync('.env.local', content) console.log('✅ Environment configured successfully!') }
Type Safety End-to-end TypeScript with strict mode enabled for compile-time error detection
Serverless Architecture Zero-infrastructure deployment using Vercel Edge Functions
Vector Embeddings 1536-dimensional embeddings with cosine similarity matching
Security First Database-level access control with Postgres RLS policies
Developer Experience Custom npm scripts for streamlined environment management
Cost Optimization Built entirely on free-tier services with intelligent caching