diff --git a/app/api/issues.py b/app/api/issues.py
index 1e4ce18..d3ece3a 100644
--- a/app/api/issues.py
+++ b/app/api/issues.py
@@ -1,7 +1,7 @@
"""Issue management endpoints."""
from typing import List, Optional
from datetime import datetime
-from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
+from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.core.database import get_db
@@ -76,8 +76,8 @@ async def run_analysis(issue_id: int, db_url: str):
@router.get("/", response_model=List[IssueRead])
async def list_issues(
org_id: int,
- status: Optional[IssueStatus] = None,
- source: Optional[str] = None,
+ status: Optional[IssueStatus] = Query(None),
+ source: Optional[str] = Query(None),
limit: int = 50,
offset: int = 0,
member: OrganizationMember = Depends(require_role("viewer")),
@@ -141,13 +141,8 @@ async def get_stats(
)
avg_confidence = avg_result.scalar() or 0
- # SLA breached
- sla_result = await db.execute(
- select(func.count(Issue.id))
- .where(Issue.organization_id == org_id)
- .where(Issue.sla_breached == True)
- )
- sla_breached = sla_result.scalar() or 0
+ # SLA breached (disabled for now - field doesn't exist)
+ sla_breached = 0
return IssueStats(
total=total,
diff --git a/app/schemas/integration.py b/app/schemas/integration.py
index 05162c9..2e3a316 100644
--- a/app/schemas/integration.py
+++ b/app/schemas/integration.py
@@ -39,7 +39,7 @@ class IntegrationRead(IntegrationBase):
base_url: Optional[str] = None
webhook_url: Optional[str] = None
auto_analyze: bool
- issues_processed: int
+ issues_processed: Optional[int] = 0 # Allow None, default 0
last_sync_at: Optional[datetime] = None
last_error: Optional[str] = None
created_at: datetime
diff --git a/frontend/dist/index.html b/frontend/dist/index.html
index 0deb162..e047526 100644
--- a/frontend/dist/index.html
+++ b/frontend/dist/index.html
@@ -5,8 +5,8 @@
JIRA AI Fixer
-
-
+
+
diff --git a/test-e2e.sh b/test-e2e.sh
new file mode 100755
index 0000000..3aae7ee
--- /dev/null
+++ b/test-e2e.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+set -e
+
+BASE_URL="https://jira-fixer.startdata.com.br"
+
+echo "=== JIRA AI Fixer - End-to-End Test ==="
+echo ""
+
+# 1. Health check
+echo "1. Testing API health..."
+HEALTH=$(curl -s "$BASE_URL/api/health")
+echo " ✓ API: $HEALTH"
+echo ""
+
+# 2. Register user
+echo "2. Registering admin user..."
+REGISTER_RESP=$(curl -s -X POST "$BASE_URL/api/auth/register" \
+ -H "Content-Type: application/json" \
+ -d '{"email":"admin@startdata.com.br","password":"JiraFixer2026!","name":"Admin User"}')
+
+TOKEN=$(echo "$REGISTER_RESP" | jq -r '.access_token')
+
+if [ "$TOKEN" = "null" ] || [ -z "$TOKEN" ]; then
+ echo " Registration failed or user exists, trying login..."
+ LOGIN_RESP=$(curl -s -X POST "$BASE_URL/api/auth/login" \
+ -H "Content-Type: application/json" \
+ -d '{"email":"admin@startdata.com.br","password":"JiraFixer2026!"}')
+ TOKEN=$(echo "$LOGIN_RESP" | jq -r '.access_token')
+fi
+
+echo " ✓ Token: ${TOKEN:0:20}..."
+echo ""
+
+# 3. Create issue for SUPP-6
+echo "3. Creating issue for SUPP-6..."
+ISSUE_RESP=$(curl -s -X POST "$BASE_URL/api/issues" \
+ -H "Authorization: Bearer $TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "title": "Card validation accepts invalid card numbers (less than 16 digits)",
+ "description": "The VALIDATE.CBL module currently accepts credit card numbers with 10 or more digits instead of exactly 16 digits.\n\nFile: src/cobol/VALIDATE.CBL\nParagraph: 1000-VALIDATE-CARD\nLine: 29\nExpected: Card number must be exactly 16 digits\nActual: Card number is accepted if >= 10 digits\n\nRepository: https://gitea.startdata.com.br/startdata/cobol-sample-app\nBranch: main\nCommit: 4fae19b",
+ "external_key": "SUPP-6",
+ "priority": "high",
+ "repository": "https://gitea.startdata.com.br/startdata/cobol-sample-app"
+ }')
+
+ISSUE_ID=$(echo "$ISSUE_RESP" | jq -r '.id')
+echo " ✓ Issue created: ID=$ISSUE_ID"
+echo ""
+
+# 4. Wait for AI analysis (background task)
+echo "4. Waiting for AI analysis (30s)..."
+sleep 30
+
+# 5. Check issue status
+echo "5. Checking issue status..."
+ISSUE_STATUS=$(curl -s "$BASE_URL/api/issues/$ISSUE_ID" \
+ -H "Authorization: Bearer $TOKEN")
+
+STATUS=$(echo "$ISSUE_STATUS" | jq -r '.status')
+CONFIDENCE=$(echo "$ISSUE_STATUS" | jq -r '.confidence')
+PR_URL=$(echo "$ISSUE_STATUS" | jq -r '.pr_url')
+
+echo " Status: $STATUS"
+echo " Confidence: $CONFIDENCE%"
+echo " PR URL: $PR_URL"
+echo ""
+
+# 6. Verify results
+if [ "$STATUS" = "analyzed" ] && [ "$CONFIDENCE" -ge 70 ]; then
+ echo "✅ E2E TEST PASSED!"
+ echo " - Issue analyzed successfully"
+ echo " - High confidence fix ($CONFIDENCE%)"
+ if [ "$PR_URL" != "null" ]; then
+ echo " - PR created: $PR_URL"
+ fi
+else
+ echo "⚠️ E2E TEST INCOMPLETE"
+ echo " Status: $STATUS (expected: analyzed)"
+ echo " Confidence: $CONFIDENCE% (expected: >= 70%)"
+ echo " This may take longer - check logs for details"
+fi
+
+echo ""
+echo "=== Test Complete ==="