Files
TimeTracker/docs
Dries Peeters 3e7b7ab787 feat: add per-user GitHub, Google Calendar, and Slack connectors
Three new opt-in integration connectors that plug into the existing
`app/integrations/base.py:BaseConnector` pattern and the integrations
settings UI. Each connector subclasses `BaseConnector`, persists its
state inside the existing `Integration.config` JSONB (no new tables),
encrypts every secret at rest via `app/utils/secret_crypto`, and
degrades gracefully when the integration row is missing or
`is_active=False` -- every method returns
`{"ok": false, "error": "Integration not configured"}` without
raising, so the timer, exports, and dashboards keep working when a
connector is disabled or broken.

All third-party HTTP calls go through `requests` with a 10-second
timeout and a `try/except requests.RequestException`. Tokens are
never written to logs in their raw form -- only short
`xoxb-...` / `ghp_...` truncations.

GitHub connector (`app/integrations/github_connector.py`, provider
key `github_connector`):
  - Webhook receiver at `POST /api/integrations/github/webhook`
    verifies `X-Hub-Signature-256` with HMAC-SHA256 against the
    per-integration webhook secret before reading the payload.
  - Handles `issues.opened` (creates a task with
    `external_ref="github_issue_{n}"`, mapped priority and `todo`
    status), `issues.assigned` (optionally starts a timer for the
    linked TimeTracker user when `users.github_username` matches),
    `issues.closed` (marks the existing task `done`), and `ping`.
  - Manual sync (`POST /api/integrations/github/sync`, admin only)
    pulls open issues from
    `GET /repos/{owner}/{repo}/issues?state=open&per_page=50` and
    upserts tasks by `external_ref`. Optional `label_filter`.

Google Calendar connector (`app/integrations/google_calendar_connector.py`,
provider key `google_calendar_connector`):
  - OAuth2 flow at `/integrations/google/{connect,callback,disconnect}`
    using raw `requests` against
    `https://oauth2.googleapis.com/token`. Tokens (`access_token`,
    `refresh_token`, `token_expiry`) are stored encrypted in
    `Integration.config`. `client_id`/`client_secret` come from
    Flask config (`GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`) and are
    never hardcoded.
  - `_refresh_token_if_needed()` refreshes within 5 minutes of expiry
    on every API call.
  - `sync()` supports `import` / `export` / `both`:
    * import: pulls dated events from the configured `calendar_id`
      over the last `sync_days_back` days (clamped 1-30), skips
      all-day events and anything tagged `[TT]` or already linked via
      `gcal:{event_id}` in the notes of an existing `TimeEntry`.
    * export: posts completed entries created since `last_sync_at`
      back to Google as `[TT] {project} -- {task or notes}` events
      with `timeZone: "UTC"`.
  - `revoke()` calls `https://oauth2.googleapis.com/revoke` and
    wipes the stored tokens.
  - APScheduler job `google_calendar_sync` runs every 30 minutes;
    each user is wrapped in `try/except` so one broken token cannot
    block the rest.

Slack connector (`app/integrations/slack_connector.py`, provider key
`slack_connector`):
  - Webhook receiver at `POST /api/integrations/slack/events`
    verifies `X-Slack-Signature` (HMAC-SHA256 of
    `v0:{timestamp}:{body}`) and rejects requests older than 5
    minutes. Replies to Slack's URL verification handshake
    immediately.
  - Slash command `/tt` supports `start [project]` (id or
    case-insensitive partial name match against the user's allowed
    projects), `stop`, `status`, `today` (via
    `notification_service.get_today_summary_for_user`), and an
    in-place help text fallback. Every reply is ephemeral JSON so it
    fits inside Slack's 3-second budget without touching
    `response_url`.
  - `notify_timer_started` / `notify_timer_stopped` post a
    stopwatch/checkmark message to the configured channel. Wired
    into both the page route (`app/routes/timer.py`) and the JSON
    API (`app/routes/api.py`) as a fire-and-forget hook: the import
    + call are wrapped in `try/except` and only log at `DEBUG` on
    failure, so Slack outages can't slow down the timer flow.
  - `post_daily_summary` posts a daily roll-up; APScheduler job
    `slack_daily_summary` runs every 30 minutes and matches each
    user's configured `HH:MM` against the window.

Plumbing and storage:
  - New blueprint `app/routes/integrations_webhooks.py` registers
    the webhook receivers (`csrf.exempt`, signature-verified) plus a
    uniform `config`/`status`/`test` API surface
    (`/api/integrations/{github,google,slack}/{config,status,test}`)
    used by the settings UI. Optional-registered in
    `app/blueprint_registry.py`.
  - Alembic revision `155_add_integration_columns`:
    * `users.github_username` (String(100), nullable) - GitHub login
      join key for the assignment auto-start-timer flow.
    * `tasks.external_ref` (String(200), nullable, indexed) -
      canonical external id for connector-created tasks; the new
      index lets webhook receivers de-duplicate cheaply.
    Both columns are added defensively (inspector-checked) so the
    migration is safe to re-run.
  - New cards in `app/templates/integrations/_connector_cards.html`
    (included by `templates/integrations/list.html`) drive the
    Personal connectors UI -- Tailwind CSS only, vanilla JS, per-card
    status fetch, save, test, and sync actions.

Documentation:
  - `docs/integrations/README.md` indexes all built-in connectors.
  - `docs/integrations/GITHUB_CONNECTOR.md`,
    `docs/integrations/GOOGLE_CALENDAR.md`, and
    `docs/integrations/SLACK.md` cover setup, OAuth/webhook wiring,
    config fields, endpoints, and operational notes for each
    connector.
  - `docs/api/REST_API.md` lists the new endpoints under a new
    "Personal integration connectors" subsection.
  - `CHANGELOG.md` notes the feature under the [Unreleased] section.

`LLMService`, `TimeTrackingService`, `ForecastService`, and the
`Integration` model schema are intentionally untouched -- only
`users` and `tasks` gain columns via migration.
2026-05-15 10:45:30 +02:00
..

TimeTracker Documentation

Welcome to the comprehensive TimeTracker documentation. Everything you need to install, configure, use, and contribute to TimeTracker.



🗺️ Documentation Map

docs/
├── 👤 User Documentation
│   ├── Getting Started
│   ├── Feature Guides
│   └── User Guides
│
├── 🔧 Administrator Documentation
│   ├── Configuration
│   ├── Deployment
│   ├── Security
│   └── Monitoring
│
├── 👨‍💻 Developer Documentation
│   ├── Contributing
│   ├── Architecture
│   ├── Development Setup
│   └── Testing
│
└── 📚 Reference
    ├── API Documentation
    ├── Implementation Notes
    └── Reports

👤 User Documentation

Getting Started

User Guides

Feature Documentation

See features/ for additional feature documentation.


🔧 Administrator Documentation

Configuration

Deployment

Security

Monitoring

📖 See admin/README.md for complete administrator documentation


👨‍💻 Developer Documentation

Terminology

Use consistent terms in code, API, and user-facing copy: time entry / time entries, client, project, task, invoice. See Product/UX Audit for full context and naming recommendations.

Getting Started

Development Setup

Testing

CI/CD

Technical Documentation

Product & Roadmap

📖 See development/README.md for complete developer documentation


📚 API Documentation

📖 See api/README.md for complete API documentation

Quick API Examples

Authentication:

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
     https://your-domain.com/api/v1/projects

Create Time Entry:

curl -X POST -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"project_id": 1, "start_time": "2025-01-27T09:00:00", "end_time": "2025-01-27T17:00:00"}' \
     https://your-domain.com/api/v1/time-entries

See REST API Documentation for complete examples and endpoint details.


🚀 Installation & Deployment

Quick Start

  1. Installation Guide — Step-by-step installation (root)
  2. Getting Started Guide — Complete beginner tutorial
  3. Docker Compose Setup — Recommended deployment method
  4. Requirements — System requirements
  5. Uninstall / remove data — Tear down containers, volumes, and optional AI (Ollama)

Database & Migrations


🛠️ Troubleshooting

Common Issues

Quick Fixes

  • Port conflicts: Change PORT=8081 in docker-compose command
  • Database issues: Run docker-compose down -v && docker-compose up -d
  • Permission errors: Check file ownership with chown -R $USER:$USER .
  • Migration failures: See Database Migrations

📝 Additional Resources

Implementation Notes

Recent improvements and changes are documented in implementation-notes/:

  • Layout & UX improvements
  • Feature implementations
  • Bug fixes and improvements
  • Architecture changes

Reports & Analysis

Analysis reports and summaries are available in reports/:

  • Bugfix summaries
  • Audit reports
  • Translation analysis

Feature-Specific Documentation

Detailed feature documentation is available in features/:

  • Feature guides
  • Quick start guides
  • Implementation status

User Guides

Additional user guides are available in user-guides/:

  • Step-by-step guides
  • Tips and tricks
  • Best practices

🔍 Documentation by Role

For New Users

  1. Start with Main README for product overview
  2. Follow Getting Started Guide for installation
  3. Review Requirements to check system compatibility
  4. Explore Feature Documentation to learn features

For Administrators

  1. Follow Docker Compose Setup for deployment
  2. Review Version Management for updates
  3. Set up Email Configuration if needed
  4. Configure OIDC/SSO for authentication
  5. See admin/README.md for complete admin documentation

For Developers

  1. Read Contributing Guidelines before making changes
  2. Review Project Structure to understand codebase
  3. Check Solution Guide for technical patterns
  4. Use Local Testing with SQLite for development
  5. See development/README.md for complete developer documentation

For Troubleshooting

  1. Check Docker Startup Troubleshooting
  2. Review Database Connection Issues
  3. Consult Solution Guide for common problems
  4. Check specific feature documentation if issue is feature-related

📁 Documentation Structure

docs/
├── README.md                          # This file - documentation index
├── GETTING_STARTED.md                 # Beginner tutorial
├── REQUIREMENTS.md                    # System requirements
├── FEATURES_COMPLETE.md               # Complete features list
│
├── guides/                            # User-facing guides
│   ├── DEPLOYMENT_GUIDE.md
│   ├── QUICK_START_GUIDE.md
│   └── ...
│
├── admin/                             # Administrator documentation
│   ├── configuration/                 # Configuration guides
│   ├── deployment/                    # Deployment guides
│   ├── security/                      # Security documentation
│   └── monitoring/                    # Monitoring & analytics
│
├── development/                       # Developer documentation
│   ├── CONTRIBUTING.md
│   ├── CODE_OF_CONDUCT.md
│   ├── PROJECT_STRUCTURE.md
│   └── ...
│
├── api/                               # API documentation
│   ├── REST_API.md
│   ├── API_TOKEN_SCOPES.md
│   └── ...
│
├── features/                          # Feature-specific guides
│   └── ...
│
├── implementation-notes/              # Development notes
│   └── ...
│
├── testing/                           # Testing documentation
│   └── ...
│
├── reports/                           # Reports & analysis
│   └── ...
│
├── user-guides/                       # Additional user guides
│   └── ...
│
└── cicd/                              # CI/CD documentation
    └── ...

📋 Documentation Audit

A summary of doc accuracy, outdated content, gaps, and contradictions is in DOCS_AUDIT.md. Use it when updating or reorganizing docs.


🤝 Contributing to Documentation

Found an error? Want to improve the docs?

  1. Check the Contributing Guidelines
  2. Make your changes to the relevant documentation file
  3. Test that all links work correctly
  4. Submit a pull request with a clear description

Good documentation helps everyone! 📚


💡 Tips for Using This Documentation

  • Use the search function in your browser (Ctrl/Cmd + F) to find specific topics
  • Follow links to related documentation for deeper understanding
  • Start with Quick Links at the top if you're in a hurry
  • Browse by role using the role-based sections above
  • Check Implementation Notes for recent changes and improvements

Need help? Open an issue or check the troubleshooting section

Want to contribute? See our Contributing Guidelines


⬆ Back to Top