Helper Libraries Reference
Documentation for utility functions in the lib/ directory.
Table of Contents
lib/supabase.ts
Comprehensive Supabase helper functions for database operations.
Exports
Supabase Client
Export:
export const supabase: SupabaseClient<Database>
Usage:
import { supabase } from '@/lib/supabase';
// Direct query (when helper doesn't exist)
const { data, error } = await supabase
.from('accounts')
.select('*')
.eq('user_id', userId);
Note: Prefer using helper functions over direct queries for type safety and consistency.
Authentication Functions
getCurrentUser()
Get current authenticated user with profile data.
Signature:
function getCurrentUser(): Promise<User | null>
Returns: User object or null if not authenticated
Example:
import { getCurrentUser } from '@/lib/supabase';
const user = await getCurrentUser();
if (!user) {
// Redirect to login
router.push('/finance/login');
return;
}
console.log(user.email, user.full_name);
Implementation:
- Gets auth user from Supabase Auth
- Fetches user profile from
userstable - Returns combined user object
signIn()
Sign in user with email and password.
Signature:
function signIn(
email: string,
password: string
): Promise<{ user: User | null; error: string | null }>
Parameters:
email- User emailpassword- User password
Returns: Object with user (on success) or error (on failure)
Example:
import { signIn } from '@/lib/supabase';
const { user, error } = await signIn('user@example.com', 'password123');
if (error) {
setError(error);
return;
}
// User signed in successfully
router.push('/finance');
signUpWithInvite()
Sign up new user with invite code.
Signature:
function signUpWithInvite(
email: string,
password: string,
fullName: string,
inviteCode: string
): Promise<{ user: User | null; error: string | null }>
Parameters:
email- User emailpassword- User passwordfullName- User's full nameinviteCode- Valid invite code
Returns: Object with user or error
Example:
import { signUpWithInvite } from '@/lib/supabase';
const { user, error } = await signUpWithInvite(
'newuser@example.com',
'securepassword',
'John Doe',
'WELCOME2024'
);
if (error) {
if (error.includes('expired')) {
setError('Your invite code has expired.');
} else if (error.includes('used')) {
setError('This invite code has been fully used.');
} else {
setError(error);
}
return;
}
// User created successfully
Validation Checks:
- ✅ Invite code exists and is active
- ✅ Not expired
- ✅ Usage limit not exceeded
- ✅ Creates auth user
- ✅ Updates invite usage count
- ✅ Links user to invite
signOut()
Sign out current user.
Signature:
function signOut(): Promise<{ error: string | null }>
Returns: Object with error if sign out failed
Example:
import { signOut } from '@/lib/supabase';
const handleSignOut = async () => {
const { error } = await signOut();
if (error) {
console.error('Sign out failed:', error);
return;
}
router.push('/finance/login');
};
isAdmin()
Check if user has admin privileges.
Signature:
function isAdmin(userId: string): Promise<boolean>
Parameters:
userId- User ID to check
Returns: true if user is admin, false otherwise
Example:
import { isAdmin } from '@/lib/supabase';
const checkAdminAccess = async () => {
const user = await getCurrentUser();
if (!user) return false;
const hasAdminAccess = await isAdmin(user.id);
if (!hasAdminAccess) {
toast.error('Admin access required');
return false;
}
return true;
};
Account Functions
getUserAccounts()
Get user's bank accounts with Plaid item info (optimized query).
Signature:
function getUserAccounts(userId: string): Promise<Account[]>
Parameters:
userId- User ID
Returns: Array of accounts (sorted: cash accounts first)
Example:
import { getUserAccounts } from '@/lib/supabase';
const accounts = await getUserAccounts(user.id);
accounts.forEach(account => {
console.log(account.account_name, account.current_balance);
// Access nested Plaid item data
if (account.plaid_items) {
console.log('Bank:', account.plaid_items.institution_name);
console.log('Status:', account.plaid_items.status);
}
});
Performance Note:
- ✅ Uses single query with nested relations (not multiple queries)
- ✅ 50% faster than separate queries for accounts and Plaid items
getTotalBalance()
Get total balance across all user accounts.
Signature:
function getTotalBalance(userId: string): Promise<number>
Parameters:
userId- User ID
Returns: Total balance in cents
Example:
import { getTotalBalance, formatCurrency } from '@/lib/supabase';
const balanceInCents = await getTotalBalance(user.id);
const formatted = formatCurrency(balanceInCents);
console.log('Total Balance:', formatted); // "$1,234.56"
Optimization:
- ✅ Only fetches
current_balancecolumn (no unnecessary data) - ✅ Performs sum on client (fast for reasonable number of accounts)
Transaction Functions
getUserTransactions()
Get user's transactions with pagination and filtering.
Signature:
function getUserTransactions(
userId: string,
options?: {
limit?: number;
offset?: number;
startDate?: string;
endDate?: string;
category?: string;
}
): Promise<Transaction[]>
Parameters:
userId- User IDoptions.limit- Max results (default: 100)options.offset- Pagination offset (default: 0)options.startDate- Filter by start date (ISO string)options.endDate- Filter by end date (ISO string)options.category- Filter by category
Returns: Array of transactions (sorted by date, newest first)
Example:
import { getUserTransactions } from '@/lib/supabase';
// Get last 30 days of transactions
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
const transactions = await getUserTransactions(user.id, {
startDate: thirtyDaysAgo.toISOString().split('T')[0],
limit: 50,
});
// Get transactions for specific category
const foodTransactions = await getUserTransactions(user.id, {
category: 'Food and Drink',
});
// Pagination
const page2 = await getUserTransactions(user.id, {
limit: 50,
offset: 50,
});
getSpendingByCategory()
Get spending totals grouped by category for a date range.
Signature:
function getSpendingByCategory(
userId: string,
startDate: string,
endDate: string
): Promise<Record<string, number>>
Parameters:
userId- User IDstartDate- Start date (ISO string, YYYY-MM-DD)endDate- End date (ISO string, YYYY-MM-DD)
Returns: Object mapping category to total spending (in cents)
Example:
import { getSpendingByCategory, formatCurrency } from '@/lib/supabase';
const spending = await getSpendingByCategory(
user.id,
'2024-12-01',
'2024-12-31'
);
Object.entries(spending).forEach(([category, amount]) => {
console.log(`${category}: ${formatCurrency(amount)}`);
});
// Output:
// Food and Drink: $456.78
// Transportation: $123.45
// Shopping: $789.01
getTotalSpending()
Get total spending for a date range.
Signature:
function getTotalSpending(
userId: string,
startDate: string,
endDate: string
): Promise<number>
Parameters:
userId- User IDstartDate- Start date (ISO string)endDate- End date (ISO string)
Returns: Total spending in cents
Example:
import { getTotalSpending, formatCurrency } from '@/lib/supabase';
const totalCents = await getTotalSpending(user.id, '2024-12-01', '2024-12-31');
const formatted = formatCurrency(totalCents);
console.log('December Spending:', formatted);
Budget Functions
getUserBudgets()
Get user's active budgets.
Signature:
function getUserBudgets(userId: string): Promise<Budget[]>
Parameters:
userId- User ID
Returns: Array of active budgets
Example:
import { getUserBudgets } from '@/lib/supabase';
const budgets = await getUserBudgets(user.id);
budgets.forEach(budget => {
const percentage = (budget.spent_amount / budget.amount) * 100;
console.log(`${budget.name}: ${percentage.toFixed(0)}% spent`);
});
createBudget()
Create a new budget.
Signature:
function createBudget(
userId: string,
name: string,
category: string,
amount: number,
period: 'weekly' | 'monthly' | 'yearly'
): Promise<{ budget: Budget | null; error: string | null }>
Parameters:
userId- User IDname- Budget namecategory- Transaction category to trackamount- Budget limit in centsperiod- Budget period
Returns: Object with budget or error
Example:
import { createBudget, dollarsToCents } from '@/lib/supabase';
const { budget, error } = await createBudget(
user.id,
'Groceries',
'Food and Drink',
dollarsToCents(500), // $500
'monthly'
);
if (error) {
toast.error(error);
return;
}
toast.success('Budget created!');
updateBudgetSpending()
Update budget spent amount.
Signature:
function updateBudgetSpending(
budgetId: string,
spentAmount: number
): Promise<{ error: string | null }>
Parameters:
budgetId- Budget IDspentAmount- New spent amount in cents
Returns: Object with error if update failed
Example:
import { updateBudgetSpending } from '@/lib/supabase';
const { error } = await updateBudgetSpending(budget.id, 45000); // $450
if (error) {
console.error('Failed to update budget:', error);
}
Plaid Item Functions
getUserPlaidItems()
Get user's Plaid items (bank connections).
Signature:
function getUserPlaidItems(userId: string): Promise<PlaidItem[]>
Parameters:
userId- User ID
Returns: Array of Plaid items
Example:
import { getUserPlaidItems } from '@/lib/supabase';
const items = await getUserPlaidItems(user.id);
items.forEach(item => {
console.log(`${item.institution_name}: ${item.status}`);
console.log(`Last synced: ${item.last_synced_at}`);
});
Utility Functions
formatCurrency()
Format cents to dollars with currency symbol.
Signature:
function formatCurrency(cents: number): string
Parameters:
cents- Amount in cents
Returns: Formatted currency string
Example:
import { formatCurrency } from '@/lib/supabase';
formatCurrency(123456); // "$1,234.56"
formatCurrency(1000); // "$10.00"
formatCurrency(-5000); // "-$50.00"
dollarsToCents()
Convert dollars to cents (safe for database storage).
Signature:
function dollarsToCents(dollars: number): number
Parameters:
dollars- Amount in dollars
Returns: Amount in cents (integer)
Example:
import { dollarsToCents } from '@/lib/supabase';
dollarsToCents(19.99); // 1999
dollarsToCents(100); // 10000
dollarsToCents(0.01); // 1
Note: Uses Math.round() to handle floating-point precision issues.
centsToDollars()
Convert cents to dollars.
Signature:
function centsToDollars(cents: number): number
Parameters:
cents- Amount in cents
Returns: Amount in dollars
Example:
import { centsToDollars } from '@/lib/supabase';
centsToDollars(1999); // 19.99
centsToDollars(10000); // 100
centsToDollars(1); // 0.01
formatDate()
Format date string to readable format.
Signature:
function formatDate(dateString: string): string
Parameters:
dateString- ISO date string
Returns: Formatted date (e.g., "Dec 4, 2024")
Example:
import { formatDate } from '@/lib/supabase';
formatDate('2024-12-04'); // "Dec 4, 2024"
formatDate('2024-01-15T10:30:00Z'); // "Jan 15, 2024"
formatRelativeTime()
Format date as relative time (e.g., "2 days ago").
Signature:
function formatRelativeTime(dateString: string): string
Parameters:
dateString- ISO date string
Returns: Relative time string
Example:
import { formatRelativeTime } from '@/lib/supabase';
formatRelativeTime('2024-12-04T10:00:00Z'); // "Today"
formatRelativeTime('2024-12-03T10:00:00Z'); // "Yesterday"
formatRelativeTime('2024-11-27T10:00:00Z'); // "1 week ago"
formatRelativeTime('2024-11-04T10:00:00Z'); // "1 month ago"
isValidUser()
Type guard to check if object is a valid User.
Signature:
function isValidUser(user: unknown): user is User
Parameters:
user- Object to check
Returns: true if valid User, false otherwise
Example:
import { isValidUser } from '@/lib/supabase';
const data = await someFunction();
if (isValidUser(data)) {
// TypeScript knows data is User
console.log(data.email, data.id);
} else {
console.error('Invalid user object');
}
lib/plaid.ts
Plaid API integration helpers.
Key Functions
createLinkToken(userId)- Generate Plaid Link tokenexchangePublicToken(publicToken)- Exchange public token for access tokengetAccounts(accessToken)- Fetch accounts from PlaidsyncTransactions(accessToken, cursor)- Sync transactionsgetItem(accessToken)- Get Plaid item details
lib/admin-auth.ts
Admin authentication and authorization helpers.
Key Functions
createAdminUser(email, password, fullName)- Create admin userauthenticateAdmin(email, password)- Step 1 of loginverifyAdminTOTP(userId, code)- Step 2 of login (2FA)createAdminSession(userId)- Create admin sessionverifyAdminSession(token)- Verify session validitydeleteAdminSession(token)- LogoutsetupAdminTOTP(userId)- Initialize 2FAverifyTOTPSetup(userId, code)- Verify 2FA setuplogAdminAction(userId, action, ...)- Audit logging
See: Authentication for detailed authentication documentation.
lib/env.ts
Type-safe environment variable validation.
Usage
Import:
import { env } from '@/lib/env';
Access variables:
// Supabase
env.supabase.url
env.supabase.anonKey
env.supabase.serviceRoleKey
// Plaid
env.plaid.clientId
env.plaid.secret
env.plaid.env // 'sandbox' | 'development' | 'production'
// Encryption
env.encryption.key
Validation:
- ✅ Validates all required variables on app startup
- ✅ Throws helpful errors for missing/invalid values
- ✅ Type-safe access (no string indexing)
Example:
import { env } from '@/lib/env';
// Type-safe access
const plaidClient = new PlaidApi(
new Configuration({
basePath: PlaidEnvironments[env.plaid.env],
baseOptions: {
headers: {
'PLAID-CLIENT-ID': env.plaid.clientId,
'PLAID-SECRET': env.plaid.secret,
},
},
})
);
lib/utils.ts
Generic utility functions (likely cn() for Tailwind classes).
cn()
Conditionally join class names.
Signature:
function cn(...inputs: ClassValue[]): string
Usage:
import { cn } from '@/lib/utils';
// Conditional classes
const buttonClass = cn(
'px-4 py-2 rounded',
isActive && 'bg-blue-500',
isDisabled && 'opacity-50'
);
// Merge conflicting classes
const mergedClass = cn(
'text-red-500',
someCondition && 'text-blue-500' // Blue wins if true
);
Next Steps:
- Review API Reference for API endpoints that use these helpers
- Check Database Schema for database structure
- Read Authentication for auth implementation details