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