diff --git a/changedetectionio/store/__init__.py b/changedetectionio/store/__init__.py index 52d137ac1..cd4798b13 100644 --- a/changedetectionio/store/__init__.py +++ b/changedetectionio/store/__init__.py @@ -340,23 +340,22 @@ class ChangeDetectionStore(DatastoreUpdatesMixin, FileSavingDataStore): """ Build settings data structure for saving. - Tags are excluded - they are stored in individual {uuid}/tag.json files. - This keeps changedetection.json small and allows atomic tag updates. + Tags are stored both in settings AND individual {uuid}/tag.json files. + This allows backwards compatibility while enabling atomic tag updates. Returns: - dict: Settings data ready for serialization (without tags) + dict: Settings data ready for serialization (with tags) """ import copy # Deep copy settings to avoid modifying the original settings_copy = copy.deepcopy(self.__data['settings']) - # Replace tags dict with empty dict (tags are in individual tag.json files) - # We keep the empty dict for backwards compatibility and clear structure - settings_copy['application']['tags'] = {} + # Tags remain in settings for backwards compatibility and easy access + # They are ALSO stored in individual tag.json files (dual storage) return { - 'note': 'Settings file - watches are in {uuid}/watch.json, tags are in {uuid}/tag.json', + 'note': 'Settings file - watches are in {uuid}/watch.json, tags are in both settings and {uuid}/tag.json', 'app_guid': self.__data['app_guid'], 'settings': settings_copy, 'build_sha': self.__data.get('build_sha'), diff --git a/changedetectionio/store/updates.py b/changedetectionio/store/updates.py index a0fd8a46e..a6f11efbd 100644 --- a/changedetectionio/store/updates.py +++ b/changedetectionio/store/updates.py @@ -709,18 +709,18 @@ class DatastoreUpdatesMixin: """ Migrate tags to individual tag.json files. - Tags are currently saved as part of changedetection.json (settings). - This migration moves them to individual {uuid}/tag.json files, - similar to how watches are stored. + Tags are currently saved only in changedetection.json (settings). + This migration ALSO saves them to individual {uuid}/tag.json files, + similar to how watches are stored (dual storage). Benefits: - - Reduces changedetection.json size - Allows atomic tag updates without rewriting entire settings - Enables independent tag versioning/backup + - Maintains backwards compatibility (tags stay in settings too) """ logger.critical("=" * 80) logger.critical("Running migration: Individual tag persistence (update_27)") - logger.critical("Moving tags from settings to individual tag.json files") + logger.critical("Creating individual tag.json files (tags remain in settings too)") logger.critical("=" * 80) tags = self.data['settings']['application'].get('tags', {}) @@ -753,9 +753,9 @@ class DatastoreUpdatesMixin: else: logger.success(f"Migration complete: {saved_count} tags saved to individual tag.json files") - # Tags remain in settings for backwards compatibility - # On next load, _load_tags() will read from tag.json files and override settings - logger.info("Tags remain in settings for backwards compatibility") - logger.info("Future tag edits will save to tag.json files only") + # Tags remain in settings for backwards compatibility AND easy access + # On next load, _load_tags() will read from tag.json files and merge with settings + logger.info("Tags saved to both settings AND individual tag.json files") + logger.info("Future tag edits will update both locations (dual storage)") logger.critical("=" * 80) \ No newline at end of file