Merge pull request 'chore(bug_fix): Update payment redirect and scheduler job for deleting document id' (#3) from feature/document_clean_up_chore into dev
Reviewed-on: freeleaps/freeleaps-service-hub#3 Reviewed-by: dax.li <dl@mathmast.com>
This commit is contained in:
commit
d3248f43a0
26
CHANGELOG.md
Normal file
26
CHANGELOG.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
## [1.1.1](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/compare/v1.1.0...v1.1.1) (2025-03-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* invalid import path for app config ([4dfbab4](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/commit/4dfbab4d4de83fbe5140c05071d8138cb09ef688))
|
||||||
|
|
||||||
|
# [1.1.0](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/compare/v1.0.0...v1.1.0) (2025-03-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **observability:** add configuration options and implement metrics/probes APIs ([d5e42d3](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/commit/d5e42d31a4ce1ac64f6c5dcf5688c0acae1fdaa6))
|
||||||
|
* **probes:** add metrics and probes APIs for application health checks ([9754576](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/commit/9754576d28066c9805e5e4673e03fd79b3a603bd))
|
||||||
|
|
||||||
|
# 1.0.0 (2025-03-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **rabbitmq:** correct syntax for port and virtual host parameters in AsyncMQClient ([78c7217](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/commit/78c72179ec3fdb15d4af01bee15a441f0e383638))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **notification:** add rabbitmq credentials relates notification services configs ([853d817](https://dev.azure.com/freeleaps/freeleaps-service-hub/_git/freeleaps-service-hub/commit/853d81793332513e89286d61429444d520252c27))
|
||||||
@ -1,6 +1,7 @@
|
|||||||
from common.config.app_settings import app_settings
|
from common.config.app_settings import app_settings
|
||||||
from backend.content.models import DocumentDoc
|
from backend.content.models import DocumentDoc
|
||||||
from backend.document.models import BasicProfileDoc
|
from backend.document.models import BasicProfileDoc
|
||||||
|
from datetime import datetime, timezone
|
||||||
import httpx
|
import httpx
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
@ -53,9 +54,12 @@ class DocumentManager:
|
|||||||
print(f"Failed to queue deletion: {response.text}")
|
print(f"Failed to queue deletion: {response.text}")
|
||||||
|
|
||||||
async def cleanup_document(self):
|
async def cleanup_document(self):
|
||||||
|
# Get today's date at midnight (UTC)
|
||||||
|
today_start = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
# Corrected query with regex
|
# Corrected query with regex
|
||||||
documents = await DocumentDoc.find(
|
documents = await DocumentDoc.find(
|
||||||
{"created_by": {"$regex": "^content-service-"}}
|
{"created_by": {"$regex": "^content-service-"},
|
||||||
|
"create_time": {"$lt": today_start}}
|
||||||
).to_list()
|
).to_list()
|
||||||
|
|
||||||
if documents:
|
if documents:
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
from apscheduler.triggers.date import DateTrigger
|
from apscheduler.triggers.date import DateTrigger
|
||||||
|
from apscheduler.triggers.cron import CronTrigger
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from scheduler.refresh_sharepoint_content_job import (
|
from scheduler.refresh_sharepoint_content_job import (
|
||||||
refresh_sharepoint_content_job,
|
refresh_sharepoint_content_job,
|
||||||
@ -28,15 +29,11 @@ async def register_job(scheduler: AsyncIOScheduler):
|
|||||||
"date",
|
"date",
|
||||||
run_date=datetime(2025, 2, 7, 20, 0, 0),
|
run_date=datetime(2025, 2, 7, 20, 0, 0),
|
||||||
)
|
)
|
||||||
# Register cleanup_document_job as a one-time job
|
|
||||||
# This job is just one-time job for removing many unused documents
|
await init_lock(ScheduleJobLocker.CLEANUP_DOCUMENT_JOB_LOCKER)
|
||||||
# Run already, now comment it out
|
scheduler.add_job(
|
||||||
# await init_lock(ScheduleJobLocker.CLEANUP_DOCUMENT_JOB_LOCKER)
|
cleanup_document_job,
|
||||||
# execution_time = datetime.now() + timedelta(
|
trigger=CronTrigger(hour=2, minute=0), # Runs every day at 2:00 AM
|
||||||
# seconds=60
|
id="cleanup_document_daily",
|
||||||
# ) # Schedule to run 60 seconds from now
|
)
|
||||||
# scheduler.add_job(
|
|
||||||
# cleanup_document_job, # Job function
|
|
||||||
# trigger=DateTrigger(run_date=execution_time), # One-time trigger
|
|
||||||
# id="cleanup_document_one_time", # Optional: Give the job an ID
|
|
||||||
# )
|
|
||||||
|
|||||||
@ -86,27 +86,45 @@ class NotificationManager:
|
|||||||
properties: dict,
|
properties: dict,
|
||||||
region: Optional[UserRegion] = None,
|
region: Optional[UserRegion] = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
# leverage the information in properties to enrich the message.
|
# Default region to international if not set
|
||||||
message_subject = None
|
|
||||||
message = None
|
|
||||||
if subject.lower() == "payment":
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Default region to be international if not set
|
|
||||||
if region is None:
|
if region is None:
|
||||||
region = UserRegion.OTHER
|
region = UserRegion.OTHER
|
||||||
|
|
||||||
message_subject = SystemNotifications[region][subject.lower()][event.lower()][
|
subject_lower = subject.lower()
|
||||||
"message_subject"
|
event_lower = event.lower()
|
||||||
]
|
|
||||||
message = SystemNotifications[region][subject.lower()][event.lower()]["message"]
|
|
||||||
|
|
||||||
if event.lower() == "authentication":
|
try:
|
||||||
|
# Get message template and subject from SystemNotifications
|
||||||
|
notification_config = SystemNotifications[region][subject_lower][event_lower]
|
||||||
|
message = notification_config["message"]
|
||||||
|
message_subject = notification_config["message_subject"]
|
||||||
|
|
||||||
|
# Handle authentication specific formatting
|
||||||
|
if event_lower == "authentication" and "auth_code" in properties:
|
||||||
message = message.format(properties["auth_code"])
|
message = message.format(properties["auth_code"])
|
||||||
if not message:
|
|
||||||
raise RuntimeError("unsupported event:{}".format(event))
|
# Append content_text if it exists in properties
|
||||||
|
if properties.get("content_text"):
|
||||||
|
if isinstance(properties["content_text"], dict):
|
||||||
|
# If content_text is a dictionary, use format with kwargs
|
||||||
|
message = message.format(**properties["content_text"])
|
||||||
|
elif isinstance(properties["content_text"], str):
|
||||||
|
# If content_text is a string, append it with proper spacing
|
||||||
|
content = properties["content_text"].strip()
|
||||||
|
if message and content:
|
||||||
|
# Use HTML line breaks for email compatibility
|
||||||
|
message = f"{message.rstrip()}<br><br>{content}"
|
||||||
|
else:
|
||||||
|
# If either is empty, just use the non-empty one
|
||||||
|
message = message or content
|
||||||
|
|
||||||
return message, message_subject
|
return message, message_subject
|
||||||
|
|
||||||
|
except KeyError as e:
|
||||||
|
raise RuntimeError(f"Unsupported configuration - subject: {subject_lower}, event: {event_lower}, error: {str(e)}")
|
||||||
|
except ValueError as e:
|
||||||
|
raise RuntimeError(f"Invalid message format - error: {str(e)}")
|
||||||
|
|
||||||
async def send_in_app_notification(
|
async def send_in_app_notification(
|
||||||
self, receiver_id: str, subject: str, event: str, properties: dict = None
|
self, receiver_id: str, subject: str, event: str, properties: dict = None
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@ -14,6 +14,7 @@ from webapi.providers import metrics
|
|||||||
from .freeleaps_app import FreeleapsApp
|
from .freeleaps_app import FreeleapsApp
|
||||||
from common.config.app_settings import app_settings
|
from common.config.app_settings import app_settings
|
||||||
|
|
||||||
|
from prometheus_fastapi_instrumentator import Instrumentator
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
def create_app() -> FastAPI:
|
||||||
logging.info("App initializing")
|
logging.info("App initializing")
|
||||||
@ -38,6 +39,8 @@ def create_app() -> FastAPI:
|
|||||||
|
|
||||||
# Call the custom_openapi function to change the OpenAPI version
|
# Call the custom_openapi function to change the OpenAPI version
|
||||||
customize_openapi_security(app)
|
customize_openapi_security(app)
|
||||||
|
# expose prometheus metrics
|
||||||
|
Instrumentator().instrument(app).expose(app)
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,14 @@ class StripeManager:
|
|||||||
async def create_account_link(self, account_id: str, link_type: str = "account_onboarding") -> Optional[str]:
|
async def create_account_link(self, account_id: str, link_type: str = "account_onboarding") -> Optional[str]:
|
||||||
account = stripe.Account.retrieve(account_id)
|
account = stripe.Account.retrieve(account_id)
|
||||||
# For account_update, try to show dashboard if TOS is accepted
|
# For account_update, try to show dashboard if TOS is accepted
|
||||||
|
|
||||||
|
self.module_logger.log_info("create_account_link urls",
|
||||||
|
{
|
||||||
|
"redirect_url": "{}/work".format(self.site_url_root),
|
||||||
|
"refresh_url": "{}/front-door".format(self.site_url_root),
|
||||||
|
"return_url": "{}/work".format(self.site_url_root)
|
||||||
|
}
|
||||||
|
)
|
||||||
if link_type == "account_update" and account.tos_acceptance.date:
|
if link_type == "account_update" and account.tos_acceptance.date:
|
||||||
login_link = stripe.Account.create_login_link(
|
login_link = stripe.Account.create_login_link(
|
||||||
account_id,
|
account_id,
|
||||||
@ -284,10 +292,10 @@ class StripeManager:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mode="payment",
|
mode="payment",
|
||||||
success_url="{}/work-space".format(
|
success_url="{}/projects".format(
|
||||||
self.site_url_root
|
self.site_url_root
|
||||||
), # needs to be set, local: http://localhost/
|
), # needs to be set, local: http://localhost/
|
||||||
cancel_url="{}/work-space".format(self.site_url_root),
|
cancel_url="{}/projects".format(self.site_url_root),
|
||||||
)
|
)
|
||||||
|
|
||||||
if session:
|
if session:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user