docs: sync CHANGELOG and implementation status; add CODEBASE_AUDIT

- CHANGELOG: document offline queue replay, inventory scopes, client portal
  reports (date range + CSV), Jira webhook verification; activity feed date
  validation, PEPPOL exception handling, settings redirect, doc sync
- CLIENT_FEATURES_IMPLEMENTATION_STATUS: report date range and CSV export
  marked as implemented
- INCOMPLETE_IMPLEMENTATIONS_ANALYSIS: add Verified 2026-03-16 for webhooks,
  issues permissions, search API, offline queue, error handling
- Add CODEBASE_AUDIT.md with gap analysis and fixed/remaining items
This commit is contained in:
Dries Peeters
2026-03-16 16:44:31 +01:00
parent 3654a6a5d3
commit a50a4ebf2e
4 changed files with 198 additions and 5 deletions
+9
View File
@@ -7,7 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- **Offline queue replay** — Queued requests now store method, headers, and body in a replay-safe form (serializable for localStorage). POST/PUT requests replayed when back online send the same body and method. Legacy queue items (with `options` only) are still replayed via fallback.
- **Inventory API scopes** — New scopes `read:inventory` and `write:inventory` for inventory-only API access. Existing `read:projects` and `write:projects` still grant the same inventory access for backward compatibility.
- **Client portal reports: date range and CSV export** — Reports support optional `days` query param (1365, default 30). Add `?format=csv` to download a CSV of the same report (summary, hours by project, time by date). Export uses the same access control as the reports page.
- **Jira webhook verification** — When a webhook secret is configured in the Jira integration (Connection Settings → Webhook Secret), incoming webhooks are verified using HMAC-SHA256 of the request body. Supported headers: `X-Hub-Signature-256`, `X-Atlassian-Webhook-Signature`, `X-Hub-Signature`. Requests with missing or invalid signature are rejected. If no secret is set, behavior is unchanged (all webhooks accepted).
### Changed
- **Documentation sync** — CODEBASE_AUDIT.md: marked gaps 2.32.7 and 2.9 as fixed; added “Implemented 2026-03-16” summary. CLIENT_FEATURES_IMPLEMENTATION_STATUS: report date range and CSV export noted as implemented. INCOMPLETE_IMPLEMENTATIONS_ANALYSIS: added “Verified 2026-03-16” for webhook verification, issues permissions, search API, offline queue.
- **Activity feed API date params** — `/api/activity` now returns 400 with a clear message when `start_date` or `end_date` are invalid (e.g. not ISO 8601). Invalid dates on the web route `/activity` are logged and the filter is skipped (no 500).
- **Invoice PEPPOL compliance check** — Exceptions in the PEPPOL compliance block are no longer silently ignored: specific and generic exceptions are caught, logged, and a generic warning (“Could not verify PEPPOL compliance; check configuration.”) is shown to the user so the view still renders.
- **Documentation and i18n audit** — Updated docs and translations to match current implementation: removed stale "coming soon" claims; marked INCOMPLETE_IMPLEMENTATIONS_ANALYSIS as historical and added still-relevant summary; rewrote INVENTORY_MISSING_FEATURES as "Remaining Gaps" (transfers, adjustments, reports, PO management, API are implemented); updated GETTING_STARTED (PDF export, project permissions, REST API); REST_API (webhooks supported); KEYBOARD_SHORTCUTS_SUMMARY (customization implemented); BULK_TASK_OPERATIONS (bulk due date/priority implemented); INVENTORY_IMPLEMENTATION_STATUS (report templates done); activity_feed (invoices/clients/comments status clarified). Removed orphaned translation strings "Bulk due date update feature coming soon!" and "Bulk priority update feature coming soon!" from 10 locale `.po` files.
### Added
@@ -61,7 +61,7 @@
## Optional / future (Phase 2)
- Per-contact preferences (when contact-based login exists)
- Report export (PDF/CSV), saved report params
- **Report date range and CSV export:** implemented (query param `?days=1365`, `?format=csv`). PDF export and saved report params remain future.
- Activity: log quote/invoice events; optional `visible_to_client` on Activity
- Real-time activity feed live updates
- New widget types (e.g. documents, deadlines); admin-defined default layouts
+184
View File
@@ -0,0 +1,184 @@
# TimeTracker — Code-Grounded Audit
**Date:** 2026-03-16
**Scope:** Gaps beyond existing research (INCOMPLETE_IMPLEMENTATIONS_ANALYSIS, CLIENT_FEATURES_IMPLEMENTATION_STATUS, INVENTORY_MISSING_FEATURES). Validated against current code.
---
## 1. Audit Summary
| Category | Finding |
|----------|--------|
| **Backend route parity** | Settings blueprint exposes `/settings` and `/settings/preferences` but templates `settings/index.html` and `settings/preferences.html` are **missing**; `/settings` is served by `user_bp`, so only `/settings/preferences` 500s when hit. |
| **API parity** | `/api/search`, `/api/health`, `/api/dashboard/*`, `/api/activity/timeline` exist. **Dedicated `read:inventory`/`write:inventory` scopes added** (2026-03-16); backward compatible with `read:projects`/`write:projects`. |
| **Integrations / webhooks** | GitHub and **Jira** webhook **signature verification implemented** (optional `webhook_secret` in Jira config; HMAC-SHA256 of body). |
| **Client portal** | Access enforced via `check_client_portal_access()`. **Reports: date range (`?days=1365`) and CSV export (`?format=csv`)** added. Real-time (SocketIO) and dashboard preferences implemented. |
| **Inventory** | Transfers, Adjustments, Reports **are in the sidebar** (base.html: inventory dropdown with `list_transfers`, `list_adjustments`, `reports_dashboard`). Docs that said “add menu links” are stale. |
| **Issues permissions** | Non-admin filtering **is implemented** in issues.py via `get_accessible_project_and_client_ids_for_user` and `query.filter(Issue.project_id.in_(...), ...)`. |
| **Silent exceptions** | **PEPPOL (invoices.py)** and **activity_feed date params** addressed: targeted catch, log, and optional warning or 400. Other `except: pass` remain in lower-impact paths. |
| **Tests** | Search API, client portal (preferences, reports, activity, SocketIO), inventory API transfers/reports, keyboard shortcuts covered. Supplier/PO **web** tests still missing per docs. |
---
## 2. Detailed Gaps
### 2.1 Missing template: `settings/preferences.html`
| Field | Content |
|-------|--------|
| **Missing feature** | Settings “Preferences” page template. |
| **Evidence** | `app/routes/settings.py` line 46: `return render_template("settings/preferences.html")`. Only `app/templates/settings/keyboard_shortcuts.html` exists; no `preferences.html` or `index.html` under `settings/`. |
| **Why it matters** | Any request to `/settings/preferences` (bookmark, doc link, or future nav) returns **500 TemplateNotFound**. |
| **Approach** | Add `settings/preferences.html` that either redirects to `user.settings` (canonical user prefs) or renders a minimal page with a link to “Main settings”. |
| **Priority** | **High** (user-facing 500). |
---
### 2.2 Missing template: `settings/index.html`
| Field | Content |
|-------|--------|
| **Missing feature** | Settings hub page template. |
| **Evidence** | `app/routes/settings.py` line 22: `return render_template("settings/index.html")`. Template not present. |
| **Why it matters** | Route is only hit if something links to `url_for('settings.index')`. No such links found; URL `/settings` is taken by `user_bp`. So this is a **latent** 500 if a link is added later. |
| **Approach** | Add `settings/index.html` (e.g. hub with links to keyboard shortcuts and user settings) or redirect to `user.settings`. |
| **Priority** | **Medium** (latent; no current link). |
---
### 2.3 Jira webhook: no signature verification — **Fixed 2026-03-16**
| Field | Content |
|-------|--------|
| **Status** | **Addressed.** Optional `webhook_secret` in Jira integration config; when set, requests are verified via HMAC-SHA256 of body (headers `X-Hub-Signature-256`, `X-Atlassian-Webhook-Signature`, `X-Hub-Signature`). |
---
### 2.4 API scopes: no dedicated inventory scopes — **Fixed 2026-03-16**
| Field | Content |
|-------|--------|
| **Status** | **Addressed.** `read:inventory` and `write:inventory` added; inventory endpoints accept either new or legacy project scopes. See `docs/api/API_TOKEN_SCOPES.md`. |
---
### 2.5 Silent exception: PEPPOL compliance check (invoices) — **Fixed 2026-03-16**
| Field | Content |
|-------|--------|
| **Status** | **Addressed.** Exceptions caught and logged; generic warning “Could not verify PEPPOL compliance” shown when check fails. |
---
### 2.6 Client portal: report export and date range — **Fixed 2026-03-16**
| Field | Content |
|-------|--------|
| **Status** | **Addressed.** Reports support `?days=1365` and `?format=csv` for CSV download. PDF and saved report params remain future work. |
---
### 2.7 Offline queue: request body and method on replay — **Fixed 2026-03-16**
| Field | Content |
|-------|--------|
| **Status** | **Addressed.** Queue stores `method`, `headers`, and `body` in replay-safe form; replay uses them. Legacy items with `options` only still work via fallback. |
---
### 2.8 Keyboard shortcuts: “Usage statistics” placeholder
| Field | Content |
|-------|--------|
| **Missing feature** | Real usage data for keyboard shortcuts. |
| **Evidence** | `app/templates/settings/keyboard_shortcuts.html` ~286: “Usage statistics will appear here as you use keyboard shortcuts” with no backend or script feeding data. |
| **Why it matters** | UX promise with no implementation can confuse users. |
| **Approach** | Either implement simple client-side or server-side usage tracking and display, or replace copy with “Not available” / remove the section. |
| **Priority** | **Low**. |
---
### 2.9 Activity feed API: broad exception swallowing — **Fixed 2026-03-16**
| Field | Content |
|-------|--------|
| **Status** | **Addressed.** Date params catch `ValueError` only; API returns 400 for invalid dates; web route skips filter and logs. |
---
## 3. Newly Discovered Gaps (Not in Original Research)
1. **Settings templates missing**
Original docs do not mention missing `settings/preferences.html` and `settings/index.html`. These cause or would cause 500 for `/settings/preferences` and for any future link to the settings hub.
2. **Jira webhook unauthenticated**
INCOMPLETE_IMPLEMENTATIONS_ANALYSIS only calls out GitHub webhook verification; GitHub is now implemented. **Jira** webhook has no signature or secret verification.
3. **Inventory menu already present**
INVENTORY_MISSING_FEATURES and INVENTORY_IMPLEMENTATION_STATUS say “Add Transfers/Adjustments/Reports to menu”. In **base.html** the inventory dropdown already includes these links and `nav_active_*` for them. This is a doc staleness issue, not a code gap.
4. **Issues permission filtering implemented**
Original analysis said “permission filtering for non-admin users is incomplete” in issues.py. Current **issues.py** uses `get_accessible_project_and_client_ids_for_user` and filters the query; the gap is closed.
5. **Push subscription storage**
Original doc referred to “push_subscription field on User”. The app uses a **PushSubscription** model and persist in push_notifications.py; storage is implemented.
6. **Offline task/project sync implemented**
Original doc said “TODO: Implement task sync” and “project sync” in offline-sync.js. **offline-sync.js** contains full `syncTasks()` and `syncProjects()` with fetch to `/api/v1/tasks` and `/api/v1/projects`. The gap is closed; docs are stale.
7. **Search API implemented**
`/api/search` exists in `app/routes/api.py` and is tested; frontend uses it. No missing search endpoint.
8. **Client portal report scoping**
Reports are built from `get_portal_data(client)` and `build_report_data(client, ...)`; no cross-client data leak found. Real gap is export and date range (see 2.6).
9. **No dedicated inventory API scopes**
Not called out in original research; discovered via API_TOKEN_SCOPES and api_auth.
10. **Keyboard shortcuts “usage statistics”**
Placeholder UI with no backend; not in original list.
---
## 4. Roadmap
### Quick wins
- Add **settings/preferences.html** so `/settings/preferences` does not 500 (redirect or minimal page with link to main settings).
- Add **settings/index.html** (hub or redirect to `user.settings`) to avoid future 500.
- Replace **invoices.py** PEPPOL `except Exception: pass` with targeted catch + log (and optional generic warning).
### Medium effort / high impact
- **Jira webhook verification**: Add shared-secret or signature check from headers; document in integration config.
- **Client report export**: Add CSV (and optionally PDF) export and optional date range params for client portal reports.
- **Inventory API scopes**: Introduce `read:inventory` / `write:inventory` and gate inventory endpoints; keep project-scope fallback for backward compatibility.
- **Activity feed date params**: Validate date query params and return 400 on invalid input instead of silent `pass`.
### Architectural improvements
- **Centralized exception handling**: Replace high-impact `except: pass` with a small set of helpers (e.g. `safe_log`, structured error response) and use them in routes/api.
- **Offline queue robustness**: Standardize how request body/method are stored and replayed; add tests for offline POST replay.
- **Docs and status sync**: Update INVENTORY_MISSING_FEATURES / INVENTORY_IMPLEMENTATION_STATUS to reflect current menu and API; add a short “verified on <date>” note to INCOMPLETE_IMPLEMENTATIONS_ANALYSIS for items now fixed (GitHub webhook, issues permissions, search API, push storage, offline sync).
---
## 5. Implemented Quick Wins and Audit Gaps
1. **`/settings/preferences` no longer 500s**
The route now redirects to `user.settings` with an info flash (“Your preferences are managed on the main Settings page”) instead of rendering a missing template.
2. **`/settings` (settings index) no longer 500s**
The settings hub route now redirects to `user.settings`. (In practice `/settings` is already served by `user_bp` since it is registered first; this change makes the settings blueprint safe if registration order changes or anything links to `settings.index`.)
### Implemented 2026-03-16 (audit gaps)
3. **Jira webhook verification** — Optional `webhook_secret` in Jira integration; when set, incoming webhooks are verified via HMAC-SHA256 of the request body.
4. **Exception handling (invoices, activity_feed)** — PEPPOL block: targeted catch, log, generic warning. Activity feed API: invalid `start_date`/`end_date` return 400; web route skips filter and logs.
5. **Client portal reports** — Date range `?days=1365` and CSV export `?format=csv`.
6. **Inventory API scopes**`read:inventory` and `write:inventory` added; backward compatible with `read:projects`/`write:projects`.
7. **Offline queue replay** — Request body and method stored and replayed correctly for POST/PUT.
---
**Last updated:** 2026-03-16
+4 -4
View File
@@ -8,11 +8,11 @@
Items that may still need attention (verify in current code):
- **Security:** GitHub webhook signature verification; issues module permission filtering for non-admins
- **Security:** **Verified 2026-03-16:** GitHub and Jira webhook signature verification implemented; issues module permission filtering for non-admins implemented (see CODEBASE_AUDIT.md).
- **Integrations:** QuickBooks customer/account mapping; CalDAV bidirectional sync
- **API:** Search endpoint `/api/search` if referenced by frontend and not implemented
- **Offline/PWA:** Task and project sync in offline-sync.js; push subscription storage
- **Error handling:** Many `pass` in exception handlers; address high-impact routes first
- **API:** **Verified 2026-03-16:** Search endpoint `/api/search` exists and is used; see CODEBASE_AUDIT.
- **Offline/PWA:** **Verified 2026-03-16:** Offline queue now stores and replays request body/method; push subscription storage may still need verification.
- **Error handling:** High-impact PEPPOL (invoices) and activity_feed date params addressed 2026-03-16; other `pass` handlers remain.
---