--- name: "DevOps ↔ ClickUp Sync" client: Oliver status: active tech: [Python, FastAPI, SQLAlchemy, SQLite, Docker, Azure DevOps API, ClickUp API] local_path: /Users/ai_leed/Documents/Projects/Oliver/DevOps_Click_UP_sync deploy: docker-compose up url: http://localhost:8080 tags: [oliver, devops, ado, clickup, sync, webhook] created: 2026-04-14 server: local port: 8080 db: SQLite --- ## Overview DevOps_Click_UP_sync is a bidirectional synchronization service that bridges Azure DevOps and ClickUp, enabling seamless task/work item management across both platforms. It runs as a containerized FastAPI application that listens for webhooks and maintains data consistency between the two systems. The service is designed for teams using both Azure DevOps and ClickUp who need unified task tracking without manual duplication. ## Tech Stack - **Frontend:** N/A (API-only service) - **Backend:** Python 3.x, FastAPI, Uvicorn ASGI server - **Database:** SQLite with SQLAlchemy ORM and async support (aiosqlite) - **Infrastructure:** Docker, Docker Compose - **AI/ML:** N/A - **Key libraries:** FastAPI, SQLAlchemy, httpx (async HTTP client), Pydantic (validation), markdownify (content conversion) ## Architecture The service follows a webhook-based event-driven architecture: ``` ┌─────────────────────────────────────────────────────┐ │ External Systems │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Azure DevOps │ │ ClickUp │ │ │ └────────┬─────────┘ └────────┬─────────┘ │ └───────────┼────────────────────────┼───────────────┘ │ Webhooks │ Webhooks └────────────┬───────────┘ │ ┌────────────────▼─────────────────┐ │ FastAPI Sync Service │ │ ┌──────────────────────────┐ │ │ │ /api/health │ │ │ │ /api/webhook/ado │ │ │ │ /api/webhook/clickup │ │ │ │ /api/sync │ │ │ └──────────────────────────┘ │ └────────────────┬──────────────────┘ │ ┌────────────────▼─────────────────┐ │ SQLite Database (/app/data) │ │ - Sync mappings │ │ - Metadata │ └──────────────────────────────────┘ ``` **Key Design Decisions:** - **Async-first:** All database and HTTP operations use async/await for scalability - **Webhook-driven:** Listens for changes from both platforms rather than polling - **Content conversion:** Uses markdownify to normalize formatting between systems - **Health checks:** Built-in health endpoint for container orchestration - **Persistent storage:** SQLite for tracking sync state and mappings ## Dev Commands ```bash # Install dependencies pip install -r requirements.txt # Create .env file from template cp .env.example .env # Edit .env with your credentials # Run locally (requires Python 3.9+) python -m uvicorn main:app --reload --port 8080 # Build and run with Docker docker-compose up --build # View logs docker-compose logs -f sync-service # Stop services docker-compose down # Access health check curl http://localhost:8080/api/health ``` ## Deployment - **Server:** local (intended for container deployment) - **Deploy:** `docker-compose up -d` - **URL:** Configured via `PUBLIC_URL` env var (e.g., https://your-domain.com) - **Port:** 8080 - **Service:** Docker container managed by docker-compose - **Local path:** /Users/ai_leed/Documents/Projects/Oliver/DevOps_Click_UP_sync **Container details:** - Health check runs every 30s (timeout 10s, 3 retries) - Auto-restart policy: unless-stopped - Volumes: ./data mounted to /app/data (persistent database storage) ## Environment Variables - `ADO_ORGANIZATION` — Azure DevOps organization name - `ADO_PROJECT` — Azure DevOps project name - `ADO_PAT` — Azure DevOps Personal Access Token (authentication) - `CLICKUP_API_TOKEN` — ClickUp API token (format: pk_*) - `CLICKUP_WORKSPACE_ID` — ClickUp workspace identifier - `WEBHOOK_SECRET` — Secret key for validating incoming webhooks - `PUBLIC_URL` — Public domain/URL where this service is accessible (for webhook callbacks) - `LOG_LEVEL` — Logging verbosity (INFO, DEBUG, etc.) - `DATABASE_URL` — SQLite connection string; default: `sqlite+aiosqlite:///./data/sync.db` ## API / Endpoints - `GET /api/health` — Health check endpoint (used by Docker healthcheck) - `POST /api/webhook/ado` — Receives webhook events from Azure DevOps - `POST /api/webhook/clickup` — Receives webhook events from ClickUp - `POST /api/sync` — Manually trigger synchronization (if implemented) ## Known Issues None documented. Ensure webhook payloads are validated with `WEBHOOK_SECRET` to prevent unauthorized sync triggers. ## Git - **Remote:** [Not provided in source files] ## Sessions ### 2026-04-14 – Project catalogued **Done:** Added to Obsidian second brain. --- ## Change Log | Date | Requested | Changed | Files | |------|-----------|---------|-------| | 2026-04-14 | Initial setup | Note created | — |