API Reference
Complete API documentation for the Lakra system. All API calls are made through the Supabase JavaScript client.
Overview
Lakra uses Supabase client libraries for all backend operations. The API is organized into modules:
Authentication API - User authentication
Sentences API - Sentence management
Annotations API - Annotation operations
Evaluations API - Evaluation operations
Quality Assessments API - AI quality assessments
Admin API - Administrative functions
Authentication
Located in src/services/supabase-api.ts
authAPI
login(credentials)
Sign in a user with email or username.
Parameters:
{
identifier: string; // email or username
password: string;
isUsername?: boolean; // true if identifier is username
}
Returns:
{
user: User;
session: Session;
error: null | Error;
}
Example:
const { user, error } = await authAPI.login({
identifier: 'user@example.com',
password: 'password123'
});
register(userData)
Register a new user.
Parameters:
{
email: string;
password: string;
username?: string;
fullName?: string;
role: 'annotator' | 'evaluator';
}
logout()
Sign out the current user.
getCurrentUser()
Get the currently authenticated user with profile data.
Returns:
{
id: string;
email: string;
username?: string;
role: string;
// ... other user fields
}
updatePassword(newPassword)
Update user password.
Sentences
sentencesAPI
getSentences(filters)
Fetch sentences with optional filtering.
Parameters:
{
languagePair?: {source: string, target: string};
domain?: string;
activeOnly?: boolean;
limit?: number;
offset?: number;
}
Returns: Array of sentence objects
Example:
const sentences = await sentencesAPI.getSentences({
languagePair: {source: 'en', target: 'fil'},
activeOnly: true,
limit: 20
});
getSentenceById(id)
Fetch a specific sentence by ID.
getNextSentence(userId)
Get the next unannotated sentence for a user.
Returns: Sentence object or null
createSentence(sentenceData)
Create a new sentence (admin only).
Parameters:
{
sourceText: string;
machineTranslation: string;
sourceLanguage: string;
targetLanguage: string;
domain?: string;
context?: string;
backTranslation?: string;
isActive?: boolean;
}
updateSentence(id, updates)
Update an existing sentence (admin only).
deleteSentence(id)
Delete a sentence (admin only).
importSentencesFromCSV(csvData)
Bulk import sentences from CSV data (admin only).
Parameters:
{
csvData: Array<{
source_text: string;
machine_translation: string;
source_language: string;
target_language: string;
domain?: string;
}>;
}
Returns:
{
successful: number;
failed: number;
errors: Array<{row: number, error: string}>;
}
Annotations
annotationsAPI
createAnnotation(annotationData)
Create a new annotation.
Parameters:
{
sentenceId: string;
fluencyScore: number; // 1-5
adequacyScore: number; // 1-5
overallQualityScore: number; // 1-5
comments?: string;
suggestedCorrection?: string;
voiceRecordingUrl?: string;
timeSpentSeconds?: number;
textHighlights?: Array<{
startPosition: number;
endPosition: number;
highlightedText: string;
errorType: 'MI_ST' | 'MI_SE' | 'MA_ST' | 'MA_SE';
errorDescription?: string;
suggestedFix?: string;
}>;
}
Returns: Created annotation object
Example:
const annotation = await annotationsAPI.createAnnotation({
sentenceId: 'uuid-here',
fluencyScore: 4,
adequacyScore: 4,
overallQualityScore: 4,
comments: 'Good translation overall',
textHighlights: [
{
startPosition: 0,
endPosition: 5,
highlightedText: 'Hello',
errorType: 'MI_ST',
errorDescription: 'Missing punctuation'
}
]
});
getMyAnnotations(userId, options)
Get all annotations by a specific user.
Parameters:
{
limit?: number;
offset?: number;
status?: 'draft' | 'completed' | 'under_review';
}
getAnnotationById(id)
Fetch a specific annotation with all related data.
Returns:
{
id: string;
sentence: Sentence;
fluencyScore: number;
// ... all annotation fields
textHighlights: TextHighlight[];
evaluations: Evaluation[];
}
updateAnnotation(id, updates)
Update an existing annotation (before evaluation).
deleteAnnotation(id)
Delete an annotation (before evaluation).
getAnnotationsBysentence(sentenceId)
Get all annotations for a specific sentence.
Evaluations
evaluationsAPI
createEvaluation(evaluationData)
Create a new evaluation of an annotation.
Parameters:
{
annotationId: string;
accuracyScore: number; // 1-5
completenessScore: number; // 1-5
overallQualityScore: number; // 1-5
feedback: string;
strengths?: string;
improvementsNeeded?: string;
missedErrors?: string[];
incorrectClassifications?: string[];
timeSpentSeconds?: number;
}
getMyEvaluations(evaluatorId, options)
Get all evaluations by a specific evaluator.
getPendingEvaluations(evaluatorId, options)
Get annotations awaiting evaluation.
Returns: Array of annotations without evaluations from this evaluator
getEvaluationById(id)
Fetch a specific evaluation.
getEvaluationsForAnnotation(annotationId)
Get all evaluations for a specific annotation.
Quality Assessments
qualityAssessmentsAPI
createQualityAssessment(assessmentData)
Create an AI quality assessment for a sentence.
Parameters:
{
sentenceId: string;
evaluatedBy?: string;
// AI scores populated by backend AI service
}
getQualityAssessment(sentenceId)
Get quality assessment for a sentence.
validateQualityAssessment(id, validation)
Validate/modify an AI quality assessment.
Parameters:
{
humanFluencyScore: number;
humanAdequacyScore: number;
humanOverallScore: number;
humanFeedback: string;
validationStatus: 'confirmed' | 'rejected' | 'modified';
}
Admin Functions
adminAPI
getStats()
Get system-wide statistics.
Returns:
{
totalUsers: number;
usersByRole: {admin: number, annotator: number, evaluator: number};
totalSentences: number;
totalAnnotations: number;
totalEvaluations: number;
averageQualityScores: {
fluency: number;
adequacy: number;
overall: number;
};
recentActivity: Array<Activity>;
}
getAllUsers(options)
Get all users (admin only).
Parameters:
{
role?: string;
isActive?: boolean;
limit?: number;
offset?: number;
}
createUser(userData)
Create a new user (admin only).
Parameters:
{
email: string;
username?: string;
password: string;
role: 'admin' | 'annotator' | 'evaluator';
fullName?: string;
}
updateUser(userId, updates)
Update user profile (admin only).
deleteUser(userId)
Delete a user (admin only).
getAnnotationMetrics(options)
Get detailed annotation metrics.
Parameters:
{
startDate?: Date;
endDate?: Date;
annotatorId?: string;
languagePair?: {source: string, target: string};
}
Returns:
{
totalAnnotations: number;
averageTimePerAnnotation: number;
errorDistribution: {
MI_ST: number;
MI_SE: number;
MA_ST: number;
MA_SE: number;
};
qualityTrends: Array<{date: string, avgScore: number}>;
}
Storage (Voice Recordings)
storageAPI
uploadVoiceRecording(file, annotationId)
Upload voice recording to Supabase Storage.
Parameters:
{
file: File; // Audio file (WebM, MP3, etc.)
annotationId: string;
}
Returns:
{
url: string; // Public or signed URL
path: string; // Storage path
}
Example:
const { url } = await storageAPI.uploadVoiceRecording(
audioBlob,
annotationId
);
getVoiceRecordingUrl(path)
Get a signed URL for a voice recording.
Returns: Temporary signed URL (expires in 1 hour)
deleteVoiceRecording(path)
Delete a voice recording from storage.
Error Handling
All API functions return errors in a consistent format:
{
data: null,
error: {
message: string;
code?: string;
details?: any;
}
}
Common Error Codes:
PGRST116- No rows found23505- Unique violation42501- Insufficient privilege (RLS policy)08006- Connection failure
Example Error Handling:
const { data, error } = await annotationsAPI.createAnnotation(annotationData);
if (error) {
if (error.code === '23505') {
console.error('Duplicate annotation');
} else {
console.error('Error:', error.message);
}
return;
}
// Use data
console.log('Annotation created:', data);
Real-Time Subscriptions
Subscribe to database changes (optional feature):
// Subscribe to new annotations
const subscription = supabase
.channel('annotations')
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'annotations'
},
(payload) => {
console.log('New annotation:', payload.new);
}
)
.subscribe();
// Unsubscribe
subscription.unsubscribe();
Rate Limiting
Supabase applies rate limiting:
Anonymous requests: 100/hour
Authenticated requests: 500/hour
For production, configure appropriate limits in Supabase dashboard.
Best Practices
Always handle errors - Check for error objects on every API call
Use TypeScript - Type safety prevents many runtime errors
Implement loading states - Show loading indicators during API calls
Optimize queries - Use selective field fetching, pagination
Cache when appropriate - Store frequently accessed data client-side
Debounce user input - Prevent excessive API calls during typing
Handle offline scenarios - Graceful degradation when network fails
See Also
Database Schema - Database structure
Architecture - System architecture
Development - Development workflow