diff --git a/.claude/commands/validate.md b/.claude/commands/validate.md
index 84532b6..4c7bfc8 100644
--- a/.claude/commands/validate.md
+++ b/.claude/commands/validate.md
@@ -18,7 +18,7 @@ Comprehensive validation that tests everything in the ROA2WEB codebase. This com
### Test Configuration
- **Company ID**: 110 (MARIUSM_AUTO) - has complete Oracle schema
- **Credentials**: `MARIUS M` / `123`
-- **Backend Tests**: ~36 Oracle real tests in `reports-app/backend/tests/`
+- **Backend Tests**: ~36 Oracle real tests in `backend/tests/`
- **Telegram Bot Tests**: Pure tests + Integration tests (mock tests removed)
---
@@ -32,7 +32,7 @@ echo "===================="
echo ""
echo "📝 Frontend Linting..."
-cd reports-app/frontend
+cd src
npm run lint
cd ../..
echo "✅ Frontend linting passed"
@@ -45,7 +45,7 @@ echo "📝 Python Code Quality Checks..."
# Backend
echo " → Checking backend code..."
-cd reports-app/backend
+cd backend
if [ -d "venv" ]; then
source venv/bin/activate
python -m flake8 app/ --count --select=E9,F63,F7,F82 --show-source --statistics || echo "⚠️ Backend has critical errors"
@@ -58,7 +58,7 @@ cd ../..
# Telegram Bot
echo " → Checking telegram bot code..."
-cd reports-app/telegram-bot
+cd backend/modules/telegram
if [ -d "venv" ]; then
source venv/bin/activate
python -m flake8 app/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics || echo "⚠️ Telegram bot has critical errors"
@@ -93,7 +93,7 @@ echo "========================="
echo ""
echo "📝 Frontend Type Checking (ESLint with type checking)..."
-cd reports-app/frontend
+cd src
# ESLint already performs basic type checking for JavaScript
npm run lint -- --quiet
cd ../..
@@ -106,7 +106,7 @@ echo ""
echo "📝 Python Type Hints (Optional)..."
if command -v mypy >/dev/null 2>&1; then
echo " → Checking backend..."
- cd reports-app/backend
+ cd backend
if [ -d "venv" ]; then
source venv/bin/activate
mypy app/ --ignore-missing-imports --no-strict-optional || echo "⚠️ Backend type hints have issues"
@@ -115,7 +115,7 @@ if command -v mypy >/dev/null 2>&1; then
cd ../..
echo " → Checking telegram bot..."
- cd reports-app/telegram-bot
+ cd backend/modules/telegram
if [ -d "venv" ]; then
source venv/bin/activate
mypy app/ --ignore-missing-imports --no-strict-optional || echo "⚠️ Telegram bot type hints have issues"
@@ -139,7 +139,7 @@ echo "=========================="
echo ""
echo "📝 Frontend Code Formatting (Prettier)..."
-cd reports-app/frontend
+cd src
npm run format -- --check || echo "⚠️ Some files need formatting (run: npm run format)"
cd ../..
echo "✅ Frontend formatting checked"
@@ -151,10 +151,10 @@ echo ""
echo "📝 Python Code Formatting (Black)..."
if command -v black >/dev/null 2>&1; then
echo " → Checking backend..."
- black --check reports-app/backend/app/ || echo "⚠️ Backend needs formatting (run: black reports-app/backend/app/)"
+ black --check backend/app/ || echo "⚠️ Backend needs formatting (run: black backend/app/)"
echo " → Checking telegram bot..."
- black --check reports-app/telegram-bot/app/ reports-app/telegram-bot/tests/ || echo "⚠️ Telegram bot needs formatting (run: black reports-app/telegram-bot/)"
+ black --check backend/modules/telegram/app/ backend/modules/telegram/tests/ || echo "⚠️ Telegram bot needs formatting (run: black backend/modules/telegram/)"
echo " → Checking shared modules..."
black --check shared/ || echo "⚠️ Shared modules need formatting (run: black shared/)"
@@ -205,7 +205,7 @@ echo ""
```bash
echo "📝 Backend Oracle Real Tests..."
echo " → Testing backend services, API endpoints, and cache system..."
-cd reports-app/backend
+cd backend
if [ ! -d "venv" ]; then
echo "⚠️ Backend venv not found - creating..."
@@ -234,7 +234,7 @@ echo ""
### Telegram Bot Unit Tests (Pure - No Backend Required)
```bash
echo "📝 Telegram Bot Unit Tests (Pure)..."
-cd reports-app/telegram-bot
+cd backend/modules/telegram
if [ ! -d "venv" ]; then
echo "⚠️ Telegram bot venv not found - creating..."
@@ -262,7 +262,7 @@ echo ""
```bash
echo "📝 Telegram Bot Integration Tests..."
-cd reports-app/telegram-bot
+cd backend/modules/telegram
source venv/bin/activate
@@ -280,7 +280,7 @@ echo ""
### Frontend Unit Tests (Playwright - E2E with API Mocking)
```bash
echo "📝 Frontend Unit/E2E Tests (Playwright with API mocking)..."
-cd reports-app/frontend
+cd src
# Ensure dependencies are installed
if [ ! -d "node_modules" ]; then
@@ -720,7 +720,7 @@ echo "========================================================"
echo " → Running Playwright integration tests against real backend..."
-cd reports-app/frontend
+cd src
# Create integration test configuration for real backend
cat > playwright.integration.config.js << 'EOF'
@@ -979,9 +979,9 @@ echo "════════════════════════
- **Test Credentials**: `MARIUS M` / `123`
- **API Structure**: All endpoints use query params (`?company=110`), not path params
- **Test Structure**:
- - Backend: `reports-app/backend/tests/` (~36 Oracle real tests)
- - Telegram Bot Pure: `reports-app/telegram-bot/tests/` (~77 pure tests)
- - Telegram Bot Integration: `reports-app/telegram-bot/tests/` (~25 real tests, marked `@pytest.mark.integration`)
+ - Backend: `backend/tests/` (~36 Oracle real tests)
+ - Telegram Bot Pure: `backend/modules/telegram/tests/` (~77 pure tests)
+ - Telegram Bot Integration: `backend/modules/telegram/tests/` (~25 real tests, marked `@pytest.mark.integration`)
## Quick Run
diff --git a/.claude/rules/backend-patterns.md b/.claude/rules/backend-patterns.md
index e2d6495..4be804e 100644
--- a/.claude/rules/backend-patterns.md
+++ b/.claude/rules/backend-patterns.md
@@ -1,5 +1,5 @@
---
-paths: {reports-app,data-entry-app}/backend/**/*.py
+paths: backend/modules/**/*.py
---
# Backend Patterns
@@ -19,7 +19,7 @@ app.include_router(companies_router, prefix="/api/companies")
- Schema lookup: `SELECT SCHEMA FROM CONTAFIN_ORACLE.V_NOM_FIRME`
- Company access: Join V_NOM_FIRME with VDEF_UTIL_FIRME
-## Caching (reports-app)
+## Caching (Reports Module)
- Use `@cached` decorator from `app/cache/decorators`
- Place logic in services, not routers
- Cache schema lookups (24h TTL)
diff --git a/.claude/rules/css-design-system.md b/.claude/rules/css-design-system.md
index 58b970f..99f8622 100644
--- a/.claude/rules/css-design-system.md
+++ b/.claude/rules/css-design-system.md
@@ -1,5 +1,5 @@
---
-paths: {reports-app,data-entry-app}/frontend/**/*.{vue,css}
+paths: src/modules/**/*.{vue,css}
---
# CSS Design System Rules
diff --git a/.claude/rules/frontend-stores.md b/.claude/rules/frontend-stores.md
index 957f32f..a3b42a5 100644
--- a/.claude/rules/frontend-stores.md
+++ b/.claude/rules/frontend-stores.md
@@ -1,5 +1,5 @@
---
-paths: {reports-app,data-entry-app}/frontend/src/stores/**/*.js
+paths: src/modules/**/stores/**/*.js
---
# Frontend Store Rules
diff --git a/CLAUDE.md b/CLAUDE.md
index 1ccb9ab..713cee3 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -399,6 +399,7 @@ const response = await api.get('/endpoint');
### Deployment
- `deployment/windows/README.md` - Windows deployment quick start
- `deployment/windows/docs/WINDOWS_DEPLOYMENT.md` - Complete Windows guide
+- **`deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md`** - ⚠️ **PRODUCTION ARCHITECTURE** - 2-tier IIS setup with public gateway
- `deployment/windows/docs/TELEGRAM_BOT_TROUBLESHOOTING.md` - Bot troubleshooting
### Troubleshooting
diff --git a/DIAGNOSIS-2025-12-30.md b/DIAGNOSIS-2025-12-30.md
new file mode 100644
index 0000000..68978dc
--- /dev/null
+++ b/DIAGNOSIS-2025-12-30.md
@@ -0,0 +1,378 @@
+# ROA2WEB Production Deployment Issue - Diagnostic Report
+
+**Date**: 2025-12-30
+**Environment**: Windows Production (roa2web.romfast.ro)
+**Issue**: 404 errors on API calls after deployment
+
+---
+
+## Summary
+
+Frontend loads successfully but all API calls return **404 Not Found** errors:
+- `POST /roa2web/api/auth/login` → 404
+- `GET /roa2web/api/companies` → 404
+
+Browser console shows:
+```
+POST https://roa2web.romfast.ro/roa2web/api/auth/login 404 (Not Found)
+```
+
+---
+
+## Architecture Overview
+
+**2-Tier IIS Deployment**:
+
+```
+Internet → Public IIS (10.0.20.122 - roa2web.romfast.ro)
+ ↓ HTTPS reverse proxy
+ Internal IIS (10.0.20.36 - application server)
+ ↓ API proxy to localhost
+ Backend Service (localhost:8000 on 10.0.20.36)
+ ↓
+ Oracle Database
+```
+
+### Verified Components
+
+✅ **Public IIS** (10.0.20.122 - roa2web.romfast.ro):
+- ✅ web.config correctly proxies all requests to `https://10.0.20.36/{R:1}`
+- ✅ Forwards headers: `X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Real-IP`
+- ✅ Configuration verified - THIS SERVER IS CORRECT
+
+✅ **Frontend** (10.0.20.36):
+- Built with `base: '/roa2web/'` (correct for IIS sub-application)
+- API calls use `baseURL: '/roa2web/api'` (correct)
+- Static files load successfully
+
+❌ **Internal IIS** (10.0.20.36) - **PROBLEMA ESTE AICI**:
+- **CRITICAL**: web.config lipsește SAU nu este configurat corect
+- **MUST**: Trebuie să facă proxy de la `/roa2web/api/*` către `http://localhost:8000/api/*`
+- **Location**: `C:\inetpub\wwwroot\roa2web\web.config` (pe serverul 10.0.20.36)
+
+❓ **Backend Service** (pe 10.0.20.36):
+- **UNKNOWN**: Need to verify service is running
+- Should be accessible at `http://localhost:8000/health` (de pe 10.0.20.36)
+
+---
+
+## Root Cause Analysis
+
+Based on Playwright testing, the issue is most likely:
+
+### Primary Suspect: Internal Server web.config
+
+The internal server's web.config **MUST** handle the `/roa2web/` prefix correctly.
+
+**WRONG Configuration** (causes 404):
+```xml
+
+ ❌ Missing roa2web prefix!
+
+
+```
+
+**CORRECT Configuration**:
+```xml
+
+ ✅ Includes roa2web prefix
+
+
+```
+
+**Why**: Requests arrive at internal server as `/roa2web/api/auth/login` (NOT `/api/auth/login`), because the public server preserves the full path when proxying.
+
+### Secondary Suspects
+
+1. **Backend service not running**
+ - Check: `Get-Service ROA2WEB-Backend`
+
+2. **IIS ARR not enabled**
+ - Check: `Get-WebConfigurationProperty -PSPath "MACHINE/WEBROOT/APPHOST" -Filter "system.webServer/proxy" -Name "enabled"`
+
+3. **IIS sub-application misconfigured**
+ - Frontend should be deployed at IIS path `/roa2web`, not root
+
+---
+
+## Diagnostic Steps
+
+### Step 1: Check Backend Service (on 10.0.20.36)
+
+```powershell
+# Check service status
+Get-Service ROA2WEB-Backend
+
+# If stopped, start it
+Start-Service ROA2WEB-Backend
+
+# Test backend directly
+Invoke-WebRequest http://localhost:8000/health
+```
+
+**Expected Output**:
+```json
+{"status": "healthy", "version": "..."}
+```
+
+### Step 2: Check Internal IIS web.config (on 10.0.20.36)
+
+```powershell
+# View current web.config
+Get-Content C:\inetpub\wwwroot\roa2web\web.config
+
+# OR if frontend is in subdirectory:
+Get-Content C:\inetpub\wwwroot\roa2web\frontend\web.config
+```
+
+**Verify these rules**:
+- `` (NOT `^api/(.*)`)
+- `` (NOT `^uploads/(.*)`)
+- `` for SPA fallback
+
+### Step 3: Check IIS ARR (on 10.0.20.36)
+
+```powershell
+# Check if ARR is installed
+Get-WindowsFeature -Name Web-ARR
+
+# Check if proxy is enabled
+Get-WebConfigurationProperty -PSPath "MACHINE/WEBROOT/APPHOST" `
+ -Filter "system.webServer/proxy" `
+ -Name "enabled"
+```
+
+**Expected**: `enabled` should be `True`
+
+### Step 4: Test Internal IIS Proxy (on 10.0.20.36)
+
+```powershell
+# Test API endpoint through IIS
+Invoke-WebRequest https://localhost/roa2web/api/health
+
+# Should proxy to backend and return response
+```
+
+### Step 5: Check IIS Application Structure (on 10.0.20.36)
+
+```powershell
+# List IIS applications
+Get-WebApplication -Site "Default Web Site" | Format-Table Path, PhysicalPath
+
+# Should show:
+# /roa2web -> C:\inetpub\wwwroot\roa2web\
+```
+
+---
+
+## Fix Recommendations
+
+### Fix #1: Update Internal Server web.config
+
+**Server**: 10.0.20.36 (internal application server)
+**Location**: `C:\inetpub\wwwroot\roa2web\web.config`
+
+**IMPORTANT**: Acest web.config este pe serverul 10.0.20.36, NU pe 10.0.20.122!
+
+**Required Configuration**:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**Deployment**:
+
+```powershell
+# ⚠️ IMPORTANT: Rulează aceste comenzi pe serverul 10.0.20.36, NU pe 10.0.20.122!
+# Conectează-te la 10.0.20.36 (internal application server)
+
+# Backup current config
+Copy-Item C:\inetpub\wwwroot\roa2web\web.config `
+ C:\inetpub\wwwroot\roa2web\web.config.backup.$(Get-Date -Format 'yyyyMMdd-HHmmss')
+
+# Update web.config with corrected version
+# (copy from repository: public/web.config after updating it)
+
+# Restart IIS
+iisreset
+
+# Test
+Invoke-WebRequest https://localhost/roa2web/api/health
+```
+
+### Fix #2: Ensure Backend Service is Running
+
+```powershell
+# On internal server (10.0.20.36)
+
+# Check service
+Get-Service ROA2WEB-Backend
+
+# If stopped
+Start-Service ROA2WEB-Backend
+
+# View startup logs
+Get-Content C:\inetpub\wwwroot\roa2web\logs\backend-stdout.log -Tail 50
+
+# Check for errors
+Get-Content C:\inetpub\wwwroot\roa2web\logs\backend-stderr.log -Tail 50
+```
+
+### Fix #3: Enable IIS ARR (if not enabled)
+
+```powershell
+# On internal server (10.0.20.36)
+
+# Enable proxy
+Set-WebConfigurationProperty -PSPath "MACHINE/WEBROOT/APPHOST" `
+ -Filter "system.webServer/proxy" `
+ -Name "enabled" `
+ -Value "True"
+
+# Restart IIS
+iisreset
+```
+
+---
+
+## Verification Steps (After Fix)
+
+### 1. Backend Health Check (Direct)
+
+```powershell
+# On 10.0.20.36
+Invoke-WebRequest http://localhost:8000/health
+```
+
+**Expected**: `200 OK` with JSON response
+
+### 2. Internal IIS Proxy Test
+
+```powershell
+# On 10.0.20.36
+Invoke-WebRequest https://localhost/roa2web/api/health
+```
+
+**Expected**: `200 OK` (proxied from backend)
+
+### 3. Public Access Test
+
+```powershell
+# From any client
+Invoke-WebRequest https://roa2web.romfast.ro/roa2web/
+```
+
+**Expected**: Frontend loads (HTML page)
+
+### 4. Login Flow Test (Playwright)
+
+Use Playwright to test complete login flow:
+
+```bash
+# On development machine
+cd /mnt/e/proiecte/roa2web
+npx playwright test --headed --project=chromium tests/login.spec.js
+```
+
+**Expected**: Login succeeds without 404 errors
+
+---
+
+## Prevention
+
+To prevent this issue in future deployments:
+
+1. **Use Correct web.config Template**
+ - Repository should have separate web.config templates:
+ - `public/web.config` - for internal server (with `/roa2web/` prefix)
+ - `deployment/windows/config/web.config` - same as above
+
+2. **Automated Deployment Script**
+ - PowerShell script should validate web.config before deployment
+ - Check for required URL patterns: `^roa2web/api/`, `^roa2web/uploads/`
+
+3. **Deployment Checklist**
+ - Add to `deployment/windows/docs/DEPLOYMENT-CHECKLIST.md`:
+ - [ ] Verify web.config includes `/roa2web/` prefix in match rules
+ - [ ] Test backend: `Invoke-WebRequest http://localhost:8000/health`
+ - [ ] Test IIS proxy: `Invoke-WebRequest https://localhost/roa2web/api/health`
+ - [ ] Test public access: `Invoke-WebRequest https://roa2web.romfast.ro/roa2web/`
+
+4. **Monitoring**
+ - Add health check endpoint monitoring
+ - Alert if backend service stops
+ - Monitor IIS logs for 404/502 errors
+
+---
+
+## Next Steps
+
+1. ✅ **Immediate**: Check internal server web.config (on 10.0.20.36)
+2. ✅ **Immediate**: Verify backend service is running
+3. ✅ **Immediate**: Apply Fix #1 if web.config is incorrect
+4. ⏭️ **After Fix**: Run verification steps
+5. ⏭️ **After Fix**: Update repository web.config template
+6. ⏭️ **Future**: Add automated deployment validation
+
+---
+
+## Documentation Created
+
+- ✅ `deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md` - Complete 2-tier architecture guide
+- ✅ Updated `CLAUDE.md` with deployment documentation reference
+- ✅ This diagnostic report: `DIAGNOSIS-2025-12-30.md`
+
+---
+
+## Contact Information
+
+**Issue Reported By**: User via Playwright testing
+**Diagnosed By**: Claude Code
+**Date**: 2025-12-30
+**Severity**: HIGH (blocking production login)
+**Priority**: IMMEDIATE
+
+---
+
+*For detailed architecture documentation, see: `deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md`*
diff --git a/DOKPLOY_DEPLOYMENT.md b/DOKPLOY_DEPLOYMENT.md
index c3c995c..78231f0 100644
--- a/DOKPLOY_DEPLOYMENT.md
+++ b/DOKPLOY_DEPLOYMENT.md
@@ -749,8 +749,8 @@ a. **Clear Build Cache**:
b. **Check Dockerfile**:
```bash
# Validate Dockerfiles locally
-docker build -t test-backend ./reports-app/backend
-docker build -t test-frontend ./reports-app/frontend
+docker build -t test-backend ./backend
+docker build -t test-frontend ./src
docker build -t test-tunnel ./ssh-tunnel
```
diff --git a/README.md b/README.md
index 8681eb4..da2dcca 100644
--- a/README.md
+++ b/README.md
@@ -113,7 +113,7 @@ This starts SSH tunnel, unified backend (port 8001), and frontend (port 3000).
**For detailed development commands, testing procedures, and troubleshooting**: See `CLAUDE.md` and component-specific READMEs:
- Backend: `backend/ modules and CLAUDE.md`
- Frontend: `src/ and docs/MONOLITH_ARCHITECTURE.md` & `E2E testing guide in docs/`
-- Telegram Bot: `reports-app/telegram-bot/README.md`
+- Telegram Bot: `backend/modules/telegram/README.md`
**Key Commands**:
```bash
@@ -269,7 +269,7 @@ All endpoints prefixed with `/api`:
Copy `.env.example` to `.env` in each microservice and configure:
-### Backend (`reports-app/backend/.env`)
+### Backend (`backend/.env`)
```bash
# Oracle Database (through SSH tunnel)
ORACLE_USER=your_username
@@ -284,7 +284,7 @@ JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=30
```
-### Telegram Bot (`reports-app/telegram-bot/.env`)
+### Telegram Bot (`backend/modules/telegram/.env`)
```bash
# Telegram Bot Token
TELEGRAM_BOT_TOKEN=your_bot_token
@@ -308,8 +308,8 @@ BACKEND_API_URL=http://localhost:8001
- `backend/ modules and CLAUDE.md` - Backend specifics
- `src/ and docs/MONOLITH_ARCHITECTURE.md` - Frontend guide
- `E2E testing guide in docs/` - Frontend testing
-- `reports-app/telegram-bot/README.md` - Telegram bot guide
-- `reports-app/telegram-bot/TELEGRAM_COMMANDS.md` - Bot commands
+- `backend/modules/telegram/README.md` - Telegram bot guide
+- `backend/modules/telegram/TELEGRAM_COMMANDS.md` - Bot commands
### Frontend Styling & CSS
- `docs/ONBOARDING_CSS.md` - CSS system onboarding guide (start here!)
diff --git a/deployment/windows/config/README-WEB-CONFIG.md b/deployment/windows/config/README-WEB-CONFIG.md
new file mode 100644
index 0000000..1f4b3cd
--- /dev/null
+++ b/deployment/windows/config/README-WEB-CONFIG.md
@@ -0,0 +1,240 @@
+# web.config Files - Which Goes Where?
+
+## ⚠️ IMPORTANT - Read Before Deployment!
+
+ROA2WEB uses a **2-tier IIS architecture** with **2 different web.config files** for **2 different servers**.
+
+---
+
+## Architecture Overview
+
+```
+Internet
+ ↓
+Public Server (10.0.20.122) - roa2web.romfast.ro
+ ↓ HTTPS reverse proxy
+Internal Server (10.0.20.36) - application host
+ ↓ API proxy to localhost
+Backend Service (localhost:8000 on 10.0.20.36)
+```
+
+---
+
+## File Mapping
+
+### File: `web.config.10.0.20.122-PUBLIC`
+
+**Server**: 10.0.20.122 (Public IIS - roa2web.romfast.ro)
+**Role**: Public gateway, reverse proxy to internal server
+
+**Purpose**:
+- Proxies ALL requests to `https://10.0.20.36/{REQUEST_PATH}`
+- Sets forwarding headers (`X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Real-IP`)
+- Redirects root `/` to `/roa2web/`
+
+**Key Rule**:
+```xml
+
+
+```
+
+**Deployment Location**:
+```
+10.0.20.122:
+ C:\inetpub\wwwroot\[ROOT]\web.config
+```
+
+---
+
+### File: `web.config.10.0.20.36-INTERNAL`
+
+**Server**: 10.0.20.36 (Internal IIS - application host)
+**Role**: Serves frontend, proxies API to localhost backend
+
+**Purpose**:
+- Serves Vue.js frontend static files
+- Proxies `/roa2web/api/*` to `http://localhost:8000/api/*`
+- Proxies `/roa2web/uploads/*` to `http://localhost:8000/uploads/*`
+- SPA fallback for client-side routing
+
+**Key Rules**:
+```xml
+
+
+
+
+
+
+
+
+```
+
+**Deployment Location**:
+```
+10.0.20.36:
+ C:\inetpub\wwwroot\roa2web\web.config
+```
+
+**Note**: This file is also in `public/web.config` (repository root) and is automatically copied to `dist/` during Vite build.
+
+---
+
+## Deployment Checklist
+
+### ✅ Public Server (10.0.20.122)
+
+```powershell
+# Copy public server config
+Copy-Item deployment/windows/config/web.config.10.0.20.122-PUBLIC `
+ C:\inetpub\wwwroot\[ROOT]\web.config
+
+# Verify
+Get-Content C:\inetpub\wwwroot\[ROOT]\web.config | Select-String "10.0.20.36"
+```
+
+**Expected**: Should see `url="https://10.0.20.36/{R:1}"`
+
+### ✅ Internal Server (10.0.20.36)
+
+**Option A: From built dist/ (recommended)**:
+```powershell
+# After building frontend with `npm run build`
+# web.config is automatically in dist/
+
+# Deploy entire dist/ folder
+Copy-Item dist\* C:\inetpub\wwwroot\roa2web\ -Recurse -Force
+```
+
+**Option B: Manual copy**:
+```powershell
+# Copy internal server config
+Copy-Item deployment/windows/config/web.config.10.0.20.36-INTERNAL `
+ C:\inetpub\wwwroot\roa2web\web.config
+
+# Verify
+Get-Content C:\inetpub\wwwroot\roa2web\web.config | Select-String "roa2web/api"
+```
+
+**Expected**: Should see `url="^roa2web/api/(.*)"` and `url="http://localhost:8000/api/{R:1}"`
+
+---
+
+## Verification
+
+### Test Public Server (10.0.20.122)
+
+```powershell
+# Should proxy to internal server
+Invoke-WebRequest https://roa2web.romfast.ro/roa2web/ -UseBasicParsing
+
+# Check response headers
+(Invoke-WebRequest https://roa2web.romfast.ro/roa2web/).Headers
+```
+
+**Expected**: Request should be proxied to 10.0.20.36
+
+### Test Internal Server (10.0.20.36)
+
+```powershell
+# Test backend directly
+Invoke-WebRequest http://localhost:8000/health
+
+# Test through IIS proxy
+Invoke-WebRequest https://localhost/roa2web/api/health
+
+# Test frontend
+Invoke-WebRequest https://localhost/roa2web/
+```
+
+**Expected**: All should return 200 OK
+
+---
+
+## Common Mistakes ❌
+
+### ❌ WRONG: Using internal config on public server
+
+```xml
+
+
+
+```
+
+**Problem**: Public server doesn't have backend on localhost:8000
+
+### ❌ WRONG: Using public config on internal server
+
+```xml
+
+
+
+```
+
+**Problem**: Creates infinite redirect loop
+
+### ❌ WRONG: Missing /roa2web/ prefix on internal server
+
+```xml
+
+
+
+```
+
+**Problem**: Requests come as `/roa2web/api/...` from public server, so `^api/` won't match
+
+---
+
+## Troubleshooting
+
+### Issue: 404 on API calls
+
+**Symptom**: Frontend loads but API returns 404
+
+**Check**: web.config on 10.0.20.36
+
+```powershell
+# On 10.0.20.36
+Get-Content C:\inetpub\wwwroot\roa2web\web.config | Select-String "roa2web/api"
+```
+
+**Fix**: Update to correct internal server config (see above)
+
+### Issue: Infinite redirect loop
+
+**Symptom**: Browser shows "Too many redirects"
+
+**Check**: Verify you didn't put public config on internal server
+
+### Issue: Backend not reachable
+
+**Symptom**: 502 Bad Gateway on API calls
+
+**Check**: Backend service on 10.0.20.36
+
+```powershell
+# On 10.0.20.36
+Get-Service ROA2WEB-Backend
+Invoke-WebRequest http://localhost:8000/health
+```
+
+---
+
+## Quick Reference
+
+| Server | IP | Config File | Key Pattern | Proxies To |
+|--------|----|----|-------------|------------|
+| **Public** | 10.0.20.122 | `web.config.10.0.20.122-PUBLIC` | `url="(.*)"` | `https://10.0.20.36/{R:1}` |
+| **Internal** | 10.0.20.36 | `web.config.10.0.20.36-INTERNAL` | `url="^roa2web/api/(.*)"` | `http://localhost:8000/api/{R:1}` |
+
+---
+
+## Documentation
+
+For complete architecture details, see:
+- `deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md`
+- `DIAGNOSIS-2025-12-30.md`
+
+---
+
+*Last Updated: 2025-12-30*
+*ROA2WEB Deployment Configuration Guide*
diff --git a/deployment/windows/config/web.config.10.0.20.122-PUBLIC b/deployment/windows/config/web.config.10.0.20.122-PUBLIC
new file mode 100644
index 0000000..f408ac3
--- /dev/null
+++ b/deployment/windows/config/web.config.10.0.20.122-PUBLIC
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/deployment/windows/config/web.config.10.0.20.36-INTERNAL b/deployment/windows/config/web.config.10.0.20.36-INTERNAL
new file mode 100644
index 0000000..03ff98f
--- /dev/null
+++ b/deployment/windows/config/web.config.10.0.20.36-INTERNAL
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/deployment/windows/docs/TELEGRAM_BOT_DEPLOYMENT.md b/deployment/windows/docs/TELEGRAM_BOT_DEPLOYMENT.md
index bb707fe..d70e714 100644
--- a/deployment/windows/docs/TELEGRAM_BOT_DEPLOYMENT.md
+++ b/deployment/windows/docs/TELEGRAM_BOT_DEPLOYMENT.md
@@ -826,7 +826,7 @@ CREATE TABLE telegram_sessions (
## Support
**Documentation**:
-- Project README: `/mnt/e/proiecte/roa2web/roa2web/reports-app/telegram-bot/README.md`
+- Project README: `/mnt/e/proiecte/roa2web/roa2web/backend/modules/telegram/README.md`
- Progress Tracker: `/mnt/e/proiecte/roa2web/roa2web/development/TELEGRAM_BOT_PROGRESS.md`
- Production Deployment Plan: `/mnt/e/proiecte/roa2web/roa2web/development/TELEGRAM_BOT_PRODUCTION_DEPLOYMENT.md`
diff --git a/deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md b/deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md
new file mode 100644
index 0000000..7837a65
--- /dev/null
+++ b/deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md
@@ -0,0 +1,435 @@
+# Two-Tier IIS Deployment Architecture
+
+## Overview
+
+ROA2WEB uses a **2-tier IIS architecture** for production deployment:
+
+```
+Internet
+ ↓
+Public IIS Server (roa2web.romfast.ro)
+ ↓ HTTPS reverse proxy
+Internal IIS Server (10.0.20.36)
+ ↓ API proxy
+Backend Service (localhost:8000)
+ ↓
+Oracle Database
+```
+
+---
+
+## Architecture Components
+
+### Tier 1: Public IIS Server (Edge/Gateway)
+
+**Hostname**: `roa2web.romfast.ro`
+**IP Address**: `10.0.20.122`
+**Role**: Public-facing reverse proxy
+**Location**: DMZ/Public network
+
+**Responsibilities**:
+- SSL/TLS termination (HTTPS)
+- Reverse proxy to internal server
+- Security headers
+- Public DNS endpoint
+
+**Configuration** (`web.config` pe serverul 10.0.20.122):
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**Key Features**:
+- Root redirect: `https://roa2web.romfast.ro/` → `https://roa2web.romfast.ro/roa2web/`
+- All requests proxied to: `https://10.0.20.36/{REQUEST_PATH}`
+- Forwards client IP and protocol headers
+
+---
+
+### Tier 2: Internal IIS Server (Application Server)
+
+**IP Address**: `10.0.20.36`
+**Role**: Application host + API proxy
+**Location**: Internal network
+
+**Responsibilities**:
+- Serve Vue.js frontend static files
+- Proxy API requests to backend service
+- Handle uploads
+- IIS sub-application at `/roa2web`
+
+**Configuration** (`web.config` pe serverul 10.0.20.36 - `C:\inetpub\wwwroot\roa2web\web.config`):
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**CRITICAL**: The internal server web.config must handle the `/roa2web/` prefix since requests arrive as:
+- `https://10.0.20.36/roa2web/api/auth/login` (NOT `/api/auth/login`)
+
+---
+
+### Backend Service (FastAPI)
+
+**Host**: `localhost` (internal server)
+**Port**: `8000`
+**Type**: Windows Service (NSSM)
+**Name**: `ROA2WEB-Backend`
+
+**Configuration** (`.env`):
+```env
+HOST=127.0.0.1
+PORT=8000
+ENVIRONMENT=production
+```
+
+**Base Path**: `/api` (NOT `/roa2web/api`)
+
+The backend serves:
+- `/api/auth/login`
+- `/api/companies`
+- `/api/calendar`
+- etc.
+
+---
+
+## Request Flow Example
+
+### Login Request Flow
+
+1. **Client Browser** → `POST https://roa2web.romfast.ro/roa2web/api/auth/login`
+
+2. **Public IIS** (roa2web.romfast.ro):
+ - Receives: `/roa2web/api/auth/login`
+ - Proxies to: `https://10.0.20.36/roa2web/api/auth/login`
+ - Sets headers: `X-Forwarded-Proto: https`, `X-Forwarded-Host: roa2web.romfast.ro`
+
+3. **Internal IIS** (10.0.20.36):
+ - Receives: `/roa2web/api/auth/login`
+ - Matches rule: `^roa2web/api/(.*)`
+ - Extracts: `auth/login`
+ - Proxies to: `http://localhost:8000/api/auth/login`
+
+4. **Backend Service** (localhost:8000):
+ - Receives: `/api/auth/login`
+ - Processes request
+ - Returns response
+
+---
+
+## Frontend Configuration
+
+### Vite Build Configuration (`vite.config.js`)
+
+```javascript
+export default defineConfig({
+ // Base path for IIS sub-application
+ base: process.env.NODE_ENV === 'production' ? '/roa2web/' : '/',
+
+ // Development proxy (NOT used in production)
+ server: {
+ proxy: {
+ '/api': {
+ target: 'http://localhost:8000',
+ changeOrigin: true
+ }
+ }
+ }
+})
+```
+
+**IMPORTANT**: In production, `base: '/roa2web/'` ensures:
+- All asset paths: `/roa2web/assets/...`
+- Router base: `/roa2web/`
+- API calls: `/roa2web/api/...` (via axios baseURL)
+
+### API Service Configuration (`src/App.vue`)
+
+```javascript
+const authApi = axios.create({
+ baseURL: import.meta.env.BASE_URL + 'api', // Results in: '/roa2web/api'
+ headers: { 'Content-Type': 'application/json' }
+})
+```
+
+---
+
+## Common Issues & Troubleshooting
+
+### Issue: 404 on API calls
+
+**Symptoms**:
+- Frontend loads correctly
+- API calls return 404
+- Browser console: `POST https://roa2web.romfast.ro/roa2web/api/auth/login 404`
+
+**Possible Causes**:
+
+1. **Internal server web.config missing `/roa2web/` prefix in match rules**
+
+ ❌ **WRONG**:
+ ```xml
+
+ ```
+
+ ✅ **CORRECT**:
+ ```xml
+
+ ```
+
+2. **Backend service not running**
+
+ Check on internal server (10.0.20.36):
+ ```powershell
+ Get-Service ROA2WEB-Backend
+ Invoke-WebRequest http://localhost:8000/health
+ ```
+
+3. **IIS ARR not enabled**
+
+ On internal server (10.0.20.36):
+ ```powershell
+ # Install ARR
+ Install-WindowsFeature -Name Web-ARR
+
+ # Enable proxy
+ Set-WebConfigurationProperty -PSPath "MACHINE/WEBROOT/APPHOST" `
+ -Filter "system.webServer/proxy" `
+ -Name "enabled" `
+ -Value "True"
+ ```
+
+4. **IIS sub-application not configured at `/roa2web`**
+
+ The frontend must be deployed as IIS sub-application at path `/roa2web`, NOT as root site.
+
+### Issue: Frontend loads but shows blank page
+
+**Symptoms**:
+- Browser shows white screen
+- Console error: `Failed to load module script`
+- Assets return 404
+
+**Solution**: Check `base` in `vite.config.js` matches IIS sub-application path.
+
+### Issue: CORS errors
+
+**Symptoms**:
+- API calls blocked by CORS policy
+- Console: `Access-Control-Allow-Origin` error
+
+**Solution**: Backend should see requests as same-origin (via IIS proxy), so CORS shouldn't apply. If you see CORS errors, the proxy is misconfigured.
+
+---
+
+## Deployment Checklist
+
+### Public Server (roa2web.romfast.ro)
+
+- [ ] SSL certificate installed and valid
+- [ ] IIS ARR (Application Request Routing) installed
+- [ ] web.config configured with reverse proxy to 10.0.20.36
+- [ ] Server variables enabled in IIS
+- [ ] Firewall allows HTTPS outbound to 10.0.20.36
+
+### Internal Server (10.0.20.36)
+
+- [ ] IIS installed and running
+- [ ] IIS ARR installed
+- [ ] IIS URL Rewrite module installed
+- [ ] Sub-application created at `/roa2web`
+- [ ] Frontend files deployed to `C:\inetpub\wwwroot\roa2web\`
+- [ ] web.config includes `/roa2web/` prefix in match rules
+- [ ] Backend service (ROA2WEB-Backend) running
+- [ ] Backend accessible at `http://localhost:8000/health`
+- [ ] Firewall allows HTTPS inbound from public server
+
+### Backend Service
+
+- [ ] Windows Service created (NSSM)
+- [ ] Service set to auto-start
+- [ ] `.env` configured with correct Oracle credentials
+- [ ] Logs directory exists and writable
+- [ ] Health check returns 200 OK
+
+---
+
+## Testing Procedure
+
+### 1. Test Backend Directly (on 10.0.20.36)
+
+```powershell
+# Health check
+Invoke-WebRequest http://localhost:8000/health
+
+# API test (without auth)
+Invoke-WebRequest http://localhost:8000/api/health
+```
+
+### 2. Test Internal IIS Proxy (on 10.0.20.36)
+
+```powershell
+# Should proxy to backend
+Invoke-WebRequest https://localhost/roa2web/api/health
+
+# Should serve frontend
+Invoke-WebRequest https://localhost/roa2web/
+```
+
+### 3. Test Public Access (from any client)
+
+```powershell
+# Frontend
+Invoke-WebRequest https://roa2web.romfast.ro/roa2web/
+
+# API (will fail without auth, but should return 401 not 404)
+Invoke-WebRequest https://roa2web.romfast.ro/roa2web/api/health
+```
+
+### 4. Test with Playwright (comprehensive)
+
+```bash
+# Use Playwright to test full login flow
+./start-playwright.sh
+```
+
+---
+
+## Monitoring & Logs
+
+### Public Server Logs
+
+```powershell
+# IIS logs
+Get-Content C:\inetpub\logs\LogFiles\W3SVC*\*.log -Tail 50
+
+# Failed Request Tracing (if enabled)
+Get-ChildItem C:\inetpub\logs\FailedReqLogFiles
+```
+
+### Internal Server Logs
+
+```powershell
+# IIS logs
+Get-Content C:\inetpub\logs\LogFiles\W3SVC*\*.log -Tail 50
+
+# Backend service logs
+Get-Content C:\inetpub\wwwroot\roa2web\logs\backend-stdout.log -Tail 50 -Wait
+Get-Content C:\inetpub\wwwroot\roa2web\logs\backend-stderr.log -Tail 50
+```
+
+### Backend Application Logs
+
+```powershell
+# Application log
+Get-Content C:\inetpub\wwwroot\roa2web\backend\logs\app.log -Tail 100
+```
+
+---
+
+## Security Considerations
+
+### SSL/TLS
+
+- Public server handles SSL termination
+- Internal communication can use HTTPS (current) or HTTP (simpler)
+- Certificate management only needed on public server
+
+### Firewall Rules
+
+**Public Server**:
+- Allow inbound: 443 (HTTPS)
+- Allow outbound: 443 to 10.0.20.36
+
+**Internal Server**:
+- Allow inbound: 443 from public server IP only
+- No need to expose port 8000 externally (backend is localhost-only)
+
+### Headers
+
+Public server sets forwarding headers:
+- `X-Forwarded-Proto: https` - Original protocol
+- `X-Forwarded-Host: roa2web.romfast.ro` - Original hostname
+- `X-Real-IP: {CLIENT_IP}` - Client IP address
+
+Backend can use these for logging and security.
+
+---
+
+## Version History
+
+| Version | Date | Changes |
+|---------|------|---------|
+| 1.0.0 | 2025-12-30 | Initial documentation |
+
+---
+
+*Last Updated: 2025-12-30*
+*ROA2WEB Two-Tier IIS Deployment Architecture*
diff --git a/docs/data-entry/ARCHITECTURE.md b/docs/data-entry/ARCHITECTURE.md
index 7df4961..ac768e7 100644
--- a/docs/data-entry/ARCHITECTURE.md
+++ b/docs/data-entry/ARCHITECTURE.md
@@ -24,7 +24,7 @@ Aplicatie separata pentru introducere date in ERP, cu workflow de aprobare si st
### 2. Separare de Reports-App
-**Alegere**: Aplicatie separata in `data-entry-app/`
+**Alegere**: Aplicatie separata in `backend/modules/data_entry/`
**Motivatie**:
- Responsabilitati diferite: reports = read-only, data-entry = write
diff --git a/docs/data-entry/README.md b/docs/data-entry/README.md
index c4b7f00..113e877 100644
--- a/docs/data-entry/README.md
+++ b/docs/data-entry/README.md
@@ -33,7 +33,7 @@ Aplicatie pentru introducere bonuri fiscale cu workflow de aprobare si extragere
#### Backend Setup
```bash
-cd data-entry-app/backend
+cd backend/modules/data_entry/backend
# Create virtual environment
python -m venv venv
@@ -57,7 +57,7 @@ uvicorn app.main:app --reload --port 8003
#### Frontend Setup
```bash
-cd data-entry-app/frontend
+cd backend/modules/data_entry/frontend
# Install dependencies
npm install
@@ -212,7 +212,7 @@ DRAFT → PENDING_REVIEW → APPROVED/REJECTED → (SYNCED in Oracle)
## Project Structure
```
-data-entry-app/
+backend/modules/data_entry/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entry point
@@ -274,7 +274,7 @@ ORACLE_HOST=localhost
ORACLE_PORT=1526
ORACLE_SID=ROA
-# JWT (shared with reports-app)
+# JWT (shared with Reports module)
JWT_SECRET_KEY=your_secret_key
JWT_ALGORITHM=HS256
```
diff --git a/docs/data-entry/REQUIREMENTS.md b/docs/data-entry/REQUIREMENTS.md
index 98028c8..4f8d7e9 100644
--- a/docs/data-entry/REQUIREMENTS.md
+++ b/docs/data-entry/REQUIREMENTS.md
@@ -96,7 +96,7 @@ Preluate din Oracle (read-only):
- Paginare pentru liste > 50 elemente
### Securitate
-- Autentificare JWT (shared cu reports-app)
+- Autentificare JWT (shared cu Reports module)
- Validare MIME type pentru fisiere
- Sanitizare nume fisiere
- Acces bazat pe rol
diff --git a/docs/telegram/README.md b/docs/telegram/README.md
index 1ab2ab7..2792593 100644
--- a/docs/telegram/README.md
+++ b/docs/telegram/README.md
@@ -83,7 +83,7 @@ The bot uses a standalone SQLite database for:
```bash
# Navigate to telegram-bot directory
-cd reports-app/telegram-bot
+cd backend/modules/telegram
# Create virtual environment
python3 -m venv venv
@@ -331,7 +331,7 @@ application.add_handler(CommandHandler("mycommand", my_command))
- **Implementation Summary:** [FAZA1_IMPLEMENTATION_SUMMARY.md](./FAZA1_IMPLEMENTATION_SUMMARY.md)
**Frontend Changes:**
-- `reports-app/frontend/src/views/TelegramView.vue` - Complete UI refactor
+- `src/modules/reports/views/TelegramView.vue` - Complete UI refactor
- Added `qrcode.vue` dependency for QR generation
- Environment variable: `VITE_TELEGRAM_BOT_USERNAME`
diff --git a/docs/telegram/TELEGRAM_BUTTON_INTERFACE_PLAN.md b/docs/telegram/TELEGRAM_BUTTON_INTERFACE_PLAN.md
index 425d9ae..eb30240 100644
--- a/docs/telegram/TELEGRAM_BUTTON_INTERFACE_PLAN.md
+++ b/docs/telegram/TELEGRAM_BUTTON_INTERFACE_PLAN.md
@@ -49,7 +49,7 @@ Transformarea Telegram bot ROA2WEB dintr-o interfață bazată pe comenzi text
### Structură Fișiere Noi/Modificate
```
-roa2web/reports-app/telegram-bot/
+roa2web/backend/modules/telegram/
├── app/
│ ├── bot/
│ │ ├── menus.py ⭐ NOU - Builders pentru tastaturi butoane
@@ -343,7 +343,7 @@ def test_create_navigation_buttons():
**Rulare teste FAZA 1:**
```bash
-cd /mnt/e/proiecte/roa2web/roa2web/reports-app/telegram-bot
+cd /mnt/e/proiecte/roa2web/roa2web/backend/modules/telegram
source venv/bin/activate
pytest tests/test_menus.py -v
```
@@ -1868,11 +1868,11 @@ Documentație:
- Backend API endpoints (vezi CLAUDE.md)
### Fișiere Relevante în Proiect
-- `roa2web/reports-app/telegram-bot/app/bot/handlers.py` - Handlers principale
-- `roa2web/reports-app/telegram-bot/app/bot/formatters.py` - Formatteri răspunsuri
-- `roa2web/reports-app/telegram-bot/app/bot/helpers.py` - Helper functions
-- `roa2web/reports-app/telegram-bot/app/main.py` - Setup aplicație
-- `roa2web/reports-app/telegram-bot/TELEGRAM_COMMANDS.md` - Documentație comenzi
+- `roa2web/backend/modules/telegram/app/bot/handlers.py` - Handlers principale
+- `roa2web/backend/modules/telegram/app/bot/formatters.py` - Formatteri răspunsuri
+- `roa2web/backend/modules/telegram/app/bot/helpers.py` - Helper functions
+- `roa2web/backend/modules/telegram/app/main.py` - Setup aplicație
+- `roa2web/backend/modules/telegram/TELEGRAM_COMMANDS.md` - Documentație comenzi
### Screenshots Pentru Referință
- BotFather interface (screenshot.jpg în root) - Model pentru layout butoane
diff --git a/docs/telegram/testing/DOCKER_TESTING_GUIDE.md b/docs/telegram/testing/DOCKER_TESTING_GUIDE.md
index 27c9369..06259d8 100644
--- a/docs/telegram/testing/DOCKER_TESTING_GUIDE.md
+++ b/docs/telegram/testing/DOCKER_TESTING_GUIDE.md
@@ -16,7 +16,7 @@ Before testing Docker deployment:
### 1. Check Dockerfile Syntax
```bash
-cd /path/to/roa2web/reports-app/telegram-bot
+cd /path/to/roa2web/backend/modules/telegram
# Verify Dockerfile exists and is valid
cat Dockerfile
@@ -71,7 +71,7 @@ cat .dockerignore
### Test 1: Build Telegram Bot Image
```bash
-cd /path/to/roa2web/reports-app/telegram-bot
+cd /path/to/roa2web/backend/modules/telegram
# Build the image
docker build -t roa2web/telegram-bot:test --target production .
diff --git a/docs/telegram/testing/MANUAL_TESTING_CHECKLIST.md b/docs/telegram/testing/MANUAL_TESTING_CHECKLIST.md
index d5a7664..574cd01 100644
--- a/docs/telegram/testing/MANUAL_TESTING_CHECKLIST.md
+++ b/docs/telegram/testing/MANUAL_TESTING_CHECKLIST.md
@@ -19,12 +19,12 @@ Before starting manual tests:
```bash
# Terminal 1: Start backend API (from roa2web/)
-cd reports-app/backend
+cd backend
source venv/bin/activate
uvicorn app.main:app --reload --port 8001
# Terminal 2: Start Telegram bot
-cd reports-app/telegram-bot
+cd backend/modules/telegram
source venv/bin/activate
python -m app.main
```
diff --git a/docs/telegram/testing/README_INTEGRATION_TESTS.md b/docs/telegram/testing/README_INTEGRATION_TESTS.md
index 60dd7d4..367a8cf 100644
--- a/docs/telegram/testing/README_INTEGRATION_TESTS.md
+++ b/docs/telegram/testing/README_INTEGRATION_TESTS.md
@@ -79,7 +79,7 @@ pytest -m ""
### 1. Start Backend API
```bash
-cd roa2web/reports-app/backend
+cd roa2web/backend
source venv/bin/activate
uvicorn app.main:app --reload --port 8001
```
@@ -93,7 +93,7 @@ export TEST_PASSWORD="your_password" # Your Oracle password
### 3. Run Integration Tests
```bash
-cd roa2web/reports-app/telegram-bot
+cd roa2web/backend/modules/telegram
source venv/bin/activate
pytest -m integration -v
```
@@ -169,7 +169,7 @@ pytest -m "not slow" # Skip slow tests
### Import Errors
```bash
# Make sure you're in the right directory
-cd /mnt/e/proiecte/roa2web/roa2web/reports-app/telegram-bot
+cd /mnt/e/proiecte/roa2web/roa2web/backend/modules/telegram
# Activate virtual environment
source venv/bin/activate
diff --git a/public/web.config b/public/web.config
index 197c1f2..b84d40c 100644
--- a/public/web.config
+++ b/public/web.config
@@ -1,28 +1,52 @@
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/scripts/README.md b/scripts/README.md
index cbf5692..16b7453 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -44,10 +44,10 @@ secrets-backup/
**Ce face:**
- Decriptează fișierele .gpg din backup
- Le plasează înapoi în locațiile originale
-- reports-app/backend/.env
-- reports-app/backend/.env.prod
-- reports-app/telegram-bot/.env
-- reports-app/telegram-bot/.env.prod
+- backend/.env
+- backend/.env.prod
+- backend/modules/telegram/.env
+- backend/modules/telegram/.env.prod
**Notă:** Vei fi rugat să introduci parola de decriptare.
@@ -94,10 +94,10 @@ cp -r secrets-backup /mnt/usb/roa2web-secrets-backup
```bash
# Copiază conținutul și salvează în Bitwarden/1Password
-cat reports-app/backend/.env
-cat reports-app/backend/.env.prod
-cat reports-app/telegram-bot/.env
-cat reports-app/telegram-bot/.env.prod
+cat backend/.env
+cat backend/.env.prod
+cat backend/modules/telegram/.env
+cat backend/modules/telegram/.env.prod
```
## 🔒 Best Practices
@@ -120,13 +120,13 @@ cat reports-app/telegram-bot/.env.prod
./scripts/backup-secrets.sh
# Șterge temporar
- mv reports-app/backend/.env reports-app/backend/.env.backup
+ mv backend/.env backend/.env.backup
# Restore
./scripts/restore-secrets.sh
# Verifică
- diff reports-app/backend/.env reports-app/backend/.env.backup
+ diff backend/.env backend/.env.backup
```
4. **Pentru echipă:**
@@ -159,18 +159,18 @@ sudo apt-get install gnupg
### 1. Manual GPG (un fișier):
```bash
-gpg --symmetric --cipher-algo AES256 reports-app/backend/.env
+gpg --symmetric --cipher-algo AES256 backend/.env
# Rezultat: .env.gpg
```
### 2. Tar + GPG (toate odată):
```bash
-tar -czf - reports-app/*/.env* | gpg --symmetric --cipher-algo AES256 > secrets-backup.tar.gz.gpg
+tar -czf - backend/**/.env* | gpg --symmetric --cipher-algo AES256 > secrets-backup.tar.gz.gpg
```
### 3. Ansible Vault:
```bash
-ansible-vault encrypt reports-app/backend/.env.prod
+ansible-vault encrypt backend/.env.prod
```
## 📝 Deployment pe Windows Server
diff --git a/scripts/backup-secrets.sh b/scripts/backup-secrets.sh
index 6e5b129..08e6ffc 100644
--- a/scripts/backup-secrets.sh
+++ b/scripts/backup-secrets.sh
@@ -59,10 +59,10 @@ echo ""
# List of secret files to backup
SECRET_FILES=(
- "reports-app/backend/.env"
- "reports-app/backend/.env.prod"
- "reports-app/telegram-bot/.env"
- "reports-app/telegram-bot/.env.prod"
+ "backend/.env"
+ "backend/.env.prod"
+ "backend/modules/telegram/.env"
+ "backend/modules/telegram/.env.prod"
)
# List of secret directories to backup (will backup all files inside)
@@ -185,22 +185,22 @@ openssl enc -aes-256-cbc -d -pbkdf2 -in backend-.env.enc -out .env
# Backend .env
openssl enc -aes-256-cbc -d -pbkdf2 \\
-in backend-.env.enc \\
- -out ../../../reports-app/backend/.env
+ -out ../../../backend/.env
# Backend .env.prod
openssl enc -aes-256-cbc -d -pbkdf2 \\
-in backend-.env.prod.enc \\
- -out ../../../reports-app/backend/.env.prod
+ -out ../../../backend/.env.prod
# Telegram Bot .env
openssl enc -aes-256-cbc -d -pbkdf2 \\
-in telegram-bot-.env.enc \\
- -out ../../../reports-app/telegram-bot/.env
+ -out ../../../backend/modules/telegram/.env
# Telegram Bot .env.prod
openssl enc -aes-256-cbc -d -pbkdf2 \\
-in telegram-bot-.env.prod.enc \\
- -out ../../../reports-app/telegram-bot/.env.prod
+ -out ../../../backend/modules/telegram/.env.prod
# Decrypt and extract secrets directory
openssl enc -aes-256-cbc -d -pbkdf2 -in secrets.tar.enc | \\
diff --git a/scripts/restore-secrets.sh b/scripts/restore-secrets.sh
index 2409f0c..26ea419 100644
--- a/scripts/restore-secrets.sh
+++ b/scripts/restore-secrets.sh
@@ -132,13 +132,13 @@ for encrypted_file in "${ENCRYPTED_FILES[@]}"; do
# Determine target path based on filename
if [[ "$filename" == "backend-.env" ]]; then
- target="reports-app/backend/.env"
+ target="backend/.env"
elif [[ "$filename" == "backend-.env.prod" ]]; then
- target="reports-app/backend/.env.prod"
+ target="backend/.env.prod"
elif [[ "$filename" == "telegram-bot-.env" ]]; then
- target="reports-app/telegram-bot/.env"
+ target="backend/modules/telegram/.env"
elif [[ "$filename" == "telegram-bot-.env.prod" ]]; then
- target="reports-app/telegram-bot/.env.prod"
+ target="backend/modules/telegram/.env.prod"
else
echo -e "${YELLOW}Skipping unknown file: $filename${NC}"
continue
diff --git a/scripts/test-docker-setup.sh b/scripts/test-docker-setup.sh
index 73cfda7..8861356 100644
--- a/scripts/test-docker-setup.sh
+++ b/scripts/test-docker-setup.sh
@@ -69,13 +69,13 @@ test_file_structure() {
run_test "Production compose exists" "test -f docker-compose.production.yml"
# Backend files
- run_test "Backend Dockerfile exists" "test -f reports-app/backend/Dockerfile"
- run_test "Backend requirements exists" "test -f reports-app/backend/requirements.txt"
+ run_test "Backend Dockerfile exists" "test -f backend/Dockerfile"
+ run_test "Backend requirements exists" "test -f backend/requirements.txt"
# Frontend files
- run_test "Frontend Dockerfile exists" "test -f reports-app/frontend/Dockerfile"
- run_test "Frontend nginx.conf exists" "test -f reports-app/frontend/nginx.conf"
- run_test "Frontend package.json exists" "test -f reports-app/frontend/package.json"
+ run_test "Frontend Dockerfile exists" "test -f src/Dockerfile"
+ run_test "Frontend nginx.conf exists" "test -f src/nginx.conf"
+ run_test "Frontend package.json exists" "test -f src/package.json"
# Nginx Gateway files
run_test "Nginx Gateway Dockerfile exists" "test -f nginx/Dockerfile"
diff --git a/security/SECURITY_PROCEDURES.md b/security/SECURITY_PROCEDURES.md
index 4344eb4..8d4df00 100644
--- a/security/SECURITY_PROCEDURES.md
+++ b/security/SECURITY_PROCEDURES.md
@@ -62,7 +62,7 @@ git push --force-with-lease --tags origin
```bash
# Update all environment files
# 1. roa2web/.env
-# 2. roa2web/reports-app/backend/.env
+# 2. roa2web/backend/.env
# 3. Production environment variables
# Restart all services
diff --git a/security/git_cleanup.py b/security/git_cleanup.py
index 5d525d7..58a055c 100644
--- a/security/git_cleanup.py
+++ b/security/git_cleanup.py
@@ -34,7 +34,7 @@ class GitHistoryCleanup:
# Files and patterns to remove from history
self.FILES_TO_REMOVE = [
"app/.env",
- "roa2web/reports-app/backend/.env",
+ "roa2web/backend/.env",
"roa2web/.env",
"roa2web/.env.development",
"roa2web/.env.production",
diff --git a/shared/docs/MULTI_TENANT_UPGRADE_PLAN.md b/shared/docs/MULTI_TENANT_UPGRADE_PLAN.md
index f6cc0aa..369a211 100644
--- a/shared/docs/MULTI_TENANT_UPGRADE_PLAN.md
+++ b/shared/docs/MULTI_TENANT_UPGRADE_PLAN.md
@@ -173,7 +173,7 @@ shared/
└── cache/
└── redis_client.py ⚠️ MODIFY - Use real tenant_id (not "default")
-reports-app/backend/
+backend/
├── app/
│ ├── main.py ⚠️ MODIFY - Initialize MultiTenantPoolManager
│ └── routers/
@@ -753,7 +753,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_tenant ON audit_logs(tenant_id);
```
7. **Add background task pentru health monitoring**
- - **Fișier:** `reports-app/backend/app/main.py`
+ - **Fișier:** `backend/app/main.py`
- **Task:** Run every 60 seconds
```python
async def monitor_ssh_tunnels():
@@ -824,7 +824,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_tenant ON audit_logs(tenant_id);
```
2. **Update login endpoint să determine tenant_id**
- - **Fișier:** `reports-app/backend/app/main.py` (auth router)
+ - **Fișier:** `backend/app/main.py` (auth router)
- **Logica:**
- Check `tenant_users` table pentru user_id
- Dacă user are access la multiple tenants, return primul (default)
@@ -921,7 +921,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_tenant ON audit_logs(tenant_id);
- **Flow:** AuthMiddleware decode JWT → TenantMiddleware validate tenant access
5. **Update toate router-urile să folosească tenant_id din request.state**
- - **Fișiere:** `reports-app/backend/app/routers/*.py`
+ - **Fișiere:** `backend/app/routers/*.py`
- **Pattern:**
```python
# Înainte (single-tenant)
@@ -945,7 +945,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_tenant ON audit_logs(tenant_id);
```
6. **Update Telegram bot pentru tenant support**
- - **Fișier:** `reports-app/telegram-bot/app/auth/linking.py`
+ - **Fișier:** `backend/modules/telegram/app/auth/linking.py`
- **Modificări:**
- La linking, salvează și `tenant_id` în SQLite
- JWT token include `tenant_id`
@@ -1590,13 +1590,13 @@ locust -f shared/tests/load/test_multi_tenant_load.py --host=http://localhost:80
expdp username/password@ROA directory=BACKUP dumpfile=pre_migration.dmp
# Backup existing .env files
- cp reports-app/backend/.env reports-app/backend/.env.backup
+ cp backend/.env backend/.env.backup
```
- [ ] **Document current single-tenant config**
```bash
# Save current credentials
- cat reports-app/backend/.env > docs/pre_migration_env.txt
+ cat backend/.env > docs/pre_migration_env.txt
# Save current SSH tunnel config
./ssh-tunnel-prod.sh status > docs/pre_migration_ssh.txt
@@ -1795,7 +1795,7 @@ python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().
DB_ENCRYPTION_KEY=$(cat .encryption_key)
# 3. Update .env
-cat >> reports-app/backend/.env << EOF
+cat >> backend/.env << EOF
# Tenant Configuration
TENANT_DB_URL=sqlite:///data/tenant_config.db
DB_ENCRYPTION_KEY=$DB_ENCRYPTION_KEY
@@ -1892,7 +1892,7 @@ services:
roa-backend:
build:
context: .
- dockerfile: ./reports-app/backend/Dockerfile
+ dockerfile: ./backend/Dockerfile
image: roa2web/backend:multi-tenant
container_name: roa-backend
restart: unless-stopped
@@ -1942,7 +1942,7 @@ services:
# Frontend (unchanged)
roa-frontend:
build:
- context: ./reports-app/frontend
+ context: ./src
dockerfile: Dockerfile
image: roa2web/frontend:latest
container_name: roa-frontend
@@ -2443,7 +2443,7 @@ Multi-Tenant (10 tenants):
- **OraclePool:** `shared/database/oracle_pool.py` - Singleton pattern for single-tenant
- **JWT Handler:** `shared/auth/jwt_handler.py` - Token creation/validation (needs tenant_id)
- **Auth Middleware:** `shared/auth/middleware.py` - JWT verification (needs tenant validation)
-- **Backend Main:** `reports-app/backend/app/main.py` - Startup logic (needs MultiTenantPoolManager)
+- **Backend Main:** `backend/app/main.py` - Startup logic (needs MultiTenantPoolManager)
- **SSH Tunnel Script:** `ssh-tunnel-prod.sh` - Single tunnel script (needs per-tenant manager)
### Inspiration & Patterns
diff --git a/shared/docs/REDIS_IMPLEMENTATION_PLAN.md b/shared/docs/REDIS_IMPLEMENTATION_PLAN.md
index c0c6c6e..ef371b9 100644
--- a/shared/docs/REDIS_IMPLEMENTATION_PLAN.md
+++ b/shared/docs/REDIS_IMPLEMENTATION_PLAN.md
@@ -35,13 +35,13 @@
### Fișiere Modificate (7 fișiere)
-- [ ] `reports-app/backend/requirements.txt` - Adaugă redis>=5.0.0
-- [ ] `reports-app/backend/.env.example` - Adaugă REDIS_* env vars
-- [ ] `reports-app/backend/app/main.py` - Initialize Redis at startup
-- [ ] `reports-app/backend/app/services/dashboard_service.py` - Apply caching
-- [ ] `reports-app/backend/app/services/invoice_service.py` - Apply caching
-- [ ] `reports-app/backend/app/routers/dashboard.py` - Cache invalidation on mutations
-- [ ] `reports-app/backend/app/routers/invoices.py` - Cache invalidation on mutations
+- [ ] `backend/requirements.txt` - Adaugă redis>=5.0.0
+- [ ] `backend/.env.example` - Adaugă REDIS_* env vars
+- [ ] `backend/app/main.py` - Initialize Redis at startup
+- [ ] `backend/app/services/dashboard_service.py` - Apply caching
+- [ ] `backend/app/services/invoice_service.py` - Apply caching
+- [ ] `backend/app/routers/dashboard.py` - Cache invalidation on mutations
+- [ ] `backend/app/routers/invoices.py` - Cache invalidation on mutations
---
@@ -54,7 +54,7 @@
**Tasks:**
1. [ ] **Adaugă dependency în requirements.txt**
- - Fișier: `reports-app/backend/requirements.txt`
+ - Fișier: `backend/requirements.txt`
- Acțiune: Adaugă linia `redis>=5.0.0` după `httpx>=0.27.0`
- Motivație: redis 5.0+ are async support nativ
@@ -79,7 +79,7 @@
- Template (vezi secțiunea Code Templates mai jos)
4. [ ] **Adaugă env variables în .env.example**
- - Fișier: `reports-app/backend/.env.example`
+ - Fișier: `backend/.env.example`
- Acțiune: Adaugă la sfârșitul fișierului:
```bash
# Redis Configuration
@@ -90,7 +90,7 @@
```
5. [ ] **Initialize Redis la startup în main.py**
- - Fișier: `reports-app/backend/app/main.py`
+ - Fișier: `backend/app/main.py`
- Acțiune: În funcția `startup_event()`:
```python
from shared.cache import redis_cache
@@ -254,7 +254,7 @@
**Tasks:**
1. [ ] **Apply @cached în DashboardService.get_complete_summary()**
- - Fișier: `reports-app/backend/app/services/dashboard_service.py`
+ - Fișier: `backend/app/services/dashboard_service.py`
- Acțiune: Adaugă decorator la metoda `get_complete_summary`:
```python
from shared.cache import cached
@@ -268,26 +268,26 @@
- Motivație: Dashboard e accesat des, datele se schimbă rar
2. [ ] **Apply @cached în DashboardService.get_trends()**
- - Fișier: `reports-app/backend/app/services/dashboard_service.py`
+ - Fișier: `backend/app/services/dashboard_service.py`
- Acțiune: Similar, TTL=180 (3 min pentru trends)
- Cache key va include period: `cache:default:dashboard_trends:company-X:period-30d:abc123`
3. [ ] **Apply @cached în DashboardService.get_detailed_data()**
- - Fișier: `reports-app/backend/app/services/dashboard_service.py`
+ - Fișier: `backend/app/services/dashboard_service.py`
- Acțiune: TTL=60 (1 min pentru tabel detalii - se refreshează des)
- Cache key include page, page_size, search
4. [ ] **Apply @cached în InvoiceService.get_invoices()**
- - Fișier: `reports-app/backend/app/services/invoice_service.py`
+ - Fișier: `backend/app/services/invoice_service.py`
- Acțiune: TTL=60 (1 min)
- Cache key include filter params (partner_type, date_from, date_to, etc.)
5. [ ] **Apply @cached în InvoiceService.get_invoice_summary()**
- - Fișier: `reports-app/backend/app/services/invoice_service.py`
+ - Fișier: `backend/app/services/invoice_service.py`
- Acțiune: TTL=180 (3 min pentru summary)
6. [ ] **Cache invalidation în dashboard mutations (viitor)**
- - Fișier: `reports-app/backend/app/routers/dashboard.py`
+ - Fișier: `backend/app/routers/dashboard.py`
- Acțiune: Pregătește cod pentru invalidation (de activat când există POST/PUT/DELETE):
```python
# TODO: Activate când implementăm mutations
@@ -301,7 +301,7 @@
```
7. [ ] **Cache invalidation în invoice mutations**
- - Fișier: `reports-app/backend/app/routers/invoices.py`
+ - Fișier: `backend/app/routers/invoices.py`
- Acțiune: Când se implementează POST/PUT/DELETE pentru invoices, invalidează:
- `invoices_list`
- `invoices_summary`
@@ -601,7 +601,7 @@ ab -n 100 -c 10 http://localhost:8001/api/dashboard/summary?company=123
## 🔧 Configurare Env Variables
-**File:** `reports-app/backend/.env`
+**File:** `backend/.env`
```bash
# ============================================================================
@@ -657,7 +657,7 @@ docker-compose exec roa-backend env | grep REDIS
- [ ] Dependency added: `redis>=5.0.0` în requirements.txt
- [ ] Package created: `shared/cache/__init__.py`
- [ ] Redis client: `shared/cache/redis_client.py`
-- [ ] Env vars added: `reports-app/backend/.env.example`
+- [ ] Env vars added: `backend/.env.example`
- [ ] Main.py updated: Redis initialize at startup
- [ ] Test: `python -c "import asyncio; from shared.cache import redis_cache; asyncio.run(redis_cache.initialize())"`
@@ -703,8 +703,8 @@ docker-compose exec roa-backend env | grep REDIS
- **Docker Compose Redis Config:** `docker-compose.yml:147-163`
- **Oracle Pool Pattern:** `shared/database/oracle_pool.py` (reference for singleton pattern)
-- **Backend Services:** `reports-app/backend/app/services/` (where to apply caching)
-- **Backend Routers:** `reports-app/backend/app/routers/` (where to invalidate cache)
+- **Backend Services:** `backend/app/services/` (where to apply caching)
+- **Backend Routers:** `backend/app/routers/` (where to invalidate cache)
### Documentație Externă
diff --git a/shared/routes/__init__.py b/shared/routes/__init__.py
index 9e8effb..385afc9 100644
--- a/shared/routes/__init__.py
+++ b/shared/routes/__init__.py
@@ -2,7 +2,7 @@
Shared Routes for ROA2WEB Applications
This module provides factory functions for creating common API routers
-that can be mounted in both reports-app and data-entry-app.
+that can be mounted in both the unified monolith backend.
Usage:
from shared.routes import create_companies_router, create_calendar_router
diff --git a/shared/routes/calendar.py b/shared/routes/calendar.py
index f2b144c..3a5dd9b 100644
--- a/shared/routes/calendar.py
+++ b/shared/routes/calendar.py
@@ -2,7 +2,7 @@
Shared Calendar Router Factory for ROA2WEB Applications
Creates a FastAPI router for /api/calendar endpoints that can be used
-by both reports-app and data-entry-app.
+by both the unified monolith backend.
Usage:
from shared.routes.calendar import create_calendar_router
diff --git a/shared/routes/companies.py b/shared/routes/companies.py
index 4b0abcb..dc7cb79 100644
--- a/shared/routes/companies.py
+++ b/shared/routes/companies.py
@@ -2,7 +2,7 @@
Shared Companies Router Factory for ROA2WEB Applications
Creates a FastAPI router for /api/companies endpoints that can be used
-by both reports-app and data-entry-app.
+by both the unified monolith backend.
Usage:
from shared.routes.companies import create_companies_router