Project Structure
Understand the organization and architecture of the MegaVault codebase for effective development and contribution.
Table of Contents
Project Structure Overview
MegaVault follows Next.js 14 App Router conventions with a clear separation between frontend, backend, and shared utilities. The project structure is designed for scalability and maintainability.
Next.js App Router
Modern React framework structure
- ✅ App directory for routing
- ✅ API routes co-located
- ✅ Server components by default
- ✅ File-based routing system
TypeScript First
Type-safe development
- ✅ Strict TypeScript config
- ✅ Type definitions included
- ✅ Auto-generated types
- ✅ Import path aliases
Modular Architecture
Clean separation of concerns
- ✅ Feature-based organization
- ✅ Reusable components
- ✅ Shared utilities
- ✅ Clear dependencies
Architecture Philosophy
- Feature-first organization over technical layers
- Explicit imports and dependencies
- Separation of client and server code
- Consistent naming and file organization
Root Directory
The root directory contains configuration files, documentation, and the main source code directories.
megavault/
├── .env.example # Environment variables template
├── .env.local # Local environment variables (gitignored)
├── .eslintrc.json # ESLint configuration
├── .gitignore # Git ignore patterns
├── .prettierrc # Prettier code formatting
├── README.md # Project documentation
├── docker-compose.yml # Docker composition for development
├── dockerfile # Docker container definition
├── next.config.js # Next.js configuration
├── package.json # Node.js dependencies and scripts
├── tailwind.config.js # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
├── middleware.ts # Next.js middleware
├── public/ # Static assets
├── src/ # Source code
├── megavault_mobile/ # Flutter mobile app
├── docs/ # Additional documentation
└── scripts/ # Build and deployment scriptsKey Configuration Files
Core Configuration
- next.config.js: Next.js build and runtime configuration
- tailwind.config.js: Tailwind CSS customization
- tsconfig.json: TypeScript compiler settings
- middleware.ts: Request/response middleware
Development Tools
- .eslintrc.json: Code linting rules
- .prettierrc: Code formatting configuration
- docker-compose.yml: Development services
- package.json: Dependencies and scripts
Source Code Structure
The src/ directory contains all application source code, organized by functionality and Next.js conventions.
src/
├── app/ # Next.js App Router
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout component
│ ├── page.tsx # Home page
│ ├── loading.tsx # Global loading UI
│ ├── error.tsx # Global error UI
│ ├── not-found.tsx # 404 page
│ ├── api/ # API route handlers
│ │ ├── auth/ # Authentication endpoints
│ │ ├── files/ # File management APIs
│ │ ├── mobile/ # Mobile-specific APIs
│ │ └── users/ # User management APIs
│ ├── auth/ # Authentication pages
│ ├── dashboard/ # Dashboard application
│ ├── docs/ # Documentation pages
│ └── components/ # Page-specific components
├── components/ # Reusable UI components
│ ├── ui/ # Basic UI components
│ ├── forms/ # Form components
│ ├── layout/ # Layout components
│ └── features/ # Feature-specific components
├── lib/ # Utility libraries
│ ├── auth.ts # Authentication utilities
│ ├── storage.ts # Storage service
│ ├── redis.ts # Redis client
│ ├── config.ts # Configuration management
│ ├── utils.ts # General utilities
│ └── validations.ts # Input validation schemas
├── types/ # TypeScript type definitions
│ ├── auth.ts # Authentication types
│ ├── files.ts # File-related types
│ ├── api.ts # API response types
│ └── global.ts # Global type definitions
└── hooks/ # Custom React hooks
├── useAuth.ts # Authentication hook
├── useFiles.ts # File management hook
└── useLocalStorage.ts # Local storage hookImport Path Aliases
MegaVault uses TypeScript path aliases for cleaner imports:
// Instead of relative imports
import { Button } from '../../../components/ui/Button'
import { auth } from '../../../lib/auth'
// Use absolute imports with aliases
import { Button } from '@/components/ui/Button'
import { auth } from '@/lib/auth'
// Available aliases:
// @/ → src/
// @/components → src/components
// @/lib → src/lib
// @/types → src/typesApp Directory (Next.js 14)
The app directory follows Next.js 14 App Router conventions with server components, nested layouts, and co-located API routes.
app/
├── layout.tsx # Root layout (applied to all pages)
├── page.tsx # Home page (/)
├── loading.tsx # Loading UI for all pages
├── error.tsx # Error UI for all pages
├── not-found.tsx # 404 page
├── globals.css # Global CSS styles
├── auth/ # Authentication routes
│ ├── layout.tsx # Auth layout
│ ├── signin/
│ │ └── page.tsx # /auth/signin
│ ├── signup/
│ │ └── page.tsx # /auth/signup
│ └── verify/
│ └── page.tsx # /auth/verify
├── dashboard/ # Main application
│ ├── layout.tsx # Dashboard layout
│ ├── page.tsx # /dashboard
│ ├── files/
│ │ ├── page.tsx # /dashboard/files
│ │ └── [path]/
│ │ └── page.tsx # /dashboard/files/[path]
│ └── settings/
│ └── page.tsx # /dashboard/settings
├── docs/ # Documentation
│ ├── layout.tsx # Docs layout
│ ├── page.tsx # /docs
│ ├── getting-started/
│ ├── user-guide/
│ └── developer/
└── api/ # API routes
├── auth/
│ ├── signin/
│ │ └── route.ts # POST /api/auth/signin
│ └── signup/
│ └── route.ts # POST /api/auth/signup
├── files/
│ ├── route.ts # GET/POST /api/files
│ ├── [id]/
│ │ └── route.ts # GET/PUT/DELETE /api/files/[id]
│ └── upload/
│ └── route.ts # POST /api/files/upload
└── mobile/
├── auth/
└── files/Layout Hierarchy
- Root Layout: Applied to all pages (navigation, providers)
- Auth Layout: Authentication pages (centered forms)
- Dashboard Layout: Main app (sidebar, header, file browser)
- Docs Layout: Documentation (sidebar navigation, search)
Components Organization
Components are organized by usage pattern and complexity, from basic UI elements to complex features.
components/
├── ui/ # Basic UI components
│ ├── Button.tsx # Reusable button component
│ ├── Input.tsx # Form input component
│ ├── Modal.tsx # Modal dialog component
│ ├── Card.tsx # Card container component
│ ├── Badge.tsx # Status badge component
│ └── index.ts # Export barrel
├── forms/ # Form-specific components
│ ├── LoginForm.tsx # Login form
│ ├── SignupForm.tsx # Registration form
│ ├── SettingsForm.tsx # User settings form
│ └── FileUploadForm.tsx # File upload interface
├── layout/ # Layout components
│ ├── Header.tsx # Application header
│ ├── Sidebar.tsx # Navigation sidebar
│ ├── Footer.tsx # Application footer
│ └── Navigation.tsx # Main navigation
├── features/ # Feature-specific components
│ ├── auth/ # Authentication features
│ │ ├── AuthProvider.tsx # Auth context provider
│ │ └── ProtectedRoute.tsx # Route protection
│ ├── files/ # File management features
│ │ ├── FileList.tsx # File listing component
│ │ ├── FilePreview.tsx # File preview modal
│ │ ├── FileUpload.tsx # Upload interface
│ │ └── SearchFiles.tsx # File search
│ └── sharing/ # Sharing features
│ ├── ShareModal.tsx # File sharing dialog
│ └── ShareLink.tsx # Share link component
└── providers/ # Context providers
├── AuthProvider.tsx # Authentication state
├── ThemeProvider.tsx # Theme management
└── FileProvider.tsx # File management stateComponent Patterns
// components/ui/Button.tsx
import { forwardRef } from 'react'
import { cn } from '@/lib/utils'
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline'
size?: 'sm' | 'md' | 'lg'
loading?: boolean
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = 'primary', size = 'md', loading, children, ...props }, ref) => {
return (
<button
className={cn(
'inline-flex items-center justify-center rounded-md font-medium transition-colors',
{
'bg-blue-600 text-white hover:bg-blue-700': variant === 'primary',
'bg-gray-100 text-gray-900 hover:bg-gray-200': variant === 'secondary',
'border border-gray-300 bg-white hover:bg-gray-50': variant === 'outline',
},
{
'h-8 px-3 text-sm': size === 'sm',
'h-10 px-4': size === 'md',
'h-12 px-6 text-lg': size === 'lg',
},
className
)}
ref={ref}
disabled={loading}
{...props}
>
{loading && <span className="mr-2">Loading...</span>}
{children}
</button>
)
}
)
Button.displayName = 'Button'
export { Button }
export type { ButtonProps }Library & Utilities
The lib directory contains shared utilities, configurations, and service integrations.
lib/
├── auth.ts # Authentication configuration (NextAuth.js)
├── storage.ts # S3/R2 storage service
├── redis.ts # Redis client and utilities
├── config.ts # Application configuration
├── constants.ts # Application constants
├── utils.ts # General utility functions
├── validations.ts # Zod validation schemas
├── errors.ts # Custom error classes
├── logger.ts # Logging utilities
├── email.ts # Email service integration
└── upload.ts # File upload utilitiesKey Library Files
Core Services
- auth.ts: NextAuth.js configuration and providers
- storage.ts: S3/R2 client and file operations
- redis.ts: Redis connection and data operations
- config.ts: Environment variable management
Utilities
- utils.ts: General helper functions
- validations.ts: Input validation schemas
- errors.ts: Custom error handling
- logger.ts: Structured logging
Utility Examples
// lib/utils.ts
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
export function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes'
const k = 1024
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
// lib/validations.ts
import { z } from 'zod'
export const signInSchema = z.object({
email: z.string().email('Invalid email address'),
password: z.string().min(8, 'Password must be at least 8 characters'),
})
export const fileUploadSchema = z.object({
name: z.string().min(1, 'File name is required'),
size: z.number().max(100 * 1024 * 1024, 'File size must be less than 100MB'),
type: z.string().min(1, 'File type is required'),
folder: z.string().optional().default('/'),
})Naming Conventions
Consistent naming conventions across the codebase improve readability and maintainability.
File Naming
Next.js Files
- Pages: page.tsx (Next.js convention)
- Layouts: layout.tsx (Next.js convention)
- API Routes: route.ts (Next.js convention)
- Components: PascalCase.tsx (Button.tsx)
General Files
- Utilities: camelCase.ts (fileUtils.ts)
- Constants: camelCase.ts (apiConstants.ts)
- Types: camelCase.ts (userTypes.ts)
- Hooks: useHookName.ts (useAuth.ts)
Code Naming
- Variables: camelCase (userId, fileName, uploadProgress)
- Functions: camelCase (getUserData, handleFileUpload)
- Components: PascalCase (FileUpload, UserProfile)
- Types/Interfaces: PascalCase (User, FileMetadata)
- Constants: UPPER_SNAKE_CASE (API_BASE_URL, MAX_FILE_SIZE)
- CSS Classes: kebab-case (file-list, upload-button)
Consistency Guidelines
- Use descriptive names that clearly indicate purpose
- Avoid abbreviations unless they're widely understood
- Be consistent with similar patterns across the codebase
- Use TypeScript interfaces for complex object structures