Based on a comprehensive review of the last 20 commits (which introduced a Vue 3 frontend migration, a REST API v1, and modern Nextcloud 34 support), I have identified several architectural problems, bugs, and areas for improvement.
🔴 Critical Problems & Bugs
- Broken SQL & Dead Code:
- WorkIntervalMapper::stopAllRunning contains invalid SQL (update wi FROM ...) and incorrectly uses findEntities (which expects a SELECT result) for an UPDATE operation.
- Duplicate Logic (DRY Violation):
- The AjaxController contains almost exact copies of the logic now present in the new domain controllers (TimerController, ClientController, etc.). Maintaining both for backward compatibility without shared service layers will inevitably lead to divergent behavior and bugs.
- Property Access Regressions:
- Several controllers (e.g., ReportController, TimelineController, and parts of TimerController) still use property access for request parameters (e.g., $this->request->from). In Nextcloud 34, JSON body parameters are only reliably accessible via getParam(). The included
FakeRequest test stub correctly identifies this, but many controllers lack test coverage.
- Anti-Pattern Response Handling:
- The TimelineController uses header() and exit() for CSV downloads and emails. This bypasses the Nextcloud response lifecycle, making it harder to test and potentially causing issues with CSRF or other middleware.
- Fragile Date Formatting:
- Communication between the frontend and backend relies on a custom string format (d/m/y H:i). This is fragile, locale-dependent, and prone to "off-by-one-hour" bugs during DST transitions.
🟡 Architectural & Style Issues
- Legacy Infrastructure:
- The project still uses OldNextcloudMapper (deprecated since NC14) and manual service registration in Application.php. It should move to QBMapper and automatic dependency injection.
- Global State Access:
- Widespread use of \OC::$server and \OC_User instead of injecting services (Mailer, IGroupManager, etc.) via the constructor.
- Poor Serialization Patterns:
- Extensive use of json_decode(json_encode($data), true) to convert database entities to arrays for JSON responses. Entities should implement JsonSerializable or use a proper transformer.
- Inefficient Goal Calculations:
- GoalController::index performs a full database report for every goal in a loop ($O(N)$ database round-trips), which will scale poorly for users with many goals.
- Inconsistent Frontend Components:
- TimerView.vue and GoalsView.vue still use native HTML and elements instead of Nextcloud's NcSelect and NcTextField, leading to a subpar and inconsistent UI/UX compared to ClientsView.vue.
🚀 Improvement Proposals
- Refactor to shared Service Layer: Extract common logic from AjaxController and the new REST controllers into Service classes (e.g., TimerService, ProjectService). This ensures consistency and simplifies the controllers.
- Migrate to QBMapper: Update all mappers to use the modern Query Builder. This is required for long-term compatibility and better security (prepared statements).
- Standardize API Responses: Implement a base controller method or trait to handle standardized JSON responses with proper HTTP status codes (e.g., 400 for validation errors instead of returning ["Error" => "..."] with a 200 status).
- Use ISO 8601 for Dates: Switch all API date parameters to ISO 8601 strings or Unix timestamps to eliminate formatting and timezone ambiguity.
- Optimize UI Performance: Implement "surgical" updates to the Vue state. Currently, every small change (like renaming a task) triggers a full re-fetch of all work intervals, causing flickering and potential loss of scroll position.
- Fix Template Bugs: Replace manual HTML entities (like {{ ' ' }}) with proper Vue directives or standard CSS spacing to avoid literal text rendering.
- Modernize Authorization: Replace deprecated \OC_User::isAdminUser with IGroupManager checks and ensure resource-level ownership is verified before deletions.
- Leverage Standard Icons: Instead of hardcoding SVG paths in every component, use standard icon components from @nextcloud/vue or a centralized icon utility.
Recap of Work
- Analyzed the last 20 commits covering Vue 3 and REST API migrations.
- Audited PHP controllers, mappers, and Vue components.
- Identified critical bugs (broken SQL, property access) and architectural debt (legacy mappers, duplicate logic).
- Proposed a roadmap for technical debt reduction and performance optimization.
Based on a comprehensive review of the last 20 commits (which introduced a Vue 3 frontend migration, a REST API v1, and modern Nextcloud 34 support), I have identified several architectural problems, bugs, and areas for improvement.
🔴 Critical Problems & Bugs
FakeRequest test stub correctly identifies this, but many controllers lack test coverage.
🟡 Architectural & Style Issues
🚀 Improvement Proposals
Recap of Work