Complete documentation for the CreateFormulaV2 fragrance formulation management application. This documentation covers architecture, features, components, and development guidelines.
- Architecture - Application structure, patterns, and design decisions
- Features - Detailed feature specifications with user stories
- State Management - State patterns and event bus
- Feature Flags & API Integration - Complete integration guide
- Feature Flags Quick Start - Quick reference for developers
- Quick Reference - Fast lookup guide
CreateFormulaV2 is a React-based perfume formulation management system that enables perfumers to:
- Create and manage fragrance formulas
- Work with ingredient libraries
- Calculate formulations with real-time totals
- Use multi-workspace sessions for parallel projects
- Dilute ingredients with solvents
- Submit formulas for compounding
- Track changes with undo/redo
- React 19.0.0 with TypeScript 5.7.2
- Vite 6.0.5 for build tooling
- Tailwind CSS 3.4.0 for styling
- React Context API for state management
- Event Bus for component communication
- i18next for internationalization
Complete formula lifecycle management including creation, versioning, and activation.
Key User Stories:
- US-001: View Formula Library
- US-002: Select Formula for Workspace
- US-003: Create New Formula
- US-004: Edit Formula Metadata
- US-005: Set Active/Editable Formula
- US-006: Create Formula Version
- US-007: Normalize Formula
- US-008: Send Formula for Compounding
- US-009: Remove Formula from Workspace
- US-010: View Formula Metrics
Files:
src/components/FormulaModal.tsxsrc/components/FormulaList.tsxsrc/view/WorkArea/hooks/useFormulaOperations.tssrc/view/WorkArea/components/FormulaColumnHandlers.tsx
Comprehensive ingredient browsing, searching, filtering, and selection system.
Key User Stories:
- US-020: Browse Ingredient Library
- US-021: Search Ingredients
- US-022: Filter by Ingredient Type
- US-023: Advanced Filtering
- US-024: View Ingredient Quick Info
- US-025: View Ingredient Full Details
- US-026: Add Ingredient to Formula
- US-027: Remove Ingredient from Formula
- US-028: View Ingredient Usage
- US-029: Sort Ingredient List
Files:
src/components/IngredientList.tsxsrc/components/IngredientQuickView.tsxsrc/components/QueryBuilder.tsxsrc/view/Library/LibraryPanel.tsx
Advanced table operations including inline editing, drag-and-drop, bulk actions, and keyboard navigation.
Key User Stories:
- US-040: Edit Cell Values Inline
- US-041: Reorder Rows by Dragging
- US-042: Select Multiple Rows
- US-043: Bulk Delete Rows
- US-044: Add/Remove Columns
- US-045: Sort by Column
- US-046: Filter Column Values
- US-047: Group Rows by Attribute
- US-048: View Running Total
- US-049: Keyboard Navigation
- US-050: Copy/Paste Values
- US-051: Export Grid Data
- US-052: Resize Columns
Files:
src/components/DataGrid.tsxsrc/components/DataGrid/components/CellRenderer.tsxsrc/components/DataGrid/hooks/useRowReordering.tssrc/components/DataGrid/hooks/useBulkSelection.tssrc/components/DataGrid/hooks/useKeyboardNavigation.ts
Multi-workspace support with isolated sessions and formula locking.
Key User Stories:
- US-060: View Active Workspace
- US-061: Create New Workspace
- US-062: Switch Between Workspaces
- US-063: Rename Workspace
- US-064: Close Workspace
- US-065: Reset Workspace
- US-066: Formula Locking Across Workspaces
- US-067: View Workspace Summary
- US-068: Workspace State Persistence
- US-069: Workspace Limit Management
Files:
src/context/WorkspaceContext.tsxsrc/components/workspace/WorkspaceTabs.tsxsrc/hooks/useWorkspace.ts
Ingredient dilution system with solvent management and concentration calculations.
Key User Stories:
- US-080: Add Dilution to Ingredient
- US-081: View Dilution Details
- US-082: Edit Dilution
- US-083: Remove Dilution
- US-084: Multiple Solvents Selection
- US-085: Dilution Calculation Display
Files:
src/components/dilution/DilutionModal.tsxsrc/components/dilution/DilutionBadge.tsxsrc/components/dilution/useDilution.tssrc/types/dilution.ts
src/
├── components/ # Reusable UI components
│ ├── DataGrid/ # DataGrid sub-components
│ ├── dilution/ # Dilution feature
│ ├── workspace/ # Workspace management
│ └── *.tsx # Other components
├── context/ # React Context providers
├── hooks/ # Custom React hooks
├── services/ # External service integrations
├── utils/ # Utility functions
├── view/ # Major view components
│ ├── AppShell/ # App shell and header
│ ├── Library/ # Library panel
│ └── WorkArea/ # Main workspace
├── mocks/ # Mock data
└── types/ # TypeScript types
- Event-Driven Communication - Custom event bus for decoupled components
- Custom Hooks - Business logic extracted into reusable hooks
- Context API - Global state via WorkspaceContext
- State History - Undo/redo with StateHistoryManager
- Service Layer - API abstraction via PegaService
User Action → Component Event → Hook Function → State Update → Re-render
↓
Event Bus Notification → Other Components Update
npm installnpm run dev # Start at http://localhost:5173npm run build
npm run previewnpm run lintFormulas are compositions of ingredients with percentages. Each formula has:
- Unique ID and version
- Status (draft, active, archived, submitted)
- Ingredients list with percentages
- Metadata (creator, category, description)
Workspaces are isolated sessions that allow working on multiple projects:
- Maximum 3 concurrent workspaces
- Each has independent state (formulas, ingredients, grid)
- Formula locking prevents concurrent editing
- Default workspace (Alpha) cannot be closed
The central component for formula editing:
- Columns: Ingredient properties, formulas, attributes
- Rows: Ingredients with values per formula
- Total rows: Running total, target, RMC, lines count
- Operations: Edit, reorder, bulk actions, sorting
Real-time calculations include:
- Running Total: Sum of all ingredient percentages
- Target Total: Always 100.00000 (normalized)
- RMC (Raw Material Cost): Sum of contribution costs
- Contribution Cost: (percentage × costPerKg) / 1000
- Number of Lines: Count of non-zero ingredients
Custom event system for cross-component communication:
// Emit
eventBus.emit('ingredient-selected', { ingredient });
// Listen
eventBus.on('ingredient-selected', (data) => {
// Handle event
});
// Cleanup
eventBus.off('ingredient-selected', handler);The application is designed to integrate with Pega DX API:
- Formula Management: CRUD operations for formulas
- Ingredient Library: Fetch and search ingredients
- Attributes: Get ingredient attributes
- Compounding: Submit formulas for production
- Authentication: Bearer token authentication
Current implementation uses mock data in src/mocks/.
// 1. Imports
import React, { useState } from 'react';
// 2. Types
interface Props {}
// 3. Component
const Component = ({ prop }: Props) => {
// 4. Hooks
const [state, setState] = useState();
// 5. Handlers
const handleClick = () => {};
// 6. Effects
useEffect(() => {}, []);
// 7. Render
return <div />;
};
// 8. Export
export default Component;- Components: PascalCase (
DataGrid.tsx) - Hooks: camelCase with
useprefix (useWorkspace.ts) - Utils: camelCase (
formulaCalculations.ts) - Types: PascalCase (
Formula.ts)
Unit tests should cover:
- Utility functions (calculations, validators)
- Custom hooks in isolation
- Component rendering and interactions
- Event bus communication
- State management logic
- Create feature documentation in
docs/features/ - Define user stories and acceptance criteria
- Design data models and types
- Implement components and hooks
- Add event bus events if needed
- Update related components
- Add tests
- Update documentation
- Create component file in appropriate directory
- Define TypeScript interfaces for props
- Implement component logic
- Add JSDoc comments
- Export from index file if in subdirectory
- Document in COMPONENTS.md (when created)
- Create hook file in
src/hooks/or feature directory - Define return type interface
- Implement hook logic with memoization
- Add JSDoc comments
- Export and use in components
Formula not updating after edit:
- Check if editableFormula is set correctly
- Verify event bus listeners are registered
- Check console for validation errors
Workspace data lost on switch:
- Ensure updateWorkspaceData is called
- Check WorkspaceContext provider wraps app
- Verify activeWorkspace is being used
Calculations incorrect:
- Check formula column IDs match selectedFormulaIds
- Verify calculateTotals is called after updates
- Check for NaN values in data
Performance issues:
- Enable virtual scrolling for large lists
- Memoize expensive calculations
- Check for unnecessary re-renders
README.md- Project readmepackage.json- Dependencies and scriptsvite.config.ts- Build configurationtsconfig.json- TypeScript configurationtailwind.config.ts- Tailwind configuration
- Use clear, concise language
- Include code examples
- Add screenshots for UI features
- Keep user stories actionable
- Update index when adding docs
- Follow TypeScript strict mode
- Use functional components with hooks
- Implement proper error handling
- Add comments for complex logic
- Write self-documenting code
[License information]
[Contact information]
Last Updated: November 5, 2025
Version: 0.0.0
Documentation Status: In Progress