diff --git a/README.md b/README.md index 50ac16f8..054d8df9 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ TimeTracker has been continuously enhanced with powerful new features! Here's wh > **πŸ“‹ For complete release history, see [CHANGELOG.md](CHANGELOG.md)** **Current version** is defined in `setup.py` (single source of truth). See [CHANGELOG.md](CHANGELOG.md) for versioned release history. -- πŸ“± **Native Mobile & Desktop Apps** β€” Flutter mobile app (iOS/Android) and Electron desktop app with time tracking, offline support, and API integration ([Build Guide](docs/build/BUILD.md), [Docs](docs/mobile-desktop-apps/README.md)) +- πŸ“± **Native Mobile & Desktop Apps** β€” Flutter mobile app (iOS/Android) and Electron desktop app with time tracking, offline support, and API integration ([Build Guide](scripts/README-BUILD.md), [Docs](docs/mobile-desktop-apps/README.md)) - πŸ“‹ **Project Analysis & Documentation** β€” Comprehensive project analysis and documentation updates - πŸ”§ **Version Consistency** β€” Fixed version inconsistencies across documentation files @@ -290,7 +290,7 @@ TimeTracker includes **130+ features** across 13 major categories. See the [Comp - **Docker Ready** β€” Deploy in minutes with Docker Compose - **Database Flexibility** β€” PostgreSQL for production, SQLite for testing - **Responsive Design** β€” Mobile-first design works perfectly on desktop, tablet, and mobile -- **Native Mobile & Desktop Apps** β€” Flutter mobile app (iOS/Android) and Electron desktop app with time tracking, offline support, and API integration ([Build Guide](docs/build/BUILD.md), [Docs](docs/mobile-desktop-apps/README.md)) +- **Native Mobile & Desktop Apps** β€” Flutter mobile app (iOS/Android) and Electron desktop app with time tracking, offline support, and API integration ([Build Guide](scripts/README-BUILD.md), [Docs](docs/mobile-desktop-apps/README.md)) - **Real-time Sync** β€” WebSocket support for live updates across devices - **Automatic Backups** β€” Scheduled database backups (configurable) - **Progressive Web App (PWA)** β€” Install as mobile app with offline support and background sync @@ -631,7 +631,7 @@ Comprehensive documentation is available in the [`docs/`](docs/) directory. See **Integrations & Apps:** - **[Mobile & Desktop Apps](docs/mobile-desktop-apps/README.md)** β€” Flutter mobile and Electron desktop apps -- **[Build Guide (Mobile & Desktop)](docs/build/BUILD.md)** β€” Build scripts for Android, iOS, Windows, macOS, Linux +- **[Build Guide (Mobile & Desktop)](scripts/README-BUILD.md)** β€” Build scripts for Android, iOS, Windows, macOS, Linux - **[Peppol & ZugFerd e-Invoicing](docs/admin/configuration/PEPPOL_EINVOICING.md)** β€” Peppol sending and ZugFerd/Factur-X PDF embedding (EN 16931) - **[API Documentation](docs/api/REST_API.md)** β€” REST API reference - **[API Token Scopes](docs/api/API_TOKEN_SCOPES.md)** β€” Token permissions @@ -963,7 +963,7 @@ This starts: #### πŸ“± Native Mobile & Desktop Apps - βœ… **Flutter Mobile App** β€” Native iOS and Android apps with time tracking, calendar view, offline sync, and API token authentication - βœ… **Electron Desktop App** β€” Windows, macOS, and Linux desktop app with system tray, time tracking, and offline support -- βœ… **Build Scripts** β€” Cross-platform build scripts for mobile and desktop ([BUILD.md](docs/build/BUILD.md)) +- βœ… **Build Scripts** β€” Cross-platform build scripts for mobile and desktop ([Build Guide](scripts/README-BUILD.md)) #### πŸ—οΈ Architecture & Performance - βœ… **Service Layer Migration** β€” Routes migrated to service layer pattern diff --git a/docs/ADVANCED_PERMISSIONS.md b/docs/ADVANCED_PERMISSIONS.md index 48adab9b..4cb3ba4e 100644 --- a/docs/ADVANCED_PERMISSIONS.md +++ b/docs/ADVANCED_PERMISSIONS.md @@ -225,6 +225,10 @@ if current_user.has_all_permissions('create_invoices', 'send_invoices'): For quote listing/detail routes, users with quote-management permissions (for example `edit_quotes`) may need access beyond "own quotes only" in order to open the quote they just edited from redirects and list views. Keep list/detail scoping aligned with route-level permission intent to avoid "edit succeeds but view returns 404/redirect" behavior. +Current implementation uses a shared quote-access helper so quote list/detail scope matches edit capability: admins and users with `edit_quotes` can access quote list/detail across owners, while users without that permission remain scoped to their own quotes. + +Validation reference: behavior is covered by quote web/API regression tests in `tests/test_routes/test_quotes_web.py` and `tests/test_routes/test_api_v1_quotes_refactored.py`. + #### Using Permission Decorators Protect routes with permission decorators: @@ -361,6 +365,8 @@ This command updates permissions and roles without affecting user assignments. GET /api/users//permissions ``` +Access expectations: intended for administrator use (admin session / admin-equivalent role). + Returns: ```json { @@ -381,6 +387,8 @@ Returns: GET /api/roles//permissions ``` +Access expectations: intended for administrator use (admin session / admin-equivalent role). + Returns: ```json { diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 67fc3177..5e2f4c3e 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -119,7 +119,7 @@ See [Contributing – Testing](docs/development/CONTRIBUTING.md#testing) for mor - **Web app:** No separate frontend build required; Tailwind and static assets are served as-is (or built via your pipeline if you use one). Run the app with `flask run` or `python app.py`. - **Docker image:** `docker build -t timetracker .` from repo root. See [Docker Compose Setup](docs/admin/configuration/DOCKER_COMPOSE_SETUP.md). -- **Mobile/Desktop:** See [BUILD.md](build/BUILD.md) and [mobile-desktop-apps/README.md](mobile-desktop-apps/README.md) for Flutter and Electron build steps. +- **Mobile/Desktop:** See [Build Guide](../scripts/README-BUILD.md) and [mobile-desktop-apps/README.md](mobile-desktop-apps/README.md) for Flutter and Electron build steps. ## Contributing diff --git a/docs/admin/deployment/VERSION_MANAGEMENT.md b/docs/admin/deployment/VERSION_MANAGEMENT.md index 45630468..884f806b 100644 --- a/docs/admin/deployment/VERSION_MANAGEMENT.md +++ b/docs/admin/deployment/VERSION_MANAGEMENT.md @@ -2,7 +2,7 @@ This document describes the comprehensive version management system for TimeTracker that provides flexible versioning for both GitHub releases and build numbers. -**For contributors:** Application version is defined only in **setup.py**. Do not duplicate it in README or other docs. Desktop and mobile builds may use their own version numbers; see [BUILD.md](../../build/BUILD.md) and repo scripts. +**For contributors:** Application version is defined only in **setup.py**. Do not duplicate it in README or other docs. Desktop and mobile builds may use their own version numbers; see the [Build Guide](../../../scripts/README-BUILD.md) and repo scripts. **OpenAPI (`/api/openapi.json`):** The `info.version` field uses the same resolution as the in-app version helpers: environment variables **`TIMETRACKER_VERSION`** or **`APP_VERSION`** override the value read from **`setup.py`**; see `get_version_from_setup()` in `app/config/analytics_defaults.py` and `openapi_spec()` in `app/routes/api_docs.py`. diff --git a/docs/api/API_TOKEN_SCOPES.md b/docs/api/API_TOKEN_SCOPES.md index fb53f460..6d15a70a 100644 --- a/docs/api/API_TOKEN_SCOPES.md +++ b/docs/api/API_TOKEN_SCOPES.md @@ -206,6 +206,33 @@ curl -X POST https://your-domain.com/api/v1/clients \ --- +### Quotes + +#### `read:quotes` +**Grants**: List and view quotes +**Endpoints**: +- `GET /api/v1/quotes` - List quotes +- `GET /api/v1/quotes/{id}` - Get quote details + +**Use Cases**: +- Client portal and CRM read integrations +- Quote status dashboards +- External systems that only need quote visibility + +#### `write:quotes` +**Grants**: Create, update, and delete quotes +**Endpoints**: +- `POST /api/v1/quotes` - Create quote +- `PUT /api/v1/quotes/{id}` - Update quote +- `DELETE /api/v1/quotes/{id}` - Delete quote + +**Use Cases**: +- Quote generation from external systems +- Automated quote updates and status sync +- Back-office quote lifecycle tools + +--- + ### Invoices #### `read:invoices` @@ -368,6 +395,8 @@ read:tasks write:tasks read:clients write:clients +read:quotes +write:quotes read:reports ``` **Use For**: Personal automation, full-featured integrations @@ -565,6 +594,8 @@ curl -X POST https://your-domain.com/api/v1/projects \ | `write:tasks` | βœ… | βœ… | ❌ | Manage tasks | | `read:clients` | βœ… | ❌ | ❌ | View clients | | `write:clients` | βœ… | βœ… | ❌ | Manage clients | +| `read:quotes` | βœ… | ❌ | ❌ | View quotes | +| `write:quotes` | βœ… | βœ… | ❌ | Manage quotes | | `read:reports` | βœ… | ❌ | ❌ | View own reports | | `read:users` | βœ… | ❌ | Partial | `/users/me` for all, `/users` admin only | | `admin:all` | βœ… | βœ… | βœ… | Full access | diff --git a/docs/api/REST_API.md b/docs/api/REST_API.md index d216f8ae..82d91bcd 100644 --- a/docs/api/REST_API.md +++ b/docs/api/REST_API.md @@ -86,6 +86,8 @@ API tokens use scopes to control access to resources. When creating a token, sel | `write:tasks` | Create and update tasks | | `read:clients` | View clients | | `write:clients` | Create and update clients | +| `read:quotes` | View quotes | +| `write:quotes` | Create and update quotes | | `read:reports` | View reports and analytics | | `read:users` | View user information | | `admin:all` | Full administrative access (use with caution) | @@ -695,6 +697,54 @@ POST /api/v1/clients } ``` +### Quotes + +#### List Quotes +``` +GET /api/v1/quotes +``` + +**Required Scope:** `read:quotes` + +#### Get Quote +``` +GET /api/v1/quotes/{quote_id} +``` + +**Required Scope:** `read:quotes` + +#### Create Quote +``` +POST /api/v1/quotes +``` + +**Required Scope:** `write:quotes` + +**Request Body (example):** +```json +{ + "client_id": 1, + "title": "Website maintenance retainer", + "description": "Monthly maintenance and support", + "tax_rate": 21.0, + "currency_code": "EUR" +} +``` + +#### Update Quote +``` +PUT /api/v1/quotes/{quote_id} +``` + +**Required Scope:** `write:quotes` + +#### Delete Quote +``` +DELETE /api/v1/quotes/{quote_id} +``` + +**Required Scope:** `write:quotes` + ### Inventory Inventory endpoints require the **inventory module** to be enabled (Admin settings). They use `read:projects` and `write:projects` scopes. diff --git a/docs/development/CONTRIBUTOR_GUIDE.md b/docs/development/CONTRIBUTOR_GUIDE.md index fdeae51e..0223ffa8 100644 --- a/docs/development/CONTRIBUTOR_GUIDE.md +++ b/docs/development/CONTRIBUTOR_GUIDE.md @@ -87,7 +87,7 @@ Run the full test suite before opening a PR. Add tests for new behavior (e.g. in ## Versioning - **Application version**: Defined **only** in `setup.py`. Do not duplicate it in README or other docs. -- **Desktop / mobile**: Desktop and mobile builds may use their own version numbers; see [BUILD.md](../build/BUILD.md) and repo scripts. Align with app version when releasing together. +- **Desktop / mobile**: Desktop and mobile builds may use their own version numbers; see [Build Guide](../../scripts/README-BUILD.md) and repo scripts. Align with app version when releasing together. - **Releases and Docker images**: Tagging, GitHub releases, and image publishing are in [VERSION_MANAGEMENT.md](../admin/deployment/VERSION_MANAGEMENT.md) and [RELEASE_PROCESS.md](../admin/deployment/RELEASE_PROCESS.md). **For contributors**: When updating the app version, change only `setup.py`. Do not add the version number to README, FEATURES_COMPLETE, or PROJECT_STRUCTURE. diff --git a/docs/development/RBAC_PERMISSION_MODEL.md b/docs/development/RBAC_PERMISSION_MODEL.md index f8ca5a1b..59658bc5 100644 --- a/docs/development/RBAC_PERMISSION_MODEL.md +++ b/docs/development/RBAC_PERMISSION_MODEL.md @@ -34,12 +34,33 @@ These blueprints use only `@login_required`. Any logged-in user can access the r **Examples:** deals, leads, invoices (main routes), timer, reports, calendar, expenses (main routes), main dashboard, time_approvals, contacts, tasks, client_notes, budget_alerts, payments, recurring_invoices, etc. +### Quotes access nuance + +Quotes use permission checks plus scope logic aligned to effective capabilities. In practice: + +- users with `edit_quotes` are allowed quote list/detail visibility beyond own-created quotes so post-edit redirects and detail pages remain accessible; +- users without quote-management permissions remain scoped to their own quotes; +- admins retain full access. + +This behavior is implemented via shared quote access helpers (for list/detail scope parity) and is regression-tested in `tests/test_routes/test_quotes_web.py`. + ## When to add permission decorators - **New admin-only or sensitive feature:** Use `@admin_or_permission_required("appropriate_permission")` and define the permission in the permission system if it does not exist. - **New feature for all users:** Use only `@login_required`. - **Existing β€œlogin only” route:** Leave as-is unless you are explicitly tightening access; then add a permission and document it in ADVANCED_PERMISSIONS.md. +## Denial behavior in web routes + +For UI routes protected by permission decorators, unauthorized non-admin users can be denied in two valid ways depending on route and UX flow: + +- direct `403 Forbidden` response, or +- redirect to a page that returns `200` and shows an access/error message (for example when `follow_redirects=True` in tests). + +Keep tests and docs tolerant of both outcomes where the user is denied access but not shown privileged content (see `tests/test_permissions_routes.py`). + ## API v1 (REST) REST API v1 uses API token scopes (e.g. `read:deals`, `write:time_entries`) rather than web permission names. See [API Token Scopes](../api/API_TOKEN_SCOPES.md) and [REST_API.md](../api/REST_API.md). + +Quotes in API v1 require `read:quotes` for list/detail and `write:quotes` for create/update/delete (`/api/v1/quotes*`). diff --git a/docs/guides/QUICK_START_GUIDE.md b/docs/guides/QUICK_START_GUIDE.md index e0e08ea0..921bff32 100644 --- a/docs/guides/QUICK_START_GUIDE.md +++ b/docs/guides/QUICK_START_GUIDE.md @@ -256,9 +256,9 @@ print(f"Jobs: {scheduler.get_jobs()}") | Feature | Model | Routes | Template | |---------|-------|--------|----------| -| Time Entry Templates | `app/models/time_entry_template.py` | TBD | TBD | -| Activity Feed | `app/models/activity.py` | TBD | TBD | -| User Preferences | `app/models/user.py` | TBD | TBD | +| Time Entry Templates | `app/models/time_entry_template.py` | `app/routes/api_v1.py` (`/api/v1/time-entry-templates`) | API-driven (consumed by clients) | +| Activity Feed | `app/models/activity.py` | `app/routes/main.py` (dashboard feed), `app/routes/projects.py` (project activity) | `app/templates/dashboard.html`, `app/templates/projects/view.html` | +| User Preferences | `app/models/user.py` | `app/routes/user.py` (`/settings`, `/api/preferences`) | `app/templates/user/settings.html` | | Excel Export | `app/utils/excel_export.py` | `app/routes/reports.py` | Add button | | Email Notifications | `app/utils/email.py` | Automatic | `app/templates/email/` | | Scheduled Tasks | `app/utils/scheduled_tasks.py` | Automatic | N/A |