From 97435c42eaec05f0665bd6523645cc245aec52b2 Mon Sep 17 00:00:00 2001 From: vickytechkey Date: Thu, 15 Oct 2026 20:53:26 +0530 Subject: [PATCH] feat: add interactive verification test portal and transaction feed --- docverify/settings.py | 2 +- docverify/urls.py | 2 + templates/verifier/portal.html | 1308 ++++++++++++++++++++++++++++++++ verifier/serializers.py | 2 + verifier/tests.py | 20 + verifier/urls.py | 10 +- verifier/views.py | 32 + 7 files changed, 1374 insertions(+), 2 deletions(-) create mode 100644 templates/verifier/portal.html diff --git a/docverify/settings.py b/docverify/settings.py index 6f199f4..64575df 100644 --- a/docverify/settings.py +++ b/docverify/settings.py @@ -50,7 +50,7 @@ ROOT_URLCONF = "docverify.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], + "DIRS": [BASE_DIR / "templates"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ diff --git a/docverify/urls.py b/docverify/urls.py index c2971db..02d6df6 100644 --- a/docverify/urls.py +++ b/docverify/urls.py @@ -16,9 +16,11 @@ Including another URLconf """ from django.contrib import admin from django.urls import path, include +from verifier.views import PortalView urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('verifier.urls')), + path('', PortalView.as_view(), name='portal_root'), ] diff --git a/templates/verifier/portal.html b/templates/verifier/portal.html new file mode 100644 index 0000000..eea6f98 --- /dev/null +++ b/templates/verifier/portal.html @@ -0,0 +1,1308 @@ + + + + + + Tradhox Document Verification Studio & Test Portal + + + + + + + + + + +
+
+ +
+
+ Tradhox Document Verification Studio + LIVE ENGINE +
+
Automated Multi-Vendor Waterfall Engine • Codeplus Live Onboarded
+
+
+ +
+
+ Host: beta-documentverification.tradhox.com
+ Active Vendors: {{ active_vendor_count|default:"1" }} Active +
+ + Django Admin + + + +
+
+ +
+ + +
+
+
🪪
+
+
PAN Verification (v5 Recommended)
+ POST /v5/pan-verify +
+
+ +
+
📄
+
+
PAN Detailed API
+ POST /v4/pan-detailed +
+
+ +
+
🔍
+
+
PAN Advanced API
+ POST /v4/pan-advanced +
+
+ +
+
🏦
+
+
Bank Account (Penny Drop)
+ POST /v4/bank-verify +
+
+ +
+
🏢
+
+
GST Verification (v5)
+ POST /v5/gst-verify +
+
+ +
+
📑
+
+
Fetch GST By PAN
+ POST /v4/fetch-gst +
+
+ +
+
📜
+
+
Fetch MSME By PAN
+ POST /v4/msme-pan +
+
+
+ + +
+ + +
+
+
+ ⚡ Test Execution Console +
+ +
+ +
+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ + +
+
+
+ 📊 Live Response & Audit Inspection +
+ +
+ + +
+
+
⏱️
+
+
Engine Ready
+
Select a service and click Execute to test live waterfall verification.
+
+
+
+ + + + + + + + +
+
+
+ + +
+ +
+
// Awaiting verification trigger...
+
+
+ +
+ + +
+
+
+ 📜 Recent PostgreSQL Transactions (Audit Log) +
+
Real-time stream from beta-documentverifcation DB
+
+ +
+ + + + + + + + + + + + + + {% for tx in recent_transactions %} + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
Created AtReference IDDocumentVendorStatusLatencyAction
{{ tx.created_at|date:"Y-m-d H:i:s" }}{{ tx.reference_id|stringformat:".8s" }}...{{ tx.document_type|upper }}{{ tx.successful_vendor|default:"exhausted" }} + + {{ tx.status }} + + {{ tx.total_latency_ms|floatformat:1 }} ms
No transactions logged yet. Run your first verification above!
+
+
+ +
+ + + + + diff --git a/verifier/serializers.py b/verifier/serializers.py index abac477..a3738a0 100644 --- a/verifier/serializers.py +++ b/verifier/serializers.py @@ -28,6 +28,8 @@ class VendorAttemptLogSerializer(serializers.ModelSerializer): "vendor_name", "status", "is_success", + "data", + "raw_response", "error_code", "error_message", "latency_ms", diff --git a/verifier/tests.py b/verifier/tests.py index 73a4e46..25dd328 100644 --- a/verifier/tests.py +++ b/verifier/tests.py @@ -599,3 +599,23 @@ class VerificationAPITests(TestCase): self.assertEqual(detail_res.data["reference_id"], str(ref_id)) self.assertEqual(len(detail_res.data["attempts"]), 1) + # Verify GET /api/transactions/ (List endpoint) + list_url = reverse("verifier:transaction_list") + list_res = self.client.get(list_url) + self.assertEqual(list_res.status_code, status.HTTP_200_OK) + self.assertGreaterEqual(list_res.data["count"], 1) + + def test_portal_view_renders(self): + """Test GET / and /api/portal/ render the verification playground portal.""" + # Test root path + res_root = self.client.get("/") + self.assertEqual(res_root.status_code, status.HTTP_200_OK) + self.assertContains(res_root, "Tradhox Document Verification Studio") + self.assertContains(res_root, "PAN Verification (v5 Recommended)") + + # Test /api/portal/ + res_portal = self.client.get(reverse("verifier:portal")) + self.assertEqual(res_portal.status_code, status.HTTP_200_OK) + self.assertContains(res_portal, "Test Execution Console") + + diff --git a/verifier/urls.py b/verifier/urls.py index d4a74f5..8c0ee5d 100644 --- a/verifier/urls.py +++ b/verifier/urls.py @@ -1,10 +1,18 @@ from django.urls import path -from .views import DocumentVerifyView, VendorListView, TransactionDetailView +from .views import ( + DocumentVerifyView, + VendorListView, + TransactionDetailView, + TransactionListView, + PortalView, +) app_name = "verifier" urlpatterns = [ path("verify/", DocumentVerifyView.as_view(), name="verify_document"), path("vendors/", VendorListView.as_view(), name="list_vendors"), + path("transactions/", TransactionListView.as_view(), name="transaction_list"), path("transactions//", TransactionDetailView.as_view(), name="transaction_detail"), + path("portal/", PortalView.as_view(), name="portal"), ] diff --git a/verifier/views.py b/verifier/views.py index b2fdc30..eda5623 100644 --- a/verifier/views.py +++ b/verifier/views.py @@ -144,3 +144,35 @@ class TransactionDetailView(APIView): serializer = VerificationTransactionSerializer(tx) return Response(serializer.data) + + +class TransactionListView(APIView): + """ + GET /api/transactions/ + Lists recent verification transactions (up to 50) for dashboard/portal monitoring. + """ + + def get(self, request, *args, **kwargs): + limit = min(int(request.query_params.get("limit", 25)), 50) + txs = VerificationTransaction.objects.prefetch_related("attempts").all()[:limit] + serializer = VerificationTransactionSerializer(txs, many=True) + return Response({"count": len(serializer.data), "results": serializer.data}) + + +from django.views.generic import TemplateView + + +class PortalView(TemplateView): + """ + Renders the interactive testing & inspection studio for all verification features. + """ + template_name = "verifier/portal.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + vendors = registry.get_all_vendors() + context["vendors"] = vendors + context["active_vendor_count"] = sum(1 for v in vendors if v.is_active) + context["recent_transactions"] = VerificationTransaction.objects.prefetch_related("attempts").all()[:10] + return context +