Compare commits

...

14 Commits

Author SHA1 Message Date
CHIEFSOFT\ameye dd0f39428a SQLALCHEMY_DATABASE_URI 2025-10-10 16:17:35 +01:00
CHIEFSOFT\ameye 50eaf0099b rem remove swagger file path 2025-10-10 16:17:35 +01:00
CHIEFSOFT\ameye 6377158c3c Try catch at start 2025-10-10 16:17:35 +01:00
VivianDee ce6b0684c8 [add]: DB_URI 2025-10-10 16:15:41 +01:00
VivianDee b6ca91153f Update routes.py 2025-10-06 18:29:47 +01:00
VivianDee 244f648974 [add]: Events Service health check 2025-10-06 18:22:49 +01:00
VivianDee 06b266c3a7 [fix]: status 2025-10-03 15:00:37 +01:00
VivianDee ab9330bb23 [add]: Database health check 2025-10-03 14:54:56 +01:00
CHIEFSOFT\ameye f5cf4e5bdd sample config 2025-09-30 07:35:02 -04:00
CHIEFSOFT\ameye 0b78698db9 added logger 2025-09-26 06:49:41 -04:00
CHIEFSOFT\ameye d8abd0ff2a Fix URL 2025-09-26 06:35:18 -04:00
CHIEFSOFT\ameye c6acd9e73a returned eligibility amount checks 2025-09-26 06:01:31 -04:00
CHIEFSOFT\ameye 18dda45fa1 bank minimum amount 2025-09-25 10:01:36 -04:00
ameye 363c6b498a Merge branch 'direct_loan_repayment' of DigiFi/digifi-BankToProductCore into master 2025-09-13 20:25:30 +00:00
6 changed files with 195 additions and 30 deletions
+40
View File
@@ -0,0 +1,40 @@
# Environment Variables ======================================================
BASIC_AUTH_USERNAME=user
BASIC_AUTH_PASSWORD=password
SWAGGER_URL="/documentation"
API_URL="/swagger.json"
# Flask Configuration =========================================================
FLASK_APP=wsgi.py
FLASK_ENV=development
APP_PORT=4500
#Database Configuration =======================================================
DATABASE_USER=FIRSTADVSTG
DATABASE_PASSWORD=Pchanged_56789
DATABASE_HOST=ig-x6-uat-scan
DATABASE_PORT=1521
DATABASE_NAME=FIRSTADVSTG
DATABASE_SID=firstadv
SQLALCHEMY_DATABASE_URI_FULL="oracle+oracledb://FIRSTADVSTG:Pchanged_56789@10.2.110.30:1521/?service_name=firstadv"
# Event Bus =====================================================================
KAFKA_BROKER="10.2.110.20:9082"
#Bank Calls =====================================================================
SIMBRELLA_BASE_URL="https://bank-emulator.dev.simbrellang.net"
SIMBRELLA_APP_ID="app1"
SIMBRELLA_API_KEY="testtest-api-key-12345"
#Events Direct Location =========================================================
EVENTS_SERVICE_BASE_URL="http://10.2.24.133:5000"
ENDPOINT_DIRECT_LOAN="/autocall/direct/loan"
ENDPOINT_DIRECT_REPAYMENT="/autocall/direct/repayment"
#EVENTS_SERVICE_BASE_URL2="https://event-core.simbrellang.net"
#EVENTS_SERVICE_BASE_URL="http://10.10.11.17:14700"
+27 -23
View File
@@ -20,40 +20,44 @@ from flask_jwt_extended import (
def create_app():
"""Factory function to create a Flask app instance"""
# import oracledb
# oracledb.init_oracle_client(lib_dir=None)
app = Flask(__name__)
try:
# Load configuration
app.config.from_object(Config)
app = Flask(__name__)
CORS(app)
# Load configuration
app.config.from_object(Config)
JWTManager(app)
CORS(app, supports_credentials=True)
CORS(app)
# Swagger Doc
SWAGGER_URL = app.config.get("SWAGGER_URL")
API_URL = app.config.get("API_URL")
JWTManager(app)
CORS(app, supports_credentials=True)
# Register blueprints
app.register_blueprint(api)
# Swagger Doc
SWAGGER_URL = app.config.get("SWAGGER_URL")
API_URL = app.config.get("API_URL")
swagger_ui_blueprint = get_swaggerui_blueprint(SWAGGER_URL, API_URL)
app.register_blueprint(swagger_ui_blueprint, url_prefix=SWAGGER_URL)
# Register blueprints
app.register_blueprint(api)
# Error Handlers
register_error_handlers(app)
swagger_ui_blueprint = get_swaggerui_blueprint(SWAGGER_URL, API_URL)
app.register_blueprint(swagger_ui_blueprint, url_prefix=SWAGGER_URL)
from . import models
# Error Handlers
register_error_handlers(app)
# Initialize Flask-Mail
mail.init_app(app)
from . import models
# Database and Migrations
db.init_app(app)
# Initialize Flask-Mail
mail.init_app(app)
migrate.init_app(app, db)
# Database and Migrations
db.init_app(app)
return app
migrate.init_app(app, db)
return app
except Exception as e:
print(f"An unexpected error occurred: {e}")
+22 -2
View File
@@ -5,6 +5,7 @@ from app.config import settings
class EventServiceIntegration:
BASE_URL = settings.SIMBRELLA_BASE_URL
EVENTS_SERVICE_BASE_URL = settings.EVENTS_SERVICE_BASE_URL
ENDPOINT_DIRECT_LOAN = settings.ENDPOINT_DIRECT_LOAN
ENDPOINT_DIRECT_REPAYMENT = settings.ENDPOINT_DIRECT_REPAYMENT
@@ -13,7 +14,8 @@ class EventServiceIntegration:
"""
Calls the Direct Loan endpoint
"""
url = f"{EventServiceIntegration.BASE_URL}{EventServiceIntegration.ENDPOINT_DIRECT_LOAN}"
url = f"{EventServiceIntegration.EVENTS_SERVICE_BASE_URL}{EventServiceIntegration.ENDPOINT_DIRECT_LOAN}"
logger.info(f"Direct Loan URL: {url}")
payload = {"transactionId": str(transaction_id)}
headers = {
@@ -33,7 +35,8 @@ class EventServiceIntegration:
"""
Calls the Direct Repayment endpoint
"""
url = f"{EventServiceIntegration.BASE_URL}{EventServiceIntegration.ENDPOINT_DIRECT_REPAYMENT}"
url = f"{EventServiceIntegration.EVENTS_SERVICE_BASE_URL}{EventServiceIntegration.ENDPOINT_DIRECT_REPAYMENT}"
logger.info(f"Direct Repayment URL: {url}")
payload = {"transactionId": str(transaction_id)}
headers = {
@@ -47,3 +50,20 @@ class EventServiceIntegration:
except Exception as e:
logger.error(f"Direct Repayment API call failed: {str(e)}", exc_info=True)
raise
@staticmethod
def health_check():
"""
Health check for Events Service
"""
url = f"{EventServiceIntegration.EVENTS_SERVICE_BASE_URL}/health"
logger.info(f"Health Check URL: {url}")
try:
response = httpx.get(url, timeout=5.0)
logger.info(f"Health Check Response: {response.text}")
return response
except Exception as e:
logger.error(f"Health Check API call failed: {str(e)}", exc_info=True)
raise
+60 -5
View File
@@ -1,3 +1,4 @@
from app.api.integrations.events_service import EventServiceIntegration
from flask import Blueprint, request, jsonify, send_from_directory
from app.api.services import (
EligibilityCheckService,
@@ -19,6 +20,10 @@ from flask_jwt_extended import (
get_jwt_identity,
create_refresh_token,
)
from sqlalchemy import text
from app.extensions import db
from app.config import settings
from urllib.parse import urlparse
api = Blueprint("api", __name__)
@@ -37,10 +42,10 @@ def swagger_json():
return send_from_directory(swagger_dir, "digifi_swagger.json")
@api.route("/swagger/<path:filename>")
def serve_paths(filename):
swagger_dir = os.path.join("swagger")
return send_from_directory(swagger_dir, filename)
# @api.route("/swagger/<path:filename>")
# def serve_paths(filename):
# swagger_dir = os.path.join("swagger")
# return send_from_directory(swagger_dir, filename)
# EligibilityCheck Endpoint
@@ -117,7 +122,57 @@ def notification_callback():
# Health Check Endpoint
@api.route("/health", methods=["GET"])
def health_check():
return {"status": "ok"}, 200
SQLALCHEMY_DATABASE_URI = settings.SQLALCHEMY_DATABASE_URI
response = {}
db_status = "Connection Successful"
events_service_status = "Connection Successful"
errors = []
status = "ok"
# Extract the database URI
try:
db_uri = db.engine.url.render_as_string(hide_password=False)
db_uri = db_uri
except Exception as e:
db_uri = "Unavailable"
# Check database connection
try:
logger.info(f"Database Health == : {SQLALCHEMY_DATABASE_URI}")
db.session.execute(text("SELECT 1"))
except Exception as e:
db_status = "Connection Failed"
errors.append(f"Database Error: {str(e)}")
status = "failed"
# Check Events Service health
try:
events_service_response = EventServiceIntegration.health_check()
if events_service_response.status_code != 200:
events_service_status = "Connection Failed"
status = "failed"
errors.append(f"Events Service response: {events_service_response.text}")
except Exception as e:
events_service_status = "Connection Successful"
status = "failed"
errors.append(f"Events Service connection failed: {str(e)}")
response = {
"status": status,
"db_status": db_status,
"db_uri": db_uri,
"events_service_status": events_service_status,
"errors": errors or None
}
return jsonify(response), 200 if status == "ok" else 500
# Authorize endpoint
+7
View File
@@ -182,6 +182,10 @@ class OfferAnalysis:
logger.error(f"Max eligible amount ({real_eligible_amount}) is less than the minimum offer amount ({original_transaction_offer.min_amount}).")
raise ValueError("You are not eligible for a loan at this time.")
# if real_eligible_amount < 100:
# logger.error(f"Max eligible amount ({real_eligible_amount}) is less than the minimum offer amount ({original_transaction_offer.min_amount}).")
# raise ValueError("You are not eligible for a loan at this time.")
transaction_offer = TransactionOffer.create_transaction_offer(
customer_id=customer_id,
transaction_id=transaction_id,
@@ -223,6 +227,9 @@ class OfferAnalysis:
logger.error(f"Max eligible amount ({approved_amount}) is less than the minimum offer amount ({offer.min_amount}).")
raise ValueError("You are not eligible for a loan at this time.")
# if approved_amount < 100:
# logger.error(f"Max eligible amount ({approved_amount}) is less than the minimum offer amount ({offer.min_amount}).")
# raise ValueError("You are not eligible for a loan at this time.")
transaction_offer = TransactionOffer.create_transaction_offer(
customer_id=customer_id,
+39
View File
@@ -83,6 +83,10 @@
"description": "Find out more",
"url": "https://www.simbrellang.net"
}
},
{
"name": "Health",
"description": "System health check including DB status."
}
],
"paths": {
@@ -106,6 +110,41 @@
},
"/Repayment": {
"$ref": "swagger/paths/Repayment.json"
},
"/health": {
"get": {
"tags": ["Health"],
"summary": "Health Check",
"description": "Returns service health information including DB connection status.",
"responses": {
"200": {
"description": "Health check successful",
"content": {
"application/json": {
"example": {
"status": "ok",
"db_status": "Connection Successful",
"events_service_status": "healthy",
"error": []
}
}
}
},
"500": {
"description": "Health check failed",
"content": {
"application/json": {
"example": {
"status": "ok",
"db_status": "Connection Failed",
"events_service_status": "unhealthy",
"error":["could not connect to server: Connection refused"]
}
}
}
}
}
}
}
},
"components": {