Commit graph

402 commits

Author SHA1 Message Date
Johannes Millan
ae40f0ba2e feat(sync): add comprehensive timeout handling for large operations
Implement coordinated timeout strategy across all layers:

**Client-side (90s total):**
- HTTP requests: 75s timeout with AbortController
- Sync wait timeout: 90s (exceeds all server timeouts)
- Restore service: Retry logic for network errors (2s, 4s backoff)
- Better error messages for timeout scenarios

**Server-side:**
- Caddy proxy: 85s timeout (exceeds Fastify)
- Fastify server: 80s request timeout (exceeds DB timeout)
- Database operations: 60s (unchanged)

**Rationale:**
Each timeout layer exceeds the one below it, allowing inner operations
to complete and report errors properly. The 90s client timeout ensures
large operations (snapshot generation, imports) can complete without
premature abortion.

**Monitoring:**
- Log slow requests >30s for visibility
- Detailed error logging with duration tracking
- Android WebView timeout support via CapacitorHttp
2026-01-20 17:07:24 +01:00
Johannes Millan
be4b8ba241 fix(migrations): ensure unique IDs and prevent data loss in split operations
When splitting one operation into misc and tasks operations:
- Both operations now get unique ID suffixes (_misc and _tasks)
- Skip logic verifies both conditions before skipping:
  1. tasks config has migrated field (isConfirmBeforeDelete)
  2. misc config has NO migrated fields remaining

This prevents:
- Potential operation ID conflicts in the sync log
- Data loss in partial migration scenarios

Adds test cases for partial migration and correct skip scenarios.
2026-01-20 17:07:23 +01:00
Johannes Millan
8734b7ef4c
Merge pull request #6053 from steindvart/task-settings
Move task-related settings to a dedicated Tasks Settings tab and fix technical issues
2026-01-19 16:46:44 +01:00
Michael Chang
222b3474b8 fix(sync): restore missing force upload button in new config UI 2026-01-19 13:58:23 +01:00
Ivan Kalashnikov
1987292433 refactor: streamline migration logic and enhance field mapping for settings 2026-01-19 14:38:42 +07:00
Ivan Kalashnikov
800ba30f4f refactor: rename misc to tasks settings migration file and object. 2026-01-19 14:30:42 +07:00
Ivan Kalashnikov
356278fc87 feat: enhance migration tests for settings and operations handling 2026-01-19 14:21:09 +07:00
Ivan Kalashnikov
218e74f882 feat: implement migration of settings from misc to tasks with operation handling 2026-01-19 14:19:31 +07:00
Ivan Kalashnikov
263495b8cd feat: update migration functions to support splitting operations into multiple results 2026-01-19 13:58:27 +07:00
Ivan Kalashnikov
b3da4e4850 fix: update CURRENT_SCHEMA_VERSION to 2 for upcoming migration 2026-01-19 13:16:48 +07:00
Ivan Kalashnikov
5002bae1c0 fix: add todo comment to bump CURRENT_SCHEMA_VERSION for upcoming migration 2026-01-19 01:09:00 +07:00
Ivan Kalashnikov
325e24f461 fix: revert CURRENT_SCHEMA_VERSION to 1 2026-01-19 00:03:33 +07:00
Ivan Kalashnikov
6705033d15 feat: implement migration to move settings from MiscConfig to TasksConfig 2026-01-18 23:31:06 +07:00
Ivan Kalashnikov
2473b9698d fix: update migration test to correctly structure migrated state with globalConfig 2026-01-18 23:30:57 +07:00
Ivan Kalashnikov
d6506e95d1 refactor: rename test spec migration in format 'v1 to v2' 2026-01-18 23:18:42 +07:00
Ivan Kalashnikov
651d5dc183 feat: add migration to move settings from MiscConfig to TasksConfig as separate file 2026-01-18 23:08:30 +07:00
Ivan Kalashnikov
f2940fd7ae fix: remove outdated todo comment regarding schema version synchronization 2026-01-18 23:07:12 +07:00
Ivan Kalashnikov
0d6d17c103 fix: correct task confirmation field name in migration test 2026-01-18 23:06:37 +07:00
Ivan Kalashnikov
5f4e1cf24e fix: correct task migration field names and add markdown formatting flag 2026-01-18 21:54:24 +07:00
Ivan Kalashnikov
73c9c05c32 refactor: rename task settings field 2026-01-18 21:53:16 +07:00
Ivan Kalashnikov
a617ff4e29 fix: update MiscConfig to mark isTurnOffMarkdown as deprecated 2026-01-18 21:50:11 +07:00
Ivan Kalashnikov
bd2615e7d7 fix: update migration versions from 16 to 1 and 17 to 2 for consistency 2026-01-18 21:28:43 +07:00
Ivan Kalashnikov
088971d22b refactor: update validateMigrationRegistry test comments for clarity 2026-01-18 21:14:22 +07:00
Ivan Kalashnikov
aedab573a0 test: add migration tests for moving settings from MiscConfig to TasksConfig 2026-01-18 21:10:05 +07:00
Ivan Kalashnikov
92d7d4aafe fix: update CURRENT_SCHEMA_VERSION to 17 for new migrations 2026-01-18 21:08:31 +07:00
Ivan Kalashnikov
b565173664 feat: add migration to move settings from MiscConfig to TasksConfig 2026-01-18 21:08:19 +07:00
Johannes Millan
213d0ec010 chore(plugins): remove debug logging from procrastination-buster i18n 2026-01-16 22:34:50 +01:00
Johannes Millan
9be6bf7c27 fix(plugins): initialize current language on plugin mount
Fixed i18n to fetch and use the current language when the plugin
initializes, instead of always defaulting to English. Now the plugin
will show the correct language immediately on first load, and also
update reactively when the language changes.

Changes:
- Added getCurrentLanguage() call in useTranslate initialization
- Changed onMount to createEffect for reactive language loading
- Updated both App.tsx and ProcrastinationInfo.tsx to use createEffect
- Applied fixes to both procrastination-buster and boilerplate
- Added debug logging to troubleshoot language change events

This fixes the issue where plugins always started in English regardless
of the user's selected language.
2026-01-16 22:34:50 +01:00
Johannes Millan
fb05e7be3e chore(plugins): remove debug logging from procrastination-buster 2026-01-16 22:34:50 +01:00
Johannes Millan
de264aff48 fix(plugins): fix i18n message protocol for iframe communication
Fixed the message passing between plugin iframes and plugin.ts to use
the proper PLUGIN_MESSAGE/PLUGIN_MESSAGE_RESPONSE protocol instead of
custom messages. This ensures translations and other messages are
correctly routed through the plugin bridge.

Changes:
- Updated useTranslate to use PLUGIN_MESSAGE type
- Listen for PLUGIN_MESSAGE_RESPONSE instead of custom response
- Wrap message in { type, payload } structure
- Updated plugin.ts to read from message.payload
- Added debug logging for troubleshooting
- Applied fixes to both procrastination-buster and boilerplate
2026-01-16 22:34:50 +01:00
Johannes Millan
1df40ab02d fix(plugins): fix translation loading in procrastination-buster
Changed message.data to message.payload in the onMessage handler
to match the structure sent by useTranslate hook. This fixes the
issue where translations were not loading in the UI.
2026-01-16 22:34:50 +01:00
Johannes Millan
92fd9301fe fix(plugins): remove duplicate side panel registration in procrastination-buster
Remove manual registerSidePanelButton() call since the side panel button
is already automatically registered via manifest.json with 'sidePanel: true'.

This fixes:
- Duplicate side panel button warning
- Plugin loading in both side panel and main view simultaneously

The manifest-based registration is sufficient and avoids duplication.
2026-01-16 22:34:50 +01:00
Johannes Millan
91fe3652dc fix(plugins): copy directories recursively in build script
Add copyRecursive() helper function to handle both files and directories
when copying plugin builds to bundled-plugins. This ensures i18n folders
and other directories are properly copied.

Previously, only files were copied (checking isFile()), which caused i18n
folders to be skipped. Now all three plugin build commands (procrastination-
buster, sync-md, ai-productivity-prompts) properly copy directory trees.

Fixes: 404 errors for i18n/de.json and other directory contents
2026-01-16 22:34:50 +01:00
Johannes Millan
ba0e9ce002 fix(plugins): resolve PluginHooks runtime error in procrastination-buster
Replace PluginHooks.LANGUAGE_CHANGE enum reference with string literal
'languageChange' to fix runtime error. The type-only import of PluginHooks
was not available at runtime, causing "PluginHooks is not defined" error
when installing the plugin.

The hook registration now uses the string value directly:
- Before: plugin.registerHook(PluginHooks.LANGUAGE_CHANGE, ...)
- After: plugin.registerHook('languageChange', ...)
2026-01-16 22:34:50 +01:00
Johannes Millan
ce17c00690 feat(plugins): add German translations to procrastination-buster
- Add comprehensive de.json with 80 German translation keys
- Update manifest.json to include German language support
- Translate all UI strings: home, navigation, strategies, info
- Translate all 8 procrastination types with emotions and strategies
- Translate educational content for understanding procrastination

All translation keys match between en.json and de.json for consistency.
2026-01-16 22:34:50 +01:00
Johannes Millan
2550f91cb7 feat(plugins): add i18n support to procrastination-buster plugin
- Add comprehensive English translations (en.json) for all UI strings
- Add useTranslate() hook for reactive translations
- Update manifest.json with i18n configuration
- Add i18n message handlers to plugin.ts
- Create getProcrastinationTypes() for dynamic translation loading
- Update App.tsx to use translations throughout
- Update ProcrastinationInfo.tsx with full translation support
- All 8 procrastination types, strategies, and info content now translatable

The plugin now supports internationalization with complete English translations
and can easily be extended to support additional languages.
2026-01-16 22:34:50 +01:00
Johannes Millan
eb120baf1b feat(plugins): add i18n support to boilerplate-solid-js
- Add useTranslate() hook for reactive translations in SolidJS
- Include example translation files (en.json, de.json)
- Update Vite plugin to copy i18n folder during build
- Add i18n message handlers to plugin.ts
- Demonstrate i18n usage in App.tsx with ~10 translation keys
- Update documentation with comprehensive i18n guide
- Add i18n to features list in main plugin-dev README

The boilerplate now provides a complete working example of multi-language
plugin support, making it easy for developers to create internationalized
plugins.
2026-01-16 22:34:50 +01:00
Johannes Millan
5bb8b24c82 docs(plugins): add comprehensive i18n documentation
Phase 7: Create documentation

- Create PLUGIN_I18N.md with complete i18n guide
  - Quick start guide with file structure
  - Manifest configuration details
  - Translation file format and best practices
  - Complete API documentation (translate, formatDate, getCurrentLanguage)
  - Language change hook documentation
  - Full list of supported languages (24 languages)
  - Complete working example with multi-language support
  - Best practices and troubleshooting sections
  - Migration guide from hard-coded strings
  - Testing and performance considerations

- Update README.md with i18n section
  - Add i18n API methods to Plugin API section
  - Add languageChange hook to hooks list
  - Add i18n example to usage section
  - Add i18n files to optional files list
  - Add i18n best practice
  - Link to comprehensive PLUGIN_I18N.md guide

Documentation provides complete guide for plugin developers to add
multi-language support to their plugins with working examples.
2026-01-16 17:55:34 +01:00
Johannes Millan
95578ef77b feat(plugins): add plugin i18n foundation (Phase 0-1)
- Add i18n field to PluginManifest type in plugin-api package
- Create PluginI18nService for translation management
  - Load translations from file paths or cached content
  - Nested key lookup with dot notation (e.g., BUTTONS.SAVE)
  - Smart fallback: current language → English → key
  - Parameter interpolation with {{param}} syntax
  - Language switching via signals
  - Memory cleanup for unloaded plugins
- Add type validation for cached translation content
- Document language sync integration points

Part of plugin internationalization system implementation.
Tests will be added in Phase 8.
2026-01-16 17:52:13 +01:00
Johannes Millan
59292abacb refactor(date): use getDbDateStr() utility for consistent date formatting
Replace inline `.toISOString().split('T')[0]` pattern with getDbDateStr()
utility across production code, tests, and plugin examples.

Changes:
- Production: 6 files (plugin-bridge, metrics, counters, task-repeat-cfg)
- Tests: 4 spec files (helper functions and direct uses)
- Plugin example: Added formatDateStr() helper matching main app pattern

This ensures consistent local timezone handling for all user-facing date
operations and provides a single source of truth for date string formatting.
2026-01-16 13:28:05 +01:00
Johannes Millan
f9fd8454cc fix(sync-md): prevent crash when adding subtasks to markdown file directly
Fixes #6021

When users manually added subtasks to markdown files that referenced
non-existent parent tasks, the plugin would crash due to unsafe null
assertions and missing validation. This made the plugin permanently
disabled and required creating a new markdown file to recover.

Changes:
- Added parent ID validation before creating operations
- Orphaned subtasks are now converted to root tasks with warnings
- Added comprehensive error handling with user notifications
- Plugin stays enabled even after sync errors
- Added 15 new tests (689 lines) for orphaned subtask scenarios
- Fixed all existing tests to support new error notifications

The fix implements defense-in-depth:
1. Validation layer: Check parent IDs exist before operations
2. Error handling: Catch and report errors without crashing
3. User feedback: Clear notifications about issues
4. Data preservation: No data loss, orphans become root tasks
2026-01-16 13:28:05 +01:00
Johannes Millan
2f7a00371a fix(supersync): improve GDPR compliance in legal documents
- Remove placeholder address text from privacy policies (DE/EN)
- Expand HTML privacy policy with full GDPR disclosures:
  - Legal bases (Art. 6), data subject rights (Art. 15-22)
  - Supervisory authority, retention periods, DPA info
  - Cookies/tracking and automated decision-making sections
- Align HTML terms with German ToS:
  - Add proper termination notice periods (2 weeks/good cause)
  - Add 6-week notice for ToS amendments
  - Add consumer withdrawal rights (14 days)
  - Add ODR platform link and jurisdiction info
2026-01-15 12:48:18 +01:00
Johannes Millan
a1d736010c fix(plugins): fix empty side panel for AI Productivity Prompts plugin
The plugin was using a custom vite.config.ts that generated separate
JS/CSS files with broken relative paths. When loaded in a blob URL
iframe, these paths couldn't resolve.

- Switch to @super-productivity/vite-plugin which inlines assets
- Fix title from "Procrastination Buster" to "AI Productivity Prompts"
2026-01-15 11:04:12 +01:00
Johannes Millan
cee12a444a fix(sync): pass op.id to uploadSnapshot to prevent ID mismatch
When uploading BACKUP_IMPORT via uploadSnapshot(), the client's op.id
was not sent to the server. The server would generate its own ID,
causing the client to not recognize the operation when downloaded later.
This led to data loss as the old backup state would be re-applied.

Changes:
- Add opId parameter to uploadSnapshot() interface
- Pass op.id from operation-log-upload.service.ts
- Send opId in SuperSync API request payload
- Server uses client's opId instead of generating new one
- Add E2E test to verify ID matching

The fix is backwards compatible - legacy clients without opId still work
as the server falls back to uuidv7() when opId is not provided.
2026-01-14 21:57:08 +01:00
Johannes Millan
e7e693e78f fix(sync-server): add rate limiting to page endpoints
Add explicit per-route rate limits to /verify-email and /magic-login
endpoints to address CodeQL security alerts. These endpoints previously
relied only on global rate limiting.
2026-01-13 18:26:45 +01:00
Johannes Millan
9d77aa2d3f fix(build): add shared-schema to prepare script for CI builds
The shared-schema package was not being built before lint and test
steps in CI, causing "Cannot find module '@sp/shared-schema'" errors.

Changes:
- Add shared-schema:build script to package.json
- Update prepare script to build shared-schema first
- Add shared-schema to build-packages.js for completeness
2026-01-11 16:11:36 +01:00
Johannes Millan
23579a448a fix(shared-schema): use tsup for dual ESM/CJS build
The previous commit changed module resolution to bundler mode which
fixed Angular tests but broke Node.js ESM imports in super-sync-server.

Switch to tsup bundler that outputs both ESM (.mjs) and CJS (.js) formats,
with proper exports field to support both environments:
- CJS for super-sync-server (Node.js commonjs)
- ESM for Angular/webpack bundler imports
2026-01-11 14:05:23 +01:00
Johannes Millan
bc869d359f fix(shared-schema): fix module resolution for bundler compatibility
- Change shared-schema tsconfig to use bundler moduleResolution
- Remove .js extensions from imports (incompatible with bundler mode)
- Fix tsconfig.spec.json to include both package path mappings

The shared-schema package was using NodeNext module resolution which
requires .js extensions in imports. Since the main Angular project
uses bundler resolution and imports directly from source files,
this caused webpack to fail finding the modules during tests.
2026-01-11 13:20:16 +01:00
Johannes Millan
187bfaf24c fix(docker): upgrade npm to v11 to match lockfile version
npm 10.9.4 bundled with node:22-alpine handles optional peer
dependencies differently than npm 11, causing build failures
when resolving vitest peer dep from @angular-devkit/build-angular.
2026-01-10 19:08:38 +01:00
Johannes Millan
6501950760 fix: resolve build issues and update E2E tests for sync import conflict
- Fix TypeScript error in passkey.ts (Buffer to Uint8Array conversion)
- Update Dockerfile.test to use npm install instead of npm ci for workspace sync
- Update E2E test to not setup sync before import
- Add additional unit tests for sync-wrapper.service

Note: E2E tests for sync import conflict dialog need further work due to
automatic upload of SYNC_IMPORT when sync is enabled. The core dialog
functionality is implemented and unit tested.
2026-01-10 18:48:47 +01:00