mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-19 04:40:32 -05:00
feat: API v1 CRM/approvals, api_responses, templates, version & RBAC docs
- REST API v1: add deals, leads, contacts, time-entry-approvals (CRUD + approve/reject/cancel/bulk-approve). New scopes and /info entries. - Standardize API errors: use error_response, forbidden_response, not_found_response in api_v1 (projects + new CRM/approval routes). - Consolidate templates: move root templates/ into app/templates/, remove ChoiceLoader and legacy root files. - Version: README/FEATURES_COMPLETE/CHANGELOG/mobile docs reference setup.py as single source (4.19.0); add [4.19.0] changelog entry. - Docs: SERVICE_LAYER_AND_BASE_CRUD.md, RBAC_PERMISSION_MODEL.md; base_crud_service docstring points to service-layer doc. - Mark projects_refactored_example, timer_refactored, invoices_refactored as REFERENCE ONLY in docstrings.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# RBAC Permission Model (Route-Level)
|
||||
|
||||
This document describes how route-level access control is applied across the application. For the full role and permission system (roles, permissions, categories), see [ADVANCED_PERMISSIONS.md](../ADVANCED_PERMISSIONS.md).
|
||||
|
||||
## Two patterns
|
||||
|
||||
### 1. Permission-scoped routes
|
||||
|
||||
These blueprints protect routes with `@admin_or_permission_required("permission_name")` in addition to `@login_required`. Only users who are admins or have the given permission can access the route.
|
||||
|
||||
**Blueprints using permission decorators:**
|
||||
|
||||
- **admin** – `access_admin`, `view_users`, `create_users`, `edit_users`, `delete_users`, `manage_telemetry`, `manage_settings`, `manage_backups`, `view_system_info`, `manage_oidc`, `manage_api_tokens`, `manage_integrations`
|
||||
- **audit_logs** – `view_audit_logs`
|
||||
- **per_diem** – `per_diem_rates.view`, `per_diem_rates.create`, `per_diem_rates.edit`, `per_diem_rates.delete`
|
||||
- **inventory** – `view_inventory`, `manage_stock_items`, `manage_warehouses`, `view_stock_levels`, `view_stock_history`, `manage_stock_movements`, `transfer_stock`, `manage_stock_reservations`, `manage_suppliers`, `manage_purchase_orders`, `view_inventory_reports`
|
||||
- **clients** – permission checks where applicable
|
||||
- **projects** – `create_projects` (and others where applied)
|
||||
- **kanban** – permission checks where applied
|
||||
- **webhooks** – permission checks where applied
|
||||
- **project_templates** – permission checks where applied
|
||||
- **quotes** – permission checks where applied
|
||||
- **custom_field_definitions** – permission checks where applied
|
||||
- **invoice_approvals** – permission checks where applied
|
||||
- **payment_gateways** – permission checks where applied
|
||||
- **kiosk** – permission checks where applied
|
||||
- **offers** – permission checks where applied
|
||||
- **link_templates** – permission checks where applied
|
||||
- **expense_categories** – permission checks where applied
|
||||
|
||||
### 2. All authenticated users
|
||||
|
||||
These blueprints use only `@login_required`. Any logged-in user can access the routes. This is intentional for areas where the default roles (e.g. User, Manager) are expected to have full access within the app.
|
||||
|
||||
**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.
|
||||
|
||||
## 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.
|
||||
|
||||
## 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).
|
||||
@@ -0,0 +1,28 @@
|
||||
# Service Layer and Base CRUD Pattern
|
||||
|
||||
## Chosen pattern
|
||||
|
||||
TimeTracker uses a **domain service layer**: route handlers call service classes (e.g. `ProjectService`, `InvoiceService`, `TimeApprovalService`) that encapsulate business logic and data access. Routes are kept thin; validation, permissions, and orchestration live in services or in route-level decorators.
|
||||
|
||||
- **Services** live in `app/services/`. Each domain (projects, clients, time entries, invoices, approvals, etc.) has one or more service classes.
|
||||
- **Repositories** exist for some domains (`app/repositories/`, e.g. `TimeEntryRepository`, `ProjectRepository`, `ClientRepository`, `TaskRepository`) and are used by services or routes to avoid N+1 queries and centralize queries.
|
||||
- **Routes** use `db.session` and model queries where a dedicated service or repository is not yet introduced; new features and refactors should prefer the service (and optionally repository) pattern.
|
||||
|
||||
## BaseCRUDService
|
||||
|
||||
`app/services/base_crud_service.py` defines **BaseCRUDService**, a generic base class that provides standard CRUD (get_by_id, create, update, delete, list_all) with consistent `{ "success", "message", "data" / "error" }` result dicts.
|
||||
|
||||
- **Current use**: BaseCRUDService is **not** extended by any service today. Domain services implement their own methods and return shapes (e.g. `ProjectService.create()` returns a result dict used by the API).
|
||||
- **When to use it**: Prefer BaseCRUDService when:
|
||||
- You introduce a **new** domain that has a **repository** with `get_by_id`, `create`, `update`, `delete`, and `query()`.
|
||||
- The resource is mostly simple CRUD with minimal extra logic.
|
||||
- **When not to use it**: Existing domain services (projects, clients, invoices, time entries, etc.) have custom logic, validation, and return shapes. Migrating them to BaseCRUDService would require repository implementations and possible API response changes; it is optional and can be done incrementally.
|
||||
|
||||
## Summary
|
||||
|
||||
| Aspect | Approach |
|
||||
|---------------------|--------------------------------------------------------------------------|
|
||||
| New features | Prefer service class + optional repository; use BaseCRUDService only if CRUD is simple and a repository exists. |
|
||||
| Existing services | Keep current pattern; no requirement to extend BaseCRUDService. |
|
||||
| Route layer | Prefer calling services; direct `db.session` / model queries are acceptable where services are not yet used. |
|
||||
| API response shape | Use `app.utils.api_responses` (e.g. `error_response`, `success_response`) for consistent JSON error/success format. |
|
||||
Reference in New Issue
Block a user