bugs fixed

This commit is contained in:
Aditya Vaish 2025-10-16 10:34:08 +05:30
parent 6037a0dc83
commit 92c0474df4
4 changed files with 88 additions and 23 deletions

View file

@ -5,7 +5,7 @@ A module for retrieving data from ClickUp.
Allows fetching tasks from workspaces and lists.
"""
from datetime import datetime
from datetime import datetime, timezone
from typing import Any
import requests
@ -180,40 +180,79 @@ class ClickUpConnector:
start_timestamp = int(start_datetime.timestamp() * 1000)
end_timestamp = int(end_datetime.timestamp() * 1000)
params = {
# Base parameters for both requests
base_params = {
"page": 0,
"order_by": "created",
"reverse": "true",
"subtasks": "true",
"include_closed": str(include_closed).lower(),
# Date filtering - filter by both created and updated dates
"date_created_gt": start_timestamp,
"date_created_lt": end_timestamp,
"date_updated_gt": start_timestamp,
"date_updated_lt": end_timestamp,
}
all_tasks = []
page = 0
# Request 1: Filter by creation date
created_params = base_params.copy()
created_params.update({
"date_created_gt": start_timestamp,
"date_created_lt": end_timestamp,
})
while True:
params["page"] = page
result = self.make_api_request(f"team/{workspace_id}/task", params)
# Request 2: Filter by update date
updated_params = base_params.copy()
updated_params.update({
"date_updated_gt": start_timestamp,
"date_updated_lt": end_timestamp,
})
if not isinstance(result, dict) or "tasks" not in result:
return [], "Invalid response from ClickUp API"
def fetch_tasks_with_params(params):
"""Helper function to fetch all tasks for given parameters"""
all_tasks = []
page = 0
tasks = result["tasks"]
if not tasks:
break
while True:
params["page"] = page
result = self.make_api_request(f"team/{workspace_id}/task", params)
all_tasks.extend(tasks)
if not isinstance(result, dict) or "tasks" not in result:
return [], "Invalid response from ClickUp API"
# Check if there are more pages
if len(tasks) < 100: # ClickUp returns max 100 tasks per page
break
tasks = result["tasks"]
if not tasks:
break
page += 1
all_tasks.extend(tasks)
# Check if there are more pages
if len(tasks) < 100: # ClickUp returns max 100 tasks per page
break
page += 1
return all_tasks, None
# Fetch tasks created in date range
created_tasks, error = fetch_tasks_with_params(created_params)
if error:
return [], error
# Fetch tasks updated in date range
updated_tasks, error = fetch_tasks_with_params(updated_params)
if error:
return [], error
# Merge and deduplicate tasks by ID
# Use a dictionary to store unique tasks (ID as key)
unique_tasks = {}
# Add created tasks
for task in created_tasks:
unique_tasks[task["id"]] = task
# Add updated tasks (will overwrite duplicates, keeping the latest)
for task in updated_tasks:
unique_tasks[task["id"]] = task
# Convert back to list
all_tasks = list(unique_tasks.values())
if not all_tasks:
return [], "No tasks found in the specified date range."

View file

@ -336,6 +336,8 @@ class ConnectorSchedule(BaseModel, TimestampMixin):
)
schedule_type = Column(SQLAlchemyEnum(ScheduleType), nullable=False)
cron_expression = Column(String(100), nullable=True)
# Timezone for interpreting daily_time and weekly_time (IANA zone name)
timezone = Column(String(50), nullable=False, default="UTC")
# Optional schedule config fields (persist user selections)
daily_time = Column(Time(timezone=False), nullable=True)
weekly_day = Column(Integer, nullable=True) # 0=Mon .. 6=Sun
@ -445,6 +447,11 @@ if config.AUTH_TYPE == "GOOGLE":
"OAuthAccount", lazy="joined"
)
search_spaces = relationship("SearchSpace", back_populates="user")
search_source_connectors = relationship(
"SearchSourceConnector",
back_populates="user",
cascade="all, delete-orphan",
)
search_space_preferences = relationship(
"UserSearchSpacePreference",
back_populates="user",

View file

@ -10,10 +10,11 @@ from sqlalchemy import select, Integer
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.db import get_async_session, Log
from app.db import get_async_session, Log, ConnectorSchedule, SearchSourceConnector
from app.schemas import ConnectorScheduleRead
from app.services.connector_scheduler_service import get_scheduler
from app.users import User, current_active_user
from app.utils.check_ownership import check_ownership
logger = logging.getLogger(__name__)
@ -49,6 +50,7 @@ async def get_scheduler_status(
async def force_execute_schedule(
schedule_id: int,
background_tasks: BackgroundTasks,
session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_active_user),
):
"""
@ -58,6 +60,20 @@ async def force_execute_schedule(
the connector sync for the specified schedule.
"""
try:
# First, verify ownership of the schedule
# Load the schedule and verify the user owns the associated connector
result = await session.execute(
select(ConnectorSchedule).filter(ConnectorSchedule.id == schedule_id)
)
schedule = result.scalars().first()
if not schedule:
raise HTTPException(status_code=404, detail="Schedule not found")
# Verify schedule's connector belongs to user
await check_ownership(session, SearchSourceConnector, schedule.connector_id, user)
# Only after ownership is confirmed, proceed with scheduling
scheduler = await get_scheduler()
# Add the force execution to background tasks
@ -72,6 +88,8 @@ async def force_execute_schedule(
"schedule_id": schedule_id
}
except HTTPException:
raise
except Exception as e:
logger.error(f"Error force executing schedule {schedule_id}: {e}")
raise HTTPException(

View file

@ -14,6 +14,7 @@ class ConnectorScheduleBase(BaseModel):
schedule_type: ScheduleType
cron_expression: str | None = None
is_active: bool = True
timezone: str = "UTC" # IANA timezone name for interpreting daily_time and weekly_time
# Enhanced time selection options
daily_time: Optional[time] = None # For DAILY schedules (default: 02:00)