6.8 KiB
04 — API Reference
This document covers all Next.js route handlers (app/api/) and key server actions (features/*/api/).
Authentication: All protected endpoints require a valid Clerk session. Unauthenticated requests receive a
401 Unauthorizedresponse. Route-level protection is enforced byproxy.ts(Clerk middleware).
Route Handlers (app/api/)
POST /api/uploadthing
File: app/api/uploadthing/route.ts
Purpose: UploadThing file upload endpoint. Handles authenticated file uploads and triggers contract creation.
Constraints:
- Max file size: 32 MB
- Accepted types:
application/pdf,image/jpeg,image/png,image/webp - Authentication: Clerk session required
Flow:
- UploadThing middleware validates the session via Clerk
- File is stored on UploadThing CDN
- On completion, returns
{ fileUrl, fileName, fileSize, mimeType }to the client
POST /api/webhooks/clerk
File: app/api/webhooks/clerk/route.ts
Purpose: Receives Clerk lifecycle events and syncs user data to PostgreSQL.
Verification: Request signature verified via Svix + CLERK_WEBHOOK_SECRET
Handled Events:
| Event | Action |
|---|---|
user.created |
Creates a new User record in PostgreSQL |
user.updated |
Updates email, firstName, lastName, imageUrl |
user.deleted |
Deletes User record (cascades to contracts, notifications) |
Response: 200 OK on success, 400 Bad Request if signature invalid.
GET /api/contracts/[id]/download
File: app/api/contracts/[id]/download/route.ts
Purpose: Proxies contract file download through the server (adds auth check before serving).
Authentication: Clerk session + ownership validation
Response: File stream with appropriate Content-Type and Content-Disposition headers.
Server Actions (features/contracts/api/contract.action.ts)
All server actions are decorated with "use server" and perform double authentication (Clerk session + DB ownership check).
saveContract(data)
Saves a new contract after UploadThing upload, then automatically triggers AI analysis.
Parameters:
{
fileName: string
fileUrl: string
fileSize: number
mimeType: string
}
Returns:
{ success: true, contract: Contract } |
{ success: true, contract: Contract, analysisSuccess: false, analysisError: string } |
{ success: false, error: string }
Side effects:
- Creates
Contractrecord (status:UPLOADED) - Creates in-app notification (upload success)
- Triggers
analyzeContractAction()automatically - Revalidates
/contactsand/dashboard
getContracts(filters?)
Returns all contracts for the authenticated user with optional filtering.
Parameters:
{
status?: ContractStatus
type?: ContractType
search?: string // searches title, provider, policyNumber, fileName
}
Returns:
{
success: true,
contracts: SerializedContract[]
}
Serialization: Decimal → number, Date → ISO string
getContract(id)
Returns a single contract by ID.
Parameters: id: string (contract ID)
Returns: { success: true, contract: Contract } | { success: false, error: string }
deleteContract(id)
Permanently deletes a contract (ownership validated, cascades to RAG chunks and notifications).
Returns: { success: true } | { success: false, error: string }
Side effects:
- Deletes file from UploadThing CDN
- Cascades delete to
ContractRagChunk,Notification,BlockchainTransaction - Creates in-app notification (delete success)
- Revalidates
/contactsand/dashboard
deleteAllContractsAction()
Deletes all contracts for the authenticated user.
Returns: { success: true, deletedCount: number } | { success: false, error: string }
analyzeContractAction(id)
Triggers the full AI analysis pipeline for a contract.
Parameters: id: string (contract ID)
Returns:
{ success: true, contract: NormalizedAnalysis } |
{
success: false,
error: string,
errorCode: "INVALID_CONTRACT" | "ANALYSIS_ERROR"
}
Pipeline:
- Set status →
PROCESSING - Run AI extraction (Gemini → Mistral fallback)
- Validate AI output
- Save extracted fields to DB
- Build RAG chunks (embeddings)
- Register document hash on blockchain (non-blocking)
- Send analysis complete email (non-blocking)
- Create in-app notification
- Set status →
COMPLETED
Error codes:
INVALID_CONTRACT— uploaded file is not a recognized contract documentANALYSIS_ERROR— analysis pipeline failed (AI error, parse error, etc.)
askContractQuestionAction(id, question)
Answers a natural-language question about a specific contract using RAG + AI.
Parameters:
id: string // contract ID
question: string // user's question
Returns:
{ success: true, answer: string } |
{ success: false, error: string }
Pipeline:
- Load contract from DB
- RAGService retrieves top-6 most relevant chunks
- AIService sends question + contract context + RAG chunks to Gemini
- Sanitized answer returned to UI
getContractStats()
Returns analytics data for the dashboard.
Returns:
{
success: true,
stats: {
total: number
byStatus: Record<ContractStatus, number>
byType: Record<ContractType, number>
byMonth: Array<{ month: string, count: number }>
expiringSoon: number
averagePremium: number | null
blockchainCoverage: number // percentage
}
}
Notification Server Actions
File: features/notifications/api/ (or lib/services/notification.service.ts)
getNotificationsAction()
Returns all unread (and recent read) notifications for the user.
markNotificationReadAction(id)
Marks a single notification as read.
markAllNotificationsReadAction()
Marks all notifications as read.
deleteNotificationAction(id)
Deletes a single notification.
Blockchain Server Actions
File: features/blockchain/api/
getBlockchainStatsAction()
Returns network stats: total verified docs, block number, network name, connection status.
verifyDocumentAction(documentHash)
Verifies whether a given SHA-256 hash is registered on-chain.
Returns:
{
exists: boolean
timestamp: number // Unix timestamp
depositor: string // Ethereum address
formattedDate: string // Human-readable date
}
Health Check Endpoint
The Dockerfile HEALTHCHECK calls:
GET /api/health
This route should return 200 OK with { status: "ok" }.
If this route does not exist, create it at app/api/health/route.ts:
export async function GET() {
return Response.json({ status: "ok" });
}