# ROA2WEB - Unified Application
> **Single-Page Application** combining Reports and Data Entry modules into one unified frontend.
## ๐ Overview
This is the **unified frontend** for the ROA2WEB ERP system, consolidating two previously separate applications:
- **Reports Module** - Read-only financial reports from Oracle database
- **Data Entry Module** - Fiscal receipt management with approval workflow
### Key Features
- โ
**Single Build & Deployment** - One IIS site instead of two
- โ
**Module Isolation** - Error boundaries prevent crashes from propagating
- โ
**Lazy Loading** - Modules load on-demand for optimal performance
- โ
**Unified Navigation** - Seamless switching between Reports and Data Entry
- โ
**Shared Authentication** - Single login for both modules
- โ
**Feature Flags** - Enable/disable modules via configuration
### Technology Stack
- **Frontend**: Vue 3 (Composition API), Vite
- **UI Library**: PrimeVue (saga-blue theme)
- **State Management**: Pinia
- **Routing**: Vue Router (with lazy loading)
- **HTTP Client**: Axios
- **Charts**: Chart.js, vue-chartjs
- **Export**: jsPDF, xlsx
---
## ๐ Quick Start
### Prerequisites
- **Node.js**: 16+ (18+ recommended)
- **npm**: 8+
- **Backend Services**:
- Reports API running on `http://localhost:8001`
- Data Entry API running on `http://localhost:8003`
### Installation
```bash
# Install dependencies
npm install
```
### Development
#### Option 1: Start All Services at Once (Recommended)
```bash
# Start all services (backends + frontend) in DEV mode
./start-dev.sh
# Or for TEST environment
./start-test.sh
```
This will start:
- Reports Backend on port **8001** (with auto-reload in dev mode)
- Data Entry Backend on port **8003** (with auto-reload in dev mode)
- Telegram Bot on port **8002**
- Unified Frontend on port **3000**
- SSH Tunnel for Oracle database
#### Option 2: Start Services Manually
```bash
# Terminal 1 - Reports Backend
cd reports-app/backend
source venv/bin/activate
uvicorn app.main:app --reload --port 8001
# Terminal 2 - Data Entry Backend
cd data-entry-app/backend
source venv/bin/activate
uvicorn app.main:app --reload --port 8003
# Terminal 3 - Unified Frontend
npm run dev
```
Access the app at: **http://localhost:3000**
### Production Build
```bash
# Build for production
npm run build
# Preview production build locally
npm run preview
```
Build output will be in the `dist/` directory.
---
## ๐๏ธ Architecture
### Directory Structure
```
src/
โโโ main.js # App entry point
โโโ App.vue # Root component with unified menu
โ
โโโ router/
โ โโโ index.js # Unified router with lazy loading
โ
โโโ config/
โ โโโ menu.js # Menu configuration
โ โโโ features.js # Feature flags
โ
โโโ modules/
โ โโโ reports/ # REPORTS MODULE (isolated)
โ โ โโโ ReportsLayout.vue # Error boundary wrapper
โ โ โโโ views/ # Dashboard, Invoices, Bank/Cash, etc.
โ โ โโโ components/ # Reports-specific components
โ โ โโโ stores/ # Module stores + sharedStores.js
โ โ โโโ services/
โ โ โโโ api.js # API client (/api/reports)
โ โ
โ โโโ data-entry/ # DATA ENTRY MODULE (isolated)
โ โโโ DataEntryLayout.vue # Error boundary wrapper
โ โโโ views/receipts/ # Receipts List, Create
โ โโโ components/ocr/ # OCR components
โ โโโ stores/ # Module stores + sharedStores.js
โ โโโ services/
โ โโโ api.js # API client (/api/data-entry)
โ
โโโ shared/ # SHARED ACROSS MODULES
โ โโโ components/ # LoginView, Selectors, Layout
โ โ โโโ LoginView.vue
โ โ โโโ CompanySelector.vue
โ โ โโโ PeriodSelector.vue
โ โ โโโ ErrorBoundary.vue
โ โ โโโ layout/
โ โ โโโ AppHeader.vue
โ โ โโโ SlideMenu.vue
โ โโโ stores/ # Shared store factories
โ โ โโโ auth.js
โ โ โโโ companies.js
โ โ โโโ accountingPeriod.js
โ โโโ styles/ # Shared CSS
โ
โโโ assets/
โโโ css/ # Global CSS design system
โโโ core/ # Design tokens
โโโ components/ # Component patterns
โโโ patterns/ # Interactive patterns
โโโ layout/ # Page structure
โโโ utilities/ # Utility classes
โโโ vendor/ # PrimeVue overrides
```
### Module Isolation
Each module is wrapped in an **ErrorBoundary** component:
```vue
```
**Benefits**:
- Errors in one module don't crash the entire app
- Other modules continue to function normally
- User-friendly error messages with recovery options
### Lazy Loading Strategy
Modules are loaded **on-demand** using dynamic imports:
```javascript
// Reports module loaded only when user navigates to /reports/*
{
path: '/reports',
component: () => import('@/modules/reports/ReportsLayout.vue'),
children: [
{
path: 'dashboard',
component: () => import('@reports/views/DashboardView.vue')
}
]
}
```
### Shared Store Pattern
Shared stores use a **factory pattern** to work with both modules:
```javascript
// src/shared/stores/auth.js
export function createAuthStore(apiService) {
return defineStore('auth', () => {
// Store implementation using provided apiService
})
}
// src/modules/reports/stores/sharedStores.js
import { createAuthStore } from '@shared/stores/auth'
import api from '@reports/services/api'
export const useAuthStore = createAuthStore(api) // Binds to Reports API
```
Each module instantiates shared stores with its own API service.
---
## ๐ URL Structure
### Public Routes
- `/login` - Login page
### Reports Module
- `/reports/dashboard` - Financial dashboard
- `/reports/invoices` - Invoices view
- `/reports/bank-cash` - Bank & cash register
- `/reports/trial-balance` - Trial balance
- `/reports/telegram` - Telegram bot management
- `/reports/cache-stats` - Cache statistics
### Data Entry Module
- `/data-entry` - Receipts list
- `/data-entry/create` - Create new receipt
- `/data-entry/:id` - View receipt details
- `/data-entry/:id/edit` - Edit receipt
### Redirects
- `/` โ `/reports/dashboard` (default)
---
## ๐ข Deployment
### IIS Configuration (Windows Production)
#### 1. Build the Application
```bash
npm run build
```
#### 2. Deploy to IIS
Copy the `dist/` folder contents to your IIS site directory (e.g., `C:\inetpub\wwwroot\roa2web\`).
#### 3. Configure URL Rewriting
The `public/web.config` file (copied to `dist/`) contains the necessary IIS rewrite rules:
- **API Proxies**:
- `/api/reports/*` โ `http://localhost:8001/api/*`
- `/api/data-entry/*` โ `http://localhost:8003/api/*`
- `/uploads/*` โ `http://localhost:8003/uploads/*`
- **SPA Fallback**: All other routes โ `/index.html`
#### 4. Start Backend Services
Ensure both backend services are running:
- Reports API (port 8001) - via NSSM or similar
- Data Entry API (port 8003) - via NSSM or similar
#### 5. IIS Application Pool Settings
- **.NET CLR Version**: No Managed Code
- **Pipeline Mode**: Integrated
- **Identity**: ApplicationPoolIdentity (or custom service account)
### Nginx Configuration (Linux Production)
```nginx
server {
listen 80;
server_name your-domain.com;
root /var/www/roa2web;
index index.html;
# API Proxies
location /api/reports/ {
proxy_pass http://localhost:8001/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/data-entry/ {
proxy_pass http://localhost:8003/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /uploads/ {
proxy_pass http://localhost:8003/uploads/;
}
# SPA Fallback
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
```
---
## ๐๏ธ Feature Flags
Feature flags allow enabling/disabling modules without redeployment.
### Configuration
Edit `src/config/features.js`:
```javascript
export const features = {
reports: {
enabled: true,
modules: {
dashboard: true,
invoices: true,
bankCash: true,
trialBalance: true,
telegram: true,
cacheStats: true
}
},
dataEntry: {
enabled: true,
modules: {
receipts: true,
ocr: true
}
}
}
```
### Environment Variables
Override via `.env` file:
```bash
# Disable Data Entry module
VITE_FEATURE_DATA_ENTRY=false
# Disable Reports module
VITE_FEATURE_REPORTS=false
```
### Usage
The menu automatically filters disabled modules:
```javascript
import { isFeatureEnabled } from '@/config/features'
if (isFeatureEnabled('reports')) {
// Show Reports menu items
}
```
---
## ๐ ๏ธ Development Guide
### Adding a New Route
#### 1. Create the View Component
```bash
# For Reports module
src/modules/reports/views/NewView.vue
# For Data Entry module
src/modules/data-entry/views/NewView.vue
```
#### 2. Register in Router
Edit `src/router/index.js`:
```javascript
{
path: '/reports/new-feature',
name: 'NewFeature',
component: () => import('@reports/views/NewView.vue'),
meta: { requiresAuth: true, title: 'New Feature - ROA2WEB' }
}
```
#### 3. Add to Menu
Edit `src/config/menu.js`:
```javascript
{
to: '/reports/new-feature',
icon: 'pi pi-star',
label: 'New Feature'
}
```
### Adding a New Component
#### Module-Specific Component
```bash
# Reports module
src/modules/reports/components/MyComponent.vue
# Data Entry module
src/modules/data-entry/components/MyComponent.vue
```
Import using module alias:
```javascript
import MyComponent from '@reports/components/MyComponent.vue'
```
#### Shared Component
```bash
src/shared/components/MySharedComponent.vue
```
Import using shared alias:
```javascript
import MySharedComponent from '@shared/components/MySharedComponent.vue'
```
### Using the CSS Design System
The unified app uses the **Reports App CSS architecture**. See `docs/ONBOARDING_CSS.md` for a complete guide.
#### Quick Reference
**Design Tokens** (`src/assets/css/core/tokens.css`):
```css
var(--color-primary) /* #2563eb - Primary blue */
var(--color-success) /* #16a34a - Success green */
var(--color-danger) /* #dc2626 - Danger red */
var(--spacing-md) /* 1rem - Medium spacing */
var(--radius-md) /* 0.5rem - Medium border radius */
```
**Component Patterns** (`src/assets/css/components/`):
```html
Active
Pending
```
**Best Practices**:
- โ
Use global patterns from `src/assets/css/`
- โ
Use design tokens for colors, spacing, typography
- โ Don't create new CSS files without checking existing patterns
- โ Don't use `