Commit Graph

1246 Commits

Author SHA1 Message Date
Dries Peeters 05b6512a94 docs(i18n): link Drytrix TimeTracker Crowdin project and expand setup
Document https://crowdin.com/project/drytrix-timetracker in CONTRIBUTING.md, docs/TRANSLATION_SYSTEM.md, and contributor guides. Update CONTRIBUTING_TRANSLATIONS.md with the public project URL, clearer translator vs maintainer onboarding, and an optional "Further Crowdin integration" section (GitHub app, automation, QA, glossary, notifications).

Refresh crowdin.yml header comments (project URL, secrets pointers), normalize preserve_hierarchy to a boolean, and keep the nb→no languages_mapping quoted for YAML 1.1 compatibility.
2026-04-15 09:00:27 +02:00
Dries Peeters 49ac65b7bd Update Crowdin configuration file 2026-04-15 08:40:03 +02:00
Dries Peeters d2dbbc891b Version Bump 2026-04-15 08:19:25 +02:00
Dries Peeters 6e0010b28f docs(i18n): document Crowdin setup and add sync configuration
Add crowdin.yml mapping the English gettext catalog to per-locale messages.po paths, with an explicit nb→no mapping so Norwegian matches app/config.py.

Add a manual GitHub Action (Crowdin sync) to upload sources and download translations when CROWDIN_PROJECT_ID and CROWDIN_PERSONAL_TOKEN are configured.

Extend CONTRIBUTING_TRANSLATIONS with maintainer steps, cross-link TRANSLATION_SYSTEM and contributor guides, refresh TRANSLATION_SYSTEM metadata, and note the integration under [Unreleased] in CHANGELOG.md.
2026-04-15 08:03:48 +02:00
Dries Peeters 15ddabdffb feat(quotes): reorder form rows and improve quote view i18n docs
Add Move up / Move down controls and an Order column for quote line items, Costs, and Extra goods on create and edit pages (Issue #584). DOM row order matches POST field order so existing QuoteItem.position handling stays correct.

Fix the quote detail Valid until row by using quote.is_expired instead of an undefined Jinja now() (Issue #583). Submit a past valid_until in the web regression test so the view path is exercised.

Document translation contributions without Git: add docs/CONTRIBUTING_TRANSLATIONS.md, a Translation improvement issue template, links from CONTRIBUTING.md and TRANSLATION_SYSTEM.md, and a Translations subsection in docs/development/CONTRIBUTING.md. Refresh CHANGELOG [Unreleased] for these items.
2026-04-15 07:57:10 +02:00
Dries Peeters 19bac393b0 fix(desktop): Windows load hang and renderer helpers (#587)
The will-navigate guard compared file URL origins to the literal string
file://, but the URL API reports an opaque origin for file pages, so
legitimate file navigations were blocked and the window could fail to
load reliably on Windows.

Import utils/helpers from the renderer entry so esbuild includes
window.Helpers in the bundle, restoring formatters and isValidUrl after
build:renderer.

Documentation: desktop README explains the renderer bundle workflow;
Windows desktop troubleshooting covers stuck loading; frontend quality
gates table notes the app.js entry and rebuild step.
2026-04-15 07:56:12 +02:00
Dries Peeters 974f5cdd50 feat(quotes): invoice-style line items, costs, and extra goods (#585)
Add quote_items.line_kind (item | expense | good) plus display_name,
category, line_date, and sku so one table still drives totals, PDFs,
and acceptance stock logic.

- Migration 147: new columns with backfill line_kind=item
- Quote create/edit: three sections; stock and warehouse only when a
  line item is sourced from inventory; shared JS partial
- POST parsing, positions, and duplicate-quote copying for all fields
- API v1 quote items accept the new fields with defaults for old clients
- View, client portal, and PDF/fallback rendering use display_name and
  line metadata where relevant
- Integration tests: stock POST shape; expense and good line creation

Docs: extend INVENTORY_MANAGEMENT_PLAN QuoteItem and migration notes.
2026-04-12 14:00:12 +02:00
Dries Peeters c134e07e2a feat(quotes): reorder line items on create/edit (#584)
Add Move up / Move down controls and a 13-column desktop grid on quote
item rows so users can change line order without deleting entries. Order
matches persisted quote_items.position (migration 146) for PDFs and views.

Update CHANGELOG [Unreleased] with Issue #584. Fix inventory integration
test to read quote.items[0] (relationship returns a list, not a query).
2026-04-12 13:40:47 +02:00
Dries Peeters 70510a6622 fix: quote create 500, line order, and Factur-X PDF parity
Quotes (#583):
- Add requires_approval, approval_level, and can_be_sent; wire create form
- Migrations 145 (approval columns) and 146 (quote_items.position)
- Order Quote.items by position; set positions on create/edit/duplicate/API
- Fix view template approval branch (not_required); add web regression test

Invoices / PEPPOL:
- Use the same Factur-X embed and PDF/A-3 normalization for export and
  email attachments; Associated File Data + text/xml metadata
- CII/UBL validators, pdfa3, zugferd, and invoice_pdf_postprocess helper
- Bundle compact sRGB ICC (app/resources/icc/); INVOICE_SRGB_ICC_PATH override
- Package data in setup.py; extend PEPPOL_EINVOICING.md and tests
2026-04-12 13:34:58 +02:00
Dries Peeters 507266fbbf docs: API v1 import, bulk, idempotency, rate limits; Linear guide; release tooling
- Document CSV import, bulk actions, Idempotency-Key, and token rate limits in REST_API and scopes.
- Clarify session vs token CSV import in import/export README; mobile offline idempotency note.
- Add docs/integrations/LINEAR.md; refresh CODE_BASED_ANALYSIS_REPORT (v5.3.0, 14 connectors).
- env.example: API_TOKEN_RATE_LIMIT_*; setup.py version; CD release workflow tweak; Zapier webhook sample.
2026-04-05 08:39:22 +02:00
Dries Peeters a05bedc084 feat(mobile): idempotent offline time entry sync
- Generate and send Idempotency-Key for queued POST /api/v1/time-entries creates.
- Wire sync queue and API client so retries do not duplicate entries after reconnect.
- Adjust settings and sync use case for the new behavior.
2026-04-05 08:39:20 +02:00
Dries Peeters 9449a46a42 feat(integrations): Linear connector and shared HTTP/sync helpers
- Add Linear import (GraphQL, personal API key, optional team key filter).
- Centralize integration HTTP via integration_session and session_request.
- Add integration_sync_context for project/task refs and custom_fields metadata.
- Refactor Asana, GitHub, GitLab, Jira, Trello, ActivityWatch, and QuickBooks to use helpers.
- Extend integration UI, settings, and scheduled sync behavior as needed.
2026-04-05 08:39:18 +02:00
Dries Peeters 5df748b30e feat(api): v1 CSV import, bulk time entries, idempotency, and rate limits
- Add POST /api/v1/time-entries/import-csv and POST /api/v1/time-entries/bulk.
- Support Idempotency-Key on POST /api/v1/time-entries with 24h replay per token.
- Enforce per-token minute/hour limits (Redis when available, local fallback otherwise).
- Extract bulk and CSV import logic into dedicated services; trim legacy api route surface.
2026-04-05 08:39:14 +02:00
Dries Peeters 98e6eb87b9 feat(db): add task custom_fields and api_idempotency_keys
- Add tasks.custom_fields (JSONB) for integration metadata (migration 143).
- Add api_idempotency_keys table keyed by token, scope, and key hash (migration 144).
- Register ApiIdempotencyKey model for safe replay of POST /api/v1/time-entries.
2026-04-05 08:39:11 +02:00
Dries Peeters 47dd46a1de Update to version v5.2.2 2026-03-28 20:08:49 +01:00
Dries Peeters 07387ebf2e fix(tests): stabilize smoke suite for SA2 flush, auth, and admin routes
Detect SQLAlchemy 2.0 flush execution via _warn_on_events in
Settings._session_in_flush so get_settings() does not add/commit
during flush_context.execute(), avoiding ResourceClosedError in
invoice currency smoke tests.

Payment smoke tests now set a password on factory users and submit
it on login, matching local AUTH_METHOD requirements (fixes 302 to
login on /payments).

Allow HTTP 403 in test_non_admin_cannot_access_roles when the app
denies non-admins directly instead of redirecting with 200.
2026-03-28 20:07:19 +01:00
Dries Peeters 8e0386d2f0 fix(integrations): add module logger for GitHub connector
exchange_code_for_tokens called logger.debug without a defined logger, which triggered flake8 F821 in CI. Import logging and use getLogger(__name__) at module scope.
2026-03-28 20:02:09 +01:00
Dries Peeters eaca5e346e fix(ci): drop --release for iOS simulator builds
Flutter rejects release mode with --simulator; use the default debug
simulator build so CI can compile and zip Runner.app. Document the
constraint in workflow comments.
2026-03-28 20:01:39 +01:00
Dries Peeters c09dbbf108 fix(mobile): use UserPrefs dateFormatKey and timeFormatKey in UI
Screens referenced dateFormat and timeFormat, which do not exist on
UserPrefs. Align with the model and date_format_utils key-based API so
flutter analyze and tests compile.
2026-03-28 19:48:54 +01:00
Dries Peeters 29f085a148 Version Bump to v5.2.1 2026-03-28 18:04:54 +01:00
Dries Peeters da85aedefb feat(mobile): add data layer, OTLP telemetry, and CI build fixes
Implement the missing Flutter data layer so release builds compile: Dio ApiClient for /api/v1 (timer, time entries, projects, tasks, finance, time-off, users/me), JSON models, Hive LocalStorage, and offline SyncService queue.

Add OpenTelemetry (opentelemetry package) with initMobileOpenTelemetry() reading OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_EXPORTER_OTLP_TOKEN via --dart-define, matching server OTLP base URL and Basic auth behavior. Instrument login token validation, timer start/stop, and sync pending.

Fix SyncUseCase to import storage SyncService, use trusted insecure hosts, and call syncAll().

GitHub Actions (build-mobile.yml, cd-release.yml): run flutter test; pass OTLP secrets into flutter build apk/appbundle/ios; switch iOS CI to release simulator builds and package build/ios/iphonesimulator/Runner.app to avoid requiring an Apple Development Team for generic device builds.

.gitignore: allow tracking mobile/lib/data/ despite the repo-wide data/ ignore rule.
2026-03-28 18:01:10 +01:00
Dries Peeters 4007ee2ca8 feat(observability): add OpenTelemetry traces, OTLP metrics, and log correlation
Introduce a centralized OTel layer (app/telemetry/otel_setup.py) that reuses
the existing OTLP endpoint and token, exports traces and metrics over OTLP/HTTP,
and instruments Flask plus SQLAlchemy. Manual OTLP log export remains for base
and product analytics; log records now include trace_id, span_id, and
event_category where tracing is active.

Business spans and product metrics cover invoices, timers, reports, auth,
webhook delivery, and scheduled jobs. RED-style HTTP metrics are recorded in
after_request alongside existing Prometheus counters. ENABLE_TRACING and
ENABLE_METRICS default on when credentials exist; graceful no-op when they do not.

Privacy is preserved: user_id appears on traces only when detailed analytics is
opted in; metrics never carry user_id; _remove_pii behavior for analytics is
unchanged. Responses inject traceparent when tracing is enabled for future
browser correlation.

Tests: test_otel_integration.py and per-test reset_for_testing() in conftest
so each app factory can reinitialize OTel.
2026-03-28 17:32:18 +01:00
Dries Peeters 311aa63a27 fix(invoice): soften stacked border/shadow on line item inputs (#574)
Remove default form-input shadow and top margin inside tinted invoice and
quote line rows. The row already has a border and hover shadow; inputs
were doubling that edge so the top of each row looked overly heavy.
2026-03-28 16:46:28 +01:00
Dries Peeters 81a866a655 Version Bump to 5.2.0 2026-03-27 06:47:40 +01:00
Dries Peeters 8228c43821 test(timer): integration tests for own-entry schedule edits (#572)
Cover GET edit form and PATCH API when the user has edit_own_time_entries
on their own entries, complementing the timer route and API changes in the
mobile shell / timer edit work.
2026-03-27 06:41:03 +01:00
Dries Peeters 8afeedeb79 feat: mobile shell, own-entry timer edits, invoice/quote form borders
- Allow schedule edits (project, task, start/end, break) for users with
  edit_own_time_entries on their own entries in API update_entry and
  timer edit; scope project lists for subcontractors; admin-only source
  dropdown on edit timer form.
- App shell: min-width/overflow fixes, header layout, compact bottom nav
  on very narrow viewports (#573), dashboard timer block responsive layout.
- Invoice and quote edit: min-w-0 on grids/cells; scoped stronger neutral
  borders for .form-input on #editInvoiceForm and #quote-form (#574).
2026-03-27 06:40:17 +01:00
evilguy4000 1b5d019560 feat(admin): persist test recipient and send invoice email template tests
Add Settings.mail_test_recipient (migration 142) and wire Admin → Email Configuration to save, load, and prefill the SMTP test recipient field.

Extract invoice email PDF/HTML building into _build_invoice_email_payload for reuse. New send_invoice_template_test_email sends a real message with subject "Invoice template test: …", reusing production rendering and PDF attachment, without updating invoice status or creating InvoiceEmail records.

Add POST /admin/email-templates/<id>/send-test (optional recipient override, optional invoice_id) and Send test email UI on template view and edit pages. Extend smoke and unit tests.
2026-03-27 06:39:16 +01:00
evilguy4000 5fd0625e3a fix(inventory): stop 500 on purchase order detail view (#576)
Purchase orders with line items crashed the detail page because the template
referenced item.stock_item without a SQLAlchemy relationship, and used
datetime.now() in Jinja where datetime was not in context.

Add PurchaseOrderItem.stock_item, pass default_received_date from the view
route, and add a regression test for viewing a PO that includes line items.
2026-03-27 06:38:47 +01:00
Dries Peeters ac569122bf Update setup.py 2026-03-26 18:25:23 +01:00
Dries Peeters 631f0af2fa fix(telemetry): use embedded config and add stable install identifiers
Read telemetry/sentry status in the admin dashboard from build-injected analytics defaults with env fallback, so release images correctly show OTLP configuration. Include both install_id and telemetry_fingerprint in base and detailed telemetry payloads to reliably differentiate installations, and add tests for the new fingerprint fields.
2026-03-26 18:25:10 +01:00
Dries Peeters a97520bbaf version Bump 2026-03-26 17:06:32 +01:00
Dries Peeters 905f6fbd37 feat(telemetry): migrate analytics pipeline from PostHog to OTLP
Switch product and installation telemetry to OTLP/Grafana across runtime config, CI injection, docs, and tests to unify telemetry transport and simplify privacy-focused opt-in behavior.
2026-03-26 17:01:55 +01:00
Dries Peeters 461721f0e1 fix(email-templates): prevent silent no-op on create submit
Sync editor content before submit validation and replace hidden required-field blocking with explicit inline checks. Preserve posted form values and enforce non-empty HTML on backend validation to avoid data loss and confusing no-op behavior.
2026-03-26 14:52:25 +01:00
Dries Peeters 4e2183caed fix(inventory): harden purchase-order creation and stock idempotency
Prevent 500s during first/parallel purchase-order creation by using collision-safe PO numbering, explicit validation, and reliable commit/error handling in web and API flows. Add regressions for purchase-order edge cases and invoice stock-reduction idempotency to catch adjacent inventory failures before release.
2026-03-26 14:52:06 +01:00
Dries Peeters 60d4d55027 feat(invoices): add fully configurable invoice number patterns
Implement issue #575 by introducing token-based invoice number patterns in settings and unifying number generation across invoice creation paths. This removes hardcoded INV/date formatting and aligns export filenames and bootstrap schemas with stored invoice numbers.
2026-03-26 14:51:55 +01:00
Dries Peeters 36fcbc65bf fix(invoices): widen quantity fields in edit form layout
Increase quantity column spans for Invoice Items and Extra Goods on the invoice edit page so values are easier to read, and keep static and JS-added rows aligned.
2026-03-26 14:51:22 +01:00
Dries Peeters 3d0ad839c4 Version Bump v5.0.0 2026-03-16 17:02:08 +01:00
Dries Peeters a50a4ebf2e 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
2026-03-16 16:44:31 +01:00
Dries Peeters 3654a6a5d3 feat(offline): store method, headers, and body in queue for correct POST/PUT replay
- queueForOffline now saves url, method, headers, body (replay-safe for localStorage);
  legacy items with options only still replayed via fallback
- processOfflineQueue builds fetch options from stored method/body so replayed
  requests send the same payload when back online
- Make queueForOffline async and await it in handleFetchResponse/handleFetchException
- Add tests asserting queue stores method/body and replay uses them
2026-03-16 16:44:09 +01:00
Dries Peeters 0ade07e1e8 fix(settings): redirect /settings and /settings/preferences to user.settings
- /settings and /settings/preferences lacked templates (would 500);
  redirect to canonical user.settings with info flash for preferences
2026-03-16 16:43:52 +01:00
Dries Peeters 2808140e4c fix(invoices): handle and surface PEPPOL compliance check exceptions
- Catch AttributeError/KeyError/TypeError and generic Exception in PEPPOL block;
  log with exc_info and show generic warning to user so view still renders
- Avoid silent pass that hid configuration or data errors
- Add test for exception path (mock get_custom_field to raise)
2026-03-16 16:43:44 +01:00
Dries Peeters 346d7169da feat(client-portal): add report date range and CSV export
- Reports accept ?days=1-365 (default 30) for configurable date range
- ?format=csv returns CSV download (summary, hours by project, time by date)
  with same access control as reports page
- Subtitle shows 'Last N days' when date range is applied
- Add tests for days param and CSV export
2026-03-16 16:43:35 +01:00
Dries Peeters f05d772dbb feat(api): add read:inventory and write:inventory scopes for inventory-only access
- New scopes read:inventory and write:inventory; existing read/write:projects
  still grant same inventory access for backward compatibility
- require_api_token() accepts tuple of scopes (any one required); inventory
  endpoints accept (read:inventory | read:projects) and (write:inventory | write:projects)
- ApiTokenService: add new scopes to allowed list; document in API_TOKEN_SCOPES.md
- Add tests for inventory report endpoints with scope checks
2026-03-16 16:43:08 +01:00
Dries Peeters 8c2714bec3 fix(activity-feed): validate date params and return 400 for invalid API input
- /api/activity: return 400 with clear message when start_date/end_date
  are not valid ISO 8601; avoid silent pass on parse errors
- Web route /activity: catch ValueError, log and skip filter instead of 500
- Add tests for invalid date formats on API and web routes
2026-03-16 16:42:53 +01:00
Dries Peeters 7e059a0a52 feat(jira): add optional webhook signature verification (HMAC-SHA256)
- When webhook_secret is set in Jira integration, verify incoming webhooks
  via X-Hub-Signature-256, X-Atlassian-Webhook-Signature, or X-Hub-Signature
- Reject requests with missing or invalid signature; no secret = accept all (unchanged)
- Add webhook_secret password field to Connection Settings in Jira config
- Add tests for verification success, missing sig, and invalid sig
2026-03-16 16:42:32 +01:00
Dries Peeters b67428a98f chore: update CHANGELOG for unreleased documentation and i18n audit
- Document docs/i18n audit: removed stale claims, updated implementation status
- Mileage/Per diem export, break time, architecture refactor, fixes (Xero, time filter, mobile, dashboard cache, etc.)
2026-03-16 15:16:28 +01:00
Dries Peeters 084e0b3ef7 i18n: remove orphaned bulk-task translation strings across locales
- Remove 'Bulk due date/priority update feature coming soon!' from 10 locale .po files
- Align messages with current implementation
2026-03-16 15:16:21 +01:00
Dries Peeters c35a12ca4a test: add and update tests for client portal, shortcuts, Jira, inventory API
- Client portal, enhanced UI, keyboard shortcuts and shortcuts API
- Jira integration; API v1 inventory reports and transfers
- Silent exception handling fixes
2026-03-16 15:16:11 +01:00
Dries Peeters 7cad0c6fdd docs: align documentation with current implementation
- Remove stale 'coming soon' claims; mark incomplete implementations as historical where relevant
- Update GETTING_STARTED, REST_API, KEYBOARD_SHORTCUTS_SUMMARY, BULK_TASK_OPERATIONS
- Update client portal, inventory, and activity feed docs; API token scopes
2026-03-16 15:16:05 +01:00
Dries Peeters 624a43446d chore(ui): update static JS and base template
- enhanced-ui, error-handling, keyboard-shortcuts, pwa, smart-notifications, toast-notifications
- base.html layout and script includes
2026-03-16 15:15:56 +01:00