Development Overview
This guide provides an overview of the WealthVN development environment and common workflows.
Prerequisites
- Node.js 18+ and pnpm package manager
- Rust 1.70+ (for desktop and server development)
- Docker (optional, for containerized development)
- Git for version control
Repository Structure
wealthvn/
├── src/ # Frontend application (React + Vite)
│ ├── pages/ # Page components
│ ├── components/ # Reusable UI components
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Core utilities and types
│ ├── commands/ # Frontend command wrappers
│ └── addons/ # Addon runtime
├── src-tauri/ # Desktop app (Tauri + Rust)
│ └── src/commands/ # Tauri backend commands
├── src-server/ # Web server (Axum + Rust)
│ └── src/api.rs # HTTP API endpoints
├── src-core/ # Shared business logic (Rust)
│ ├── src/ # Core services
│ └── migrations/ # Database migrations
├── packages/ # Shared libraries
│ ├── ui/ # @wealthvn/ui component library
│ ├── addon-sdk/ # TypeScript addon SDK
│ └── addon-dev-tools/ # Addon development CLI
├── addons/ # Example addons
├── docs/ # Documentation
└── scripts/ # Build and utility scripts
Development Workflow
1. Setup
Clone the repository and install dependencies:
git clone https://github.com/chipheo00/vn-wealthvn.git
cd wealthvn
pnpm install
2. Development Modes
Frontend Only (Vite dev server)
pnpm dev
- Runs at
http://localhost:1420 - Hot module replacement enabled
- Fast refresh for component changes
Desktop (Tauri)
pnpm tauri dev
- Opens native desktop window
- Full backend integration
- SQLite database available
Web Mode (Vite + Axum)
pnpm run dev:web
- Frontend runs at
http://localhost:1420 - Axum server runs in background
- API proxied to
localhost:3000
3. Building
Development Build
pnpm build
- TypeScript compilation
- Vite optimization
- All dependencies built
- Documentation synced and generated
Desktop Build
pnpm tauri build
- Creates native executables
- Platform-specific (Windows, macOS, Linux)
- Packaged for distribution
Code Conventions
TypeScript
- Strict mode enabled
- No unused variables or parameters
- Functional components preferred
- Named exports for components
- Interfaces over
typealiases - Descriptive naming (
isLoading,hasError)
Example:
interface ButtonProps {
variant: 'primary' | 'secondary';
onClick: () => void;
children: React.ReactNode;
}
export function Button({ variant, onClick, children }: ButtonProps) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{children}
</button>
);
}
Rust
- Idiomatic Rust patterns
- Result/Option for error handling
- Immutable by default
- Clear error messages with
thiserror - Async/await for concurrent operations
Example:
#[derive(Debug, thiserror::Error)]
pub enum PortfolioError {
#[error("Portfolio not found: {0}")]
NotFound(String),
#[error("Database error: {0}")]
Database(String),
}
pub async fn get_portfolio(id: &str) -> Result<Portfolio, PortfolioError> {
// implementation
}
Styling
- Tailwind CSS utility-first approach
- Component-level styles in CSS files
- Theme tokens from
src/styles.css - Dark mode support via CSS variables
- No ad-hoc global CSS - use utilities or local scopes
Testing
Unit Tests
pnpm test
- Vitest configuration
- React Testing Library for components
- Coverage reports available
Test Watch Mode
pnpm test:watch
- Re-run tests on file changes
- Interactive test selection
Coverage Report
pnpm test:coverage
- Generate HTML coverage report
- Stored in
coverage/directory
Linting & Formatting
Check Code Quality
pnpm check
- Runs ESLint, Prettier, and TypeScript checks
- No fixes applied
Fix Issues
pnpm lint:fix
pnpm format
- Auto-fix linting issues
- Auto-format code style
Documentation
View Documentation
pnpm docs:dev
- Starts Docusaurus dev server
- Watches for markdown changes
- Runs at
http://localhost:3000
Build Documentation
pnpm docs:serve
- Builds static documentation
- Serves optimized build
Adding a New Feature
1. Frontend Route & UI
Create page in src/pages/:
// src/pages/my-feature.tsx
export function MyFeaturePage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold">My Feature</h1>
</div>
);
}
Add route in src/routes.tsx:
{
path: '/my-feature',
element: <MyFeaturePage />,
}
2. Command Wrapper
Create in src/commands/my-feature.ts:
import { getRunEnv, invokeTauri, invokeWeb } from '../adapters';
export async function getMyData(id: string): Promise<MyData> {
const env = getRunEnv();
if (env === 'desktop') {
return invokeTauri('get_my_data', { id });
} else {
return invokeWeb('/api/my-feature', { id });
}
}
3. Backend Implementation
Desktop (src-tauri/src/commands/my_feature.rs)
#[tauri::command]
pub async fn get_my_data(id: String, state: tauri::State<'_, AppState>) -> Result<MyData, String> {
let service = &state.my_service;
service.get_data(&id).await.map_err(|e| e.to_string())
}
Web (src-server/src/api.rs)
async fn get_my_data(
Path(id): Path<String>,
State(state): State<AppState>,
) -> Result<Json<MyData>, ApiError> {
state.my_service.get_data(&id).await.map(Json)
}
4. Core Logic (src-core/src/)
Implement business logic in services and repositories.
5. Tests
Add tests near your implementation:
// src/lib/my-feature.test.ts
import { describe, it, expect } from 'vitest';
import { processData } from './my-feature';
describe('processData', () => {
it('should process data correctly', () => {
const result = processData({ /* test data */ });
expect(result).toBeDefined();
});
});
Common Commands Reference
| Command | Purpose |
|---|---|
pnpm dev | Frontend development server |
pnpm tauri dev | Desktop development |
pnpm run dev:web | Web mode (frontend + server) |
pnpm build | Production build all targets |
pnpm test | Run all tests |
pnpm lint:fix | Fix linting issues |
pnpm format | Format code |
pnpm docs:dev | Documentation dev server |
pnpm type-check | Check TypeScript types |
Troubleshooting
Port Already in Use
If port 1420 is already in use:
# Kill process on port 1420
lsof -ti:1420 | xargs kill -9
Rust Compilation Errors
Clean and rebuild:
cargo clean
pnpm tauri dev
Dependency Issues
Clean install:
rm -rf node_modules pnpm-lock.yaml
pnpm install
Next Steps
- API Reference - Detailed API documentation
- Addon Development - Build custom features
- Deployment - Deploy to production
Need Help?
- Check existing issues on GitHub
- Read relevant documentation sections
- Ask in GitHub Discussions
- Review similar code examples in the codebase