Front is a React-based monorepo project built with Nx. This documentation provides comprehensive information about the project structure, development workflow, and best practices.
- Project Setup
- Development Workflow
- Project Structure
- Best Practices
- Commands Reference
- UI Design Inspiration
This project is built as an Nx workspace, which provides tools for monorepo management, code generation, and task execution. The workspace contains multiple applications and libraries that share code and configurations.
- Node.js v23 (use
nvm use 23
to switch) - npm or yarn
- Clone the repository
- Install dependencies:
pnpm install
- Start the development server:
npx nx serve core
To run the development server for a specific application:
npx nx serve core-ui # Run the core application
npx nx serve core-ui --devRemotes=[plugin name]-ui,[another plugin name]-ui # Run plugin in development mode
npx nx build core # Build the core application
npx nx build plugin # Build a plugin application
npx nx serve-static core # Serve the built core application
npx nx graph # Visualize project dependencies
npx nx show project core # Show available targets for a project
The recommended folder structure for modules:
module_name/
├── components/ # React components
├── hooks/ # Custom React hooks
├── types/ # TypeScript interfaces and types
├── utils/ # Utility functions
├── contexts/ # React contexts
├── graphql/ # GraphQL queries and mutations
└── states/ # State management
- Use TypeScript for all code; prefer interfaces over types
- Use functional components with TypeScript interfaces
- Avoid classes; use functional and declarative programming patterns
- Use descriptive variable names with auxiliary verbs (e.g.,
isLoading
,hasError
) - Structure files with exported component, utils, contexts, hooks, types
- Use lowercase with dashes for directories (e.g.,
components/auth-wizard
) - Favor named exports for components
- Avoid enums; use maps instead
- Think twice before using
any
type - Use absolute paths for imports
- Use Shadcn UI, Radix, and Tailwind for components and styling
- Implement responsive design with Tailwind CSS; use a mobile-first approach
- Avoid arbitrary Tailwind class names when possible
- Minimize use of
useEffect
- Use
useQueryState
hook for URL search parameter state management
- Clean up console.log statements
- Ensure code follows project structure and naming conventions
nvm use 23 # Switch to Node.js v23
npx nx serve core-ui # Start core development server
npx nx serve core-ui --devRemotes=[plugin name]-ui # Start with remote modules
npx nx build core # Build core for production
npx nx build plugin # Build plugin for production
npx nx serve-static core # Serve production build
npx nx list # List installed plugins
npx nx list <plugin-name> # Show capabilities of a plugin
npx nx g @nx/react:app demo # Generate a new application
npx nx g @nx/react:lib mylib # Generate a new library
The project draws design inspiration from:
- Shopify
- Airtable
- Attio
- Twenty
The project includes a Quick Actions feature that provides suggestions based on:
- Current page context
- Recent user actions
- User context (company, team, role)
- User intent
- Browser location
- User activity history
- React - UI library
- TypeScript - JavaScript with syntax for types
- Tailwind CSS - Utility-first CSS framework
- Shadcn UI - Re-usable components built with Radix UI and Tailwind
- Radix UI - Unstyled, accessible UI components
- React Router - Routing library for React
Tailwind CSS in this project uses CSS variables for theming and consistent styling. These variables are defined in the root CSS file and can be accessed throughout the application.
The project uses CSS variables for colors, spacing, and other design tokens. These are defined in the theme configuration and can be accessed in Tailwind classes or directly in CSS.
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
The project uses a set of shadow CSS variables for consistent elevation across the UI. These are the shadow variables currently implemented in the project:
:root {
/* Default shadow set */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}
.dark {
/* Adjusted shadows for dark mode */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.3);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.3), 0 8px 10px -6px rgb(0 0 0 / 0.3);
}
These shadow variables are used in Tailwind classes throughout the application:
<div className="shadow-sm">Small shadow for subtle elevation</div>
<div className="shadow">Default shadow for cards and containers</div>
<div className="shadow-md">Medium shadow for dropdowns and popovers</div>
<div className="shadow-lg">Large shadow for modals and dialogs</div>
<div className="shadow-xl">Extra large shadow for important UI elements</div>
The shadow system automatically adjusts between light and dark modes to maintain appropriate visual hierarchy while ensuring sufficient contrast in both themes.
- copy&paste sample_ui folder & replace name
- fix port in project.json
- replace all plugin names
core-ui/module-federation.config.ts
add to remotes- run in dev mode
nx serve core-ui --devRemotes=[plugin name]_ui
- change icon at module/constants/config.ts
A Node.js backend service
backend/
├── core-api/ # Core API service
├── gateway/ # API Gateway
├── libs/ # Shared libraries
The core API service handles all accounting-related operations.
- Main settings management
- Currency configuration
- Tax settings (VAT and CTax)
- Account mapping
- GraphQL API
- TypeScript support
- MongoDB integration
query GetMainConfigs {
getMainConfigs {
MainCurrency
HasVat
VatPayableAccount
VatReceivableAccount
VatAfterPayableAccount
VatAfterReceivableAccount
HasCtax
CtaxPayableAccount
}
}
query GetAccounts($journal: String) {
getAccounts(journal: $journal) {
_id
name
code
type
}
}
mutation UpdateMainConfigs($input: MainConfigsInput!) {
updateMainConfigs(input: $input) {
MainCurrency
HasVat
VatPayableAccount
VatReceivableAccount
VatAfterPayableAccount
VatAfterReceivableAccount
HasCtax
CtaxPayableAccount
}
}
interface MainConfigs {
MainCurrency: string;
HasVat: boolean;
VatPayableAccount?: string;
VatReceivableAccount?: string;
VatAfterPayableAccount?: string;
VatAfterReceivableAccount?: string;
HasCtax: boolean;
CtaxPayableAccount?: string;
}
Handles configuration management:
class ConfigsService {
async getMainConfigs(): Promise<MainConfigs>;
async updateMainConfigs(input: MainConfigsInput): Promise<MainConfigs>;
}
Manages account-related operations:
class AccountsService {
async getAccounts(journal?: string): Promise<Account[]>;
}
The API Gateway provides:
- Request routing
- Authentication
- Rate limiting
- Request/Response transformation
- Error handling
- Type definitions
- Validation schemas
- Helper functions
- Constants
- MongoDB schemas
- TypeScript interfaces
- Validation rules
Monitors and manages message queues:
- Queue status
- Message processing
- Error tracking
- Performance metrics
- Install dependencies:
pnpm install
- Set up environment variables:
cp .env.sample .env
- Start development servers:
# Start core API
pnpm dev:core-api
# Start gateway
pnpm dev:gateway
# Run all tests
pnpm test
# Run specific service tests
pnpm test:core-api
pnpm test:gateway
configs
: Stores system configurationsaccounts
: Stores account informationtransactions
: Stores transaction records
// configs collection
db.configs.createIndex({ MainCurrency: 1 });
// accounts collection
db.accounts.createIndex({ code: 1 }, { unique: true });
db.accounts.createIndex({ journal: 1 });
The backend implements a standardized error handling system:
interface ApiError {
code: string;
message: string;
details?: Record<string, any>;
}
Common error codes:
INVALID_INPUT
: Invalid request dataNOT_FOUND
: Resource not foundUNAUTHORIZED
: Authentication requiredFORBIDDEN
: Insufficient permissionsINTERNAL_ERROR
: Server error
- JWT authentication
- Role-based access control
- Input validation
- Rate limiting
- CORS configuration
- Security headers
- Database indexing
- Query optimization
- Caching strategies
- Connection pooling
- Request batching
- Health checks
- Performance metrics
- Error tracking
- Usage statistics
- Logging system
- Follow TypeScript best practices
- Write unit tests for new features
- Update documentation
- Follow the established code style
- Create feature branches
- Submit pull requests
[Your License Here]