- Delete data-entry-app/ (1.6GB), reports-app/ (447MB), .auto-build-data/
- Saved ~1.4GB disk space (64% reduction: 2.2GB → 845MB)
Updated references across 38 files:
- .claude/rules/ paths: backend/modules/, src/modules/
- .claude/commands/validate.md: all validation paths
- docs/ (13 files): data-entry, telegram, README, CLAUDE.md
- scripts/ (3 files): backup-secrets, restore-secrets, test-docker
- security/ (2 files): git_cleanup, SECURITY_PROCEDURES
- deployment/ & shared/: updated all stale comments
All paths now reflect ultrathin monolith architecture:
- Backend: backend/modules/{reports,data_entry,telegram}/
- Frontend: src/modules/{reports,data-entry}/
- Shared: shared/{auth,database,routes}/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
10 KiB
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→ 404GET /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ătrehttp://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):
<rule name="Proxy Unified API" stopProcessing="true">
<match url="^api/(.*)" /> ❌ Missing roa2web prefix!
<action type="Rewrite" url="http://localhost:8000/api/{R:1}" />
</rule>
CORRECT Configuration:
<rule name="Proxy Unified API" stopProcessing="true">
<match url="^roa2web/api/(.*)" /> ✅ Includes roa2web prefix
<action type="Rewrite" url="http://localhost:8000/api/{R:1}" />
</rule>
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
-
Backend service not running
- Check:
Get-Service ROA2WEB-Backend
- Check:
-
IIS ARR not enabled
- Check:
Get-WebConfigurationProperty -PSPath "MACHINE/WEBROOT/APPHOST" -Filter "system.webServer/proxy" -Name "enabled"
- Check:
-
IIS sub-application misconfigured
- Frontend should be deployed at IIS path
/roa2web, not root
- Frontend should be deployed at IIS path
Diagnostic Steps
Step 1: Check Backend Service (on 10.0.20.36)
# 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:
{"status": "healthy", "version": "..."}
Step 2: Check Internal IIS web.config (on 10.0.20.36)
# 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:
<match url="^roa2web/api/(.*)" />(NOT^api/(.*))<match url="^roa2web/uploads/(.*)" />(NOT^uploads/(.*))<match url="^roa2web/.*" />for SPA fallback
Step 3: Check IIS ARR (on 10.0.20.36)
# 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)
# 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)
# 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 version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- Proxy API requests to unified backend -->
<rule name="Proxy Unified API" stopProcessing="true">
<match url="^roa2web/api/(.*)" />
<action type="Rewrite" url="http://localhost:8000/api/{R:1}" />
</rule>
<!-- Proxy uploads to unified backend -->
<rule name="Proxy Uploads" stopProcessing="true">
<match url="^roa2web/uploads/(.*)" />
<action type="Rewrite" url="http://localhost:8000/uploads/{R:1}" />
</rule>
<!-- SPA fallback - serve index.html for non-file requests -->
<rule name="SPA Fallback" stopProcessing="true">
<match url="^roa2web/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/roa2web/index.html" />
</rule>
</rules>
</rewrite>
<staticContent>
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
<mimeMap fileExtension=".js" mimeType="application/javascript" />
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="public, max-age=31536000" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Deployment:
# ⚠️ 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
# 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)
# 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)
# On 10.0.20.36
Invoke-WebRequest http://localhost:8000/health
Expected: 200 OK with JSON response
2. Internal IIS Proxy Test
# On 10.0.20.36
Invoke-WebRequest https://localhost/roa2web/api/health
Expected: 200 OK (proxied from backend)
3. Public Access Test
# 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:
# 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:
-
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
- Repository should have separate web.config templates:
-
Automated Deployment Script
- PowerShell script should validate web.config before deployment
- Check for required URL patterns:
^roa2web/api/,^roa2web/uploads/
-
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/
- Verify web.config includes
- Add to
-
Monitoring
- Add health check endpoint monitoring
- Alert if backend service stops
- Monitor IIS logs for 404/502 errors
Next Steps
- ✅ Immediate: Check internal server web.config (on 10.0.20.36)
- ✅ Immediate: Verify backend service is running
- ✅ Immediate: Apply Fix #1 if web.config is incorrect
- ⏭️ After Fix: Run verification steps
- ⏭️ After Fix: Update repository web.config template
- ⏭️ Future: Add automated deployment validation
Documentation Created
- ✅
deployment/windows/docs/TWO-TIER-IIS-DEPLOYMENT.md- Complete 2-tier architecture guide - ✅ Updated
CLAUDE.mdwith 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