unified app plan
This commit is contained in:
5
.claude/settings.json
Normal file
5
.claude/settings.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"enabledPlugins": {
|
||||
"ab@roa2web-tools": true
|
||||
}
|
||||
}
|
||||
32
.claude_settings.json
Normal file
32
.claude_settings.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"sandbox": {
|
||||
"enabled": true,
|
||||
"autoAllowBashIfSandboxed": true
|
||||
},
|
||||
"permissions": {
|
||||
"defaultMode": "acceptEdits",
|
||||
"allow": [
|
||||
"Read(./**)",
|
||||
"Write(./**)",
|
||||
"Edit(./**)",
|
||||
"Glob(./**)",
|
||||
"Grep(./**)",
|
||||
"Bash(*)",
|
||||
"mcp__puppeteer__puppeteer_connect_active_tab",
|
||||
"mcp__puppeteer__puppeteer_navigate",
|
||||
"mcp__puppeteer__puppeteer_screenshot",
|
||||
"mcp__puppeteer__puppeteer_click",
|
||||
"mcp__puppeteer__puppeteer_fill",
|
||||
"mcp__puppeteer__puppeteer_select",
|
||||
"mcp__puppeteer__puppeteer_hover",
|
||||
"mcp__puppeteer__puppeteer_evaluate",
|
||||
"mcp__context7__resolve-library-id",
|
||||
"mcp__context7__get-library-docs",
|
||||
"mcp__graphiti-memory__search_nodes",
|
||||
"mcp__graphiti-memory__search_facts",
|
||||
"mcp__graphiti-memory__add_episode",
|
||||
"mcp__graphiti-memory__get_episodes",
|
||||
"mcp__graphiti-memory__get_entity_edge"
|
||||
]
|
||||
}
|
||||
}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -510,3 +510,6 @@ TELEGRAM_EMAIL_AUTH_PLAN*.md
|
||||
secrets-backup/**/*.env
|
||||
secrets-backup/**/.env.*
|
||||
!secrets-backup/**/*.gpg
|
||||
|
||||
.playwright-mcp/*
|
||||
data-entry-app/backend/data/*
|
||||
285
IMPLEMENTATION_PLAN_UNIFIED_APP.md
Normal file
285
IMPLEMENTATION_PLAN_UNIFIED_APP.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# Plan: Consolidare ROA2WEB - Pragmatic Monolith
|
||||
|
||||
> **Branch**: `feature/unified-app-pragmatic-monolith`
|
||||
> **Status**: APROBAT - Ready for Implementation
|
||||
> **Efort estimat**: ~2.5 zile
|
||||
|
||||
---
|
||||
|
||||
## Context și Problema
|
||||
|
||||
### Situația Curentă
|
||||
- 2 aplicații frontend separate în IIS: `/roa2web/` și `/data-entry/`
|
||||
- Deploy greoi (2 build-uri, 2 configurații IIS separate)
|
||||
- Componentele shared cauzează probleme CSS cross-app (text alb pe fundal alb)
|
||||
- Nu există meniu unificat între aplicații
|
||||
|
||||
### Obiectiv
|
||||
- Un singur meniu cu ambele aplicații (Reports + Data Entry)
|
||||
- Deploy simplificat (un build, un site IIS)
|
||||
- Izolare între module (bug în Reports să nu afecteze DataEntry)
|
||||
- URL-uri pe root: `/reports/*`, `/data-entry/*`
|
||||
|
||||
---
|
||||
|
||||
## Decizie Arhitecturală: Pragmatic Monolith
|
||||
|
||||
### De ce NU Micro-frontends?
|
||||
| Criteriu pentru MFE | ROA2WEB | Necesită MFE? |
|
||||
|---------------------|---------|---------------|
|
||||
| 20+ dezvoltatori | 1 dev | ❌ Nu |
|
||||
| Deploy de multe ori/zi | Săptămânal | ❌ Nu |
|
||||
| Milioane de utilizatori | 1-5 concurenți | ❌ Nu |
|
||||
| Framework-uri diferite | Vue only | ❌ Nu |
|
||||
|
||||
**Verdict**: Module Federation / Single-SPA = OVERKILL
|
||||
|
||||
### Abordare Aleasă: Monolith cu Mecanisme de Izolare
|
||||
- **Error Boundaries** per modul (bug în Reports nu strică DataEntry)
|
||||
- **Lazy Loading** (bundle-uri separate, încărcate la nevoie)
|
||||
- **Stores izolate** per modul
|
||||
- **Feature flags** pentru control
|
||||
|
||||
**Blast radius cu protecții: 50-70%** (aproape ca 2 apps separate!)
|
||||
|
||||
---
|
||||
|
||||
## Arhitectura Finală
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ROA2WEB Unified SPA │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │
|
||||
│ │ Reports Module │ │ DataEntry Module │ │ Shared │ │
|
||||
│ │ /reports/* │ │ /data-entry/* │ │ - Auth │ │
|
||||
│ │ (lazy loaded) │ │ (lazy loaded) │ │ - Company │ │
|
||||
│ │ │ │ │ │ - Period │ │
|
||||
│ │ ErrorBoundary │ │ ErrorBoundary │ │ - Header │ │
|
||||
│ └────────┬────────┘ └────────┬─────────┘ └──────────────┘ │
|
||||
│ │ │ │
|
||||
│ ┌────────┴────────────────────┴─────────┐ │
|
||||
│ │ Vue Router + Global Error Handler │ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────┴─────────┐
|
||||
│ IIS Proxy │
|
||||
└─────────┬─────────┘
|
||||
┌───────────────┴───────────────┐
|
||||
│ │
|
||||
┌────────▼────────┐ ┌──────────▼────────┐
|
||||
│ Reports Backend │ │ DataEntry Backend │
|
||||
│ port 8001 │ │ port 8003 │
|
||||
│ (Oracle RO) │ │ (SQLite + Oracle) │
|
||||
└─────────────────┘ └───────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Structura Proiect Unified
|
||||
|
||||
```
|
||||
roa2web/
|
||||
├── src/
|
||||
│ ├── main.js
|
||||
│ ├── App.vue # Meniu unificat
|
||||
│ ├── router/index.js # Rute unificate cu lazy loading
|
||||
│ │
|
||||
│ ├── modules/
|
||||
│ │ ├── reports/ # MODUL IZOLAT
|
||||
│ │ │ ├── ReportsLayout.vue # Error boundary pentru modul
|
||||
│ │ │ ├── views/
|
||||
│ │ │ │ ├── DashboardView.vue
|
||||
│ │ │ │ ├── InvoicesView.vue
|
||||
│ │ │ │ ├── BankCashRegisterView.vue
|
||||
│ │ │ │ ├── TrialBalanceView.vue
|
||||
│ │ │ │ ├── TelegramView.vue
|
||||
│ │ │ │ └── CacheStatsView.vue
|
||||
│ │ │ ├── stores/
|
||||
│ │ │ └── services/
|
||||
│ │ │
|
||||
│ │ └── data-entry/ # MODUL IZOLAT
|
||||
│ │ ├── DataEntryLayout.vue
|
||||
│ │ ├── views/
|
||||
│ │ │ ├── ReceiptsListView.vue
|
||||
│ │ │ └── ReceiptCreateView.vue
|
||||
│ │ ├── stores/
|
||||
│ │ └── services/
|
||||
│ │
|
||||
│ ├── shared/ # Shared între module
|
||||
│ │ ├── components/ # AppHeader, SlideMenu, CompanySelector, etc.
|
||||
│ │ ├── stores/ # Auth, Company, Period
|
||||
│ │ └── styles/
|
||||
│ │
|
||||
│ └── config/
|
||||
│ ├── menu.js # Configurație meniu unificat
|
||||
│ └── features.js # Feature flags
|
||||
│
|
||||
├── vite.config.js
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pași Implementare
|
||||
|
||||
### Faza 1: Setup Proiect (0.5 zile)
|
||||
1. Creează directorul `roa2web/`
|
||||
2. Setup `package.json` cu dependencies combinate din ambele apps
|
||||
3. Setup `vite.config.js` cu:
|
||||
- Dual proxy: `/api/reports/*` → `:8001`, `/api/data-entry/*` → `:8003`
|
||||
- Lazy loading chunks configuration
|
||||
- Base path `/`
|
||||
4. Setup `main.js` cu Pinia, PrimeVue, Router
|
||||
|
||||
### Faza 2: Migrare Module (1 zi)
|
||||
1. Copiază views din `reports-app/frontend/src/views/` → `modules/reports/views/`
|
||||
2. Copiază views din `data-entry-app/frontend/src/views/` → `modules/data-entry/views/`
|
||||
3. Copiază stores specifice fiecărui modul
|
||||
4. Creează `ReportsLayout.vue` și `DataEntryLayout.vue` cu error boundaries
|
||||
5. Setup router unificat:
|
||||
```javascript
|
||||
const routes = [
|
||||
{ path: '/login', component: LoginView },
|
||||
{
|
||||
path: '/reports',
|
||||
component: () => import('./modules/reports/ReportsLayout.vue'),
|
||||
children: [
|
||||
{ path: 'dashboard', component: () => import('./modules/reports/views/DashboardView.vue') },
|
||||
{ path: 'invoices', component: () => import('./modules/reports/views/InvoicesView.vue') },
|
||||
// ...
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/data-entry',
|
||||
component: () => import('./modules/data-entry/DataEntryLayout.vue'),
|
||||
children: [
|
||||
{ path: '', component: () => import('./modules/data-entry/views/ReceiptsListView.vue') },
|
||||
{ path: 'create', component: () => import('./modules/data-entry/views/ReceiptCreateView.vue') },
|
||||
]
|
||||
},
|
||||
{ path: '/', redirect: '/reports/dashboard' }
|
||||
]
|
||||
```
|
||||
|
||||
### Faza 3: Izolare și Resilience (0.5 zile)
|
||||
1. Implementează `ErrorBoundary.vue`:
|
||||
```vue
|
||||
<template>
|
||||
<div v-if="error" class="module-error">
|
||||
<h3>⚠️ {{ moduleName }} a întâmpinat o eroare</h3>
|
||||
<p>{{ error.message }}</p>
|
||||
<button @click="retry">Reîncearcă</button>
|
||||
</div>
|
||||
<slot v-else />
|
||||
</template>
|
||||
```
|
||||
2. Separă stores per modul (nu global)
|
||||
3. Adaugă feature flags în `config/features.js`
|
||||
4. Testează izolarea: introduce bug în Reports, verifică că DataEntry funcționează
|
||||
|
||||
### Faza 4: Build & Deploy (0.5 zile)
|
||||
1. Verifică bundle splitting cu `npm run build`:
|
||||
```
|
||||
dist/assets/
|
||||
├── index-[hash].js # Shell + shared (~150KB)
|
||||
├── reports-[hash].js # Reports module (~200KB)
|
||||
└── data-entry-[hash].js # DataEntry module (~100KB)
|
||||
```
|
||||
2. Update IIS web.config pentru SPA routing (toate rutele → index.html)
|
||||
3. Update deployment scripts pentru single app
|
||||
4. Test end-to-end pe server
|
||||
5. Deploy în producție
|
||||
|
||||
---
|
||||
|
||||
## Meniu Unificat
|
||||
|
||||
```javascript
|
||||
// config/menu.js
|
||||
export const menuSections = [
|
||||
{
|
||||
title: 'Rapoarte',
|
||||
items: [
|
||||
{ to: '/reports/dashboard', icon: 'pi pi-home', label: 'Dashboard' },
|
||||
{ to: '/reports/invoices', icon: 'pi pi-file', label: 'Facturi' },
|
||||
{ to: '/reports/bank-cash', icon: 'pi pi-money-bill', label: 'Casa și Banca' },
|
||||
{ to: '/reports/trial-balance', icon: 'pi pi-calculator', label: 'Balanță' },
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Introduceri Date',
|
||||
items: [
|
||||
{ to: '/data-entry', icon: 'pi pi-list', label: 'Lista Bonuri' },
|
||||
{ to: '/data-entry/create', icon: 'pi pi-plus', label: 'Bon Nou' },
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Sistem',
|
||||
items: [
|
||||
{ to: '/reports/telegram', icon: 'pi pi-telegram', label: 'Telegram' },
|
||||
{ to: '/reports/cache-stats', icon: 'pi pi-chart-bar', label: 'Cache Stats' },
|
||||
]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fișiere de Referință
|
||||
|
||||
### Fișiere Existente (sursă pentru copiere)
|
||||
- `reports-app/frontend/src/views/*.vue` - Views Reports
|
||||
- `reports-app/frontend/src/stores/*.js` - Stores Reports
|
||||
- `reports-app/frontend/src/services/api.js` - API service Reports
|
||||
- `data-entry-app/frontend/src/views/*.vue` - Views DataEntry
|
||||
- `data-entry-app/frontend/src/stores/*.js` - Stores DataEntry
|
||||
- `data-entry-app/frontend/src/services/api.js` - API service DataEntry
|
||||
- `shared/frontend/components/` - Componente shared (AppHeader, SlideMenu, etc.)
|
||||
- `shared/frontend/stores/` - Stores shared (auth, companies, accountingPeriod)
|
||||
|
||||
### Configurații de Referință
|
||||
- `reports-app/frontend/vite.config.js` - Pentru proxy și build config
|
||||
- `reports-app/frontend/package.json` - Pentru dependencies
|
||||
- `data-entry-app/frontend/vite.config.js` - Pentru proxy config
|
||||
- `data-entry-app/frontend/package.json` - Pentru dependencies
|
||||
|
||||
---
|
||||
|
||||
## URL-uri Finale
|
||||
|
||||
| Path | Descriere |
|
||||
|------|-----------|
|
||||
| `/` | Redirect la `/reports/dashboard` |
|
||||
| `/login` | Pagină login |
|
||||
| `/reports/dashboard` | Dashboard principal |
|
||||
| `/reports/invoices` | Facturi |
|
||||
| `/reports/bank-cash` | Casa și Banca |
|
||||
| `/reports/trial-balance` | Balanță de Verificare |
|
||||
| `/reports/telegram` | Telegram Bot |
|
||||
| `/reports/cache-stats` | Statistici Cache |
|
||||
| `/data-entry` | Lista Bonuri |
|
||||
| `/data-entry/create` | Bon Nou |
|
||||
| `/data-entry/:id` | Detalii Bon |
|
||||
| `/data-entry/:id/edit` | Editare Bon |
|
||||
|
||||
---
|
||||
|
||||
## Note Importante
|
||||
|
||||
1. **Backend-urile rămân separate** - port 8001 (Reports) și port 8003 (DataEntry)
|
||||
2. **IIS proxy routing** - trebuie configurat pentru a ruta API calls corect
|
||||
3. **Error Boundaries** - critice pentru izolarea modulelor
|
||||
4. **Lazy Loading** - asigură bundle splitting corect
|
||||
5. **Feature flags** - permit dezactivarea unui modul fără redeploy
|
||||
|
||||
---
|
||||
|
||||
## Handover Notes
|
||||
|
||||
Această implementare va înlocui cele 2 aplicații separate cu o aplicație unificată.
|
||||
După implementare, directoarele `reports-app/frontend/` și `data-entry-app/frontend/`
|
||||
pot fi arhivate/șterse, păstrând doar `unified-app/`.
|
||||
|
||||
Backend-urile rămân neschimbate în `reports-app/backend/` și `data-entry-app/backend/`.
|
||||
2312
data-entry-app/docs/igiena 14 decembrie five-holding.pdf
Normal file
2312
data-entry-app/docs/igiena 14 decembrie five-holding.pdf
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data-entry-app/docs/rechizite 12 decembrie pictus.pdf
Normal file
BIN
data-entry-app/docs/rechizite 12 decembrie pictus.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user