Documentation Index Fetch the complete documentation index at: https://mintlify.com/seyarhasir/AiVault/llms.txt
Use this file to discover all available pages before exploring further.
Features Overview
AiVault is packed with powerful features designed to make discovering and managing AI tools effortless. Built on a modern tech stack with Convex and Clerk, every feature is optimized for performance and security.
Real-time Search & Filtering
Advanced Discovery System AiVault’s search and filtering system provides instant results without page reloads, powered by Convex’s reactive backend.
Multi-Layer Filtering
Filter tools by multiple criteria simultaneously:
export const getTools = query ({
args: {
category: v . optional ( v . string ()),
pricing: v . optional ( v . string ()),
search: v . optional ( v . string ()),
sort: v . optional ( v . string ()), // "newest", "upvotes"
},
handler : async ( ctx : QueryCtx , args ) => {
let toolsQuery ;
if ( args . category && args . category !== "All" ) {
toolsQuery = ctx . db
. query ( "tools" )
. withIndex ( "by_category" , ( q ) => q . eq ( "category" , args . category ! ));
} else {
toolsQuery = ctx . db
. query ( "tools" )
. withIndex ( "by_approved" , ( q ) => q . eq ( "approved" , true ));
}
let tools = await toolsQuery . collect ();
// Filter by pricing
if ( args . pricing && args . pricing !== "All" ) {
tools = tools . filter (( t ) => t . pricing === args . pricing );
}
// Filter by search query
if ( args . search ) {
const searchLower = args . search . toLowerCase ();
tools = tools . filter (
( t ) =>
t . name . toLowerCase (). includes ( searchLower ) ||
t . description . toLowerCase (). includes ( searchLower ) ||
t . tags . some (( tag ) => tag . toLowerCase (). includes ( searchLower ))
);
}
// Sort results
if ( args . sort === "upvotes" ) {
tools . sort (( a , b ) => b . upvotes - a . upvotes );
} else {
tools . sort (( a , b ) => b . createdAt - a . createdAt );
}
return tools ;
},
});
Filter Options:
Category: Writing, Image, Coding, Video, Audio, and more
Pricing: Free, Freemium, Paid
Search: Name, description, and tags
Sort: Newest first or by upvotes
All queries use Convex indices for optimal performance. Category and approval status are indexed for instant lookups.
Quality-Controlled Directory Every tool submission goes through a review process to maintain directory quality and prevent spam.
Submission Process
Users can submit tools with comprehensive information:
Basic Info: Name, description, category, website URL
Metadata: Tags, pricing type, pricing details, logo
Rich Content: Long description, features, use cases, pros & cons
Platform Support: Web, iOS, Android, Desktop, API, Chrome Extension
Social Links: Twitter, GitHub, Discord
Admin Moderation
Admins have full control over submissions:
// Approve a tool submission
export const approveTool = mutation ({
args: {
toolId: v . id ( "tools" ),
sendEmail: v . optional ( v . boolean ()),
},
handler : async ( ctx : MutationCtx , args ) => {
await checkAdmin ( ctx );
await ctx . db . patch ( args . toolId , { approved: true });
return { success: true };
},
});
// Reject a tool submission
export const rejectTool = mutation ({
args: {
toolId: v . id ( "tools" ),
reason: v . optional ( v . string ()),
sendEmail: v . optional ( v . boolean ()),
},
handler : async ( ctx : MutationCtx , args ) => {
await checkAdmin ( ctx );
const tool = await ctx . db . get ( args . toolId );
await ctx . db . delete ( args . toolId );
return { success: true , tool , reason: args . reason };
},
});
Admin access is strictly enforced via RBAC (Role-Based Access Control). Admin user IDs are whitelisted in environment variables.
Bookmarks System
Save Your Favorites Authenticated users can bookmark tools for quick access later.
The bookmark system uses a dedicated table with composite indices:
bookmarks : defineTable ({
userId: v . string (),
toolId: v . id ( "tools" ),
})
. index ( "by_userId" , [ "userId" ])
. index ( "by_toolId" , [ "toolId" ])
. index ( "by_userId_and_toolId" , [ "userId" , "toolId" ]),
Features:
Add/remove bookmarks in real-time
View all your bookmarked tools in one place
Bookmarks sync across devices automatically
Fast lookups with Convex indices
Admin Dashboard
Comprehensive Control Panel Admins have access to a powerful dashboard for managing tools, reviewing submissions, and monitoring analytics.
Dashboard Features
1. Real-time Statistics
export const getAdminStats = query ({
handler : async ( ctx : QueryCtx ) => {
await checkAdmin ( ctx );
const approvedTools = await ctx . db
. query ( "tools" )
. withIndex ( "by_approved" , ( q ) => q . eq ( "approved" , true ))
. collect ();
const pendingTools = await ctx . db
. query ( "tools" )
. withIndex ( "by_approved" , ( q ) => q . eq ( "approved" , false ))
. collect ();
const categories = new Set ( approvedTools . map (( t ) => t . category ));
const totalUpvotes = approvedTools . reduce (( sum , t ) => sum + t . upvotes , 0 );
const featuredCount = approvedTools . filter (( t ) => t . featured ). length ;
return {
totalTools: approvedTools . length + pendingTools . length ,
approvedCount: approvedTools . length ,
pendingCount: pendingTools . length ,
totalCategories: categories . size ,
totalFeatured: featuredCount ,
totalUpvotes ,
};
},
});
2. Pending Submissions Queue
View all pending submissions with:
Tool details and metadata
Submitter information
Submission timestamp
Quick approve/reject actions
3. Automated Notifications
Integrated with Resend for email notifications:
Approval confirmations sent to submitters
Rejection notices with feedback
Custom transactional templates
The admin dashboard uses real-time queries, so stats update automatically as users submit tools or interact with the platform.
Security Features
Security-First Architecture AiVault is designed with enterprise-grade security from the ground up.
Security Measures:
Server-Side Validation: All data mutations derive identity from authorized Clerk tokens via ctx.auth
async function getIdentity ( ctx : QueryCtx | MutationCtx ) {
const identity = await ctx . auth . getUserIdentity ();
if ( ! identity ) throw new Error ( "Unauthenticated" );
return identity ;
}
async function checkAdmin ( ctx : QueryCtx | MutationCtx ) {
const identity = await ctx . auth . getUserIdentity ();
if ( ! identity ) throw new Error ( "Unauthenticated" );
if ( ! getAdminIds (). includes ( identity . subject )) {
throw new Error ( "Unauthorized: Admin access required" );
}
return identity ;
}
RBAC (Role-Based Access Control): Admin access whitelist stored in secure environment variables
Input Sanitization: All user-submitted content validated against Zod schemas
CSRF & XSS Protection: Leverages Next.js and React’s built-in protections with strict Content Security Policies
Mobile Experience
Mobile-First Design AiVault features a completely overhauled mobile experience with responsive design.
Mobile Features:
Drawer-based filtering system for easy access on small screens
Responsive navigation menu
Touch-optimized interactions
Smooth animations with Framer Motion
Optimized performance for mobile devices
Analytics & Monitoring
Track Engagement Real-time analytics for tracking tool performance and user engagement.
Public Statistics:
export const getStats = query ({
handler : async ( ctx : QueryCtx ) => {
const approvedTools = await ctx . db
. query ( "tools" )
. withIndex ( "by_approved" , ( q ) => q . eq ( "approved" , true ))
. collect ();
const categories = new Set ( approvedTools . map (( t ) => t . category ));
const totalUpvotes = approvedTools . reduce (( sum , t ) => sum + t . upvotes , 0 );
const featuredCount = approvedTools . filter (( t ) => t . featured ). length ;
return {
totalTools: approvedTools . length ,
totalCategories: categories . size ,
totalFeatured: featuredCount ,
totalUpvotes ,
};
},
});
Tracked Metrics:
Total approved tools
Number of categories
Featured tools count
Total upvotes across all tools
User engagement rates
Reviews & Ratings
Community Feedback Users can leave reviews and ratings on tools they’ve used.
The review system includes:
reviews : defineTable ({
userId: v . string (),
toolId: v . id ( "tools" ),
rating: v . number (),
comment: v . string (),
createdAt: v . number (),
})
. index ( "by_toolId" , [ "toolId" ])
. index ( "by_userId" , [ "userId" ]),
Features:
Star ratings (1-5)
Written reviews
User attribution
Timestamp tracking
Fast queries with Convex indices
More features are coming soon! Check the roadmap in the introduction for upcoming enhancements like AI-powered recommendations, comparison tools, and API access.