Skip to content

v2.0.0 updated with changes removing legacy support#2594

Merged
gtsteffaniak merged 2 commits into
dev/v2.0.0from
additional-legacy-changes
Jul 2, 2026
Merged

v2.0.0 updated with changes removing legacy support#2594
gtsteffaniak merged 2 commits into
dev/v2.0.0from
additional-legacy-changes

Conversation

@gtsteffaniak

@gtsteffaniak gtsteffaniak commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Description

According to the contributing guide, A PR should contain:

  • A clear description of why it was opened.
  • A short title that best describes the change.
  • Must pass unit and integration tests, which can be run checked locally prior to opening a PR.
  • Any additional details for functionality not covered by tests.

Additional Details

Summary by CodeRabbit

  • New Features
    • Search now uses a clearer scoped format for multi-source queries.
    • Public share pages are now served via standardized /public/share URL paths.
    • Permissions editing UI now shows only for admins when permissions data is present.
  • Bug Fixes
    • Share downloads and preview links now work with the updated public share route.
    • Activity labels now correctly show download events.
    • App notification settings now consistently read from the current storage key.
  • Documentation
    • Changelog migration notes and search API documentation were refreshed to remove legacy references.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR removes v1.x legacy compatibility across config, search, activity, share routing, notifications, and related tests. It also updates the changelog and bumps the ffmpeg Docker base image.

Changes

Legacy v1 compatibility removal

Layer / File(s) Summary
Conditional rules and user-default legacy struct refactor
backend/common/settings/structs.go
ConditionalRule uses singular fileName/folderName, and deprecated flat user-default/preview fields move into embedded YAML-only legacy structs.
Rule compilation and config generation
backend/common/settings/config.go, backend/common/settings/generator*.go, backend/common/settings/migration_test.go, _docker/src/noauth/backend/config.yaml
Rule resolution and YAML generation use the new rule/layout shapes, with tests and sample config updated to the legacy/organized field split.
Conditional rules test helper migration
backend/indexing/conditionalRules_test.go, backend/indexing/indexing_test.go
Conditional-rule tests migrate to []ConditionalRule and direct ResolvedRules setup.
Indexing scheduler always adaptive
backend/indexing/indexingFiles.go, backend/indexing/indexingSchedulerLoop.go
Adaptive scheduling is always enabled and the fixed-interval loop is removed.
Legacy share-download event and filtering removal
backend/database/activity/*, backend/database/sqldb/activity*.go, backend/http/activity_filter.go, frontend/src/utils/activityDetails.js
The share-download event type, owned-share-hash filtering, and legacy share-owner query path are removed, with SQL/tests/labels updated to the new download/share-owner flow.
User ApiKeys legacy field
backend/database/users/users.go
ApiKeys is moved into an embedded legacy struct.
Legacy routes and share hash parsing
backend/http/httpRouter.go, backend/http/share.go, backend/icons/manifest_share*.go
Legacy /raw routes and the share redirect helper are removed, /share/ serves the index directly, and share-hash parsing is limited to /public/share/.
Search API legacy scope/query removal
backend/http/search.go, frontend/src/api/search.js, frontend/src/api/tools.js, frontend/src/views/tools/AdvancedSearch.vue
Search now uses sourceName:relativePath scope pairs and drops legacy scope/glob/bare-scope behavior.
Playwright share URL updates
frontend/tests/playwright/**/*.spec.ts
Share tests move to /public/share/... URLs and simplify checkForErrors() calls.
App notification storage simplification
frontend/src/utils/appNotifications.js
The legacy notification storage prefix and fallback lookup are removed.
Changelog and Dockerfile version bump
CHANGELOG.md, _docker/Dockerfile
The changelog records the breaking removals, and the ffmpeg image tag is updated.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Poem

Hop, hop, the old paths fade away,
New scopes and hashes lead the way.
The fox is gone from legacy lore,
My rabbit paws now tap once more,
In tidy burrows, fresh and neat—
🐇✨ the refactor keeps the beat.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main theme of removing legacy support across v2.0.0.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch additional-legacy-changes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/tests/playwright/noauth/share.spec.ts (1)

57-64: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Stale checkForErrors(0,1) likely breaks after redirect removal.

This "share download single file" flow now navigates directly to /files/public/share/.../testdata/ (line 57), but line 63 still asserts 1 expected API error with comment // redirect errors are expected. The functionally identical test in frontend/tests/playwright/sharing/share.spec.ts (lines 33-39) was updated to checkForErrors() for the same scenario, since the legacy redirect that caused this error was removed in this cohort. This test was likely missed during migration and will fail once the redirect no longer fires.

🐛 Proposed fix
   await checkForNotification(page, "Downloading...");
-  checkForErrors(0,1); // redirect errors are expected
+  checkForErrors();
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/tests/playwright/noauth/share.spec.ts` around lines 57 - 64, The
share download single-file Playwright test still expects a redirect-related API
error via checkForErrors(0,1), but that legacy redirect path has been removed.
Update the test in share.spec.ts to match the newer share flow used by the
corresponding test in sharing/share.spec.ts by removing the stale error
expectation and calling checkForErrors() without arguments after the Download
action.
backend/indexing/conditionalRules_test.go (1)

11-90: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Test helper duplicates setConditionals' resolved-rules construction logic.

setupConditionalTestIndex reimplements essentially the same map-building loop as settings.setConditionals (config.go, lines 1282-1360): initializing the same map/slice fields, inferring the same root-level global flags, and populating FileNames/FolderNames/FilePaths/FolderPaths/etc. from the same ConditionalRule fields. Since setConditionals is unexported in package settings, this test in package indexing can't call it directly, so the logic was copied instead.

This duplication is a real drift risk: if setConditionals changes (e.g., a new rule field is added or the root-level-flag inference logic changes), the test helper can silently diverge from production behavior and continue passing while the app misbehaves — which is effectively the same failure mode as the missing FileNames/FolderNames migration flagged in config.go.

Consider exporting a single source-of-truth function in the settings package (e.g., settings.ResolveRules(rules []ConditionalRule) ResolvedRulesConfig) that both setConditionals and this test helper call, eliminating the duplicate implementation.

As per path instructions, "reduce duplication where there is clear duplication found, use consolidated functions."

♻️ Sketch of a consolidated helper
+// ResolveRules builds optimized map/slice lookup structures from a set of rules.
+// Exported so callers (production config loading and tests) share one implementation.
+func ResolveRules(rules []ConditionalRule) ResolvedRulesConfig {
+	resolved := ResolvedRulesConfig{
+		FileNames:                make(map[string]ConditionalRule),
+		FolderNames:              make(map[string]ConditionalRule),
+		FilePaths:                make(map[string]ConditionalRule),
+		FolderPaths:              make(map[string]ConditionalRule),
+		FileEndsWith:             make([]ConditionalRule, 0),
+		FolderEndsWith:           make([]ConditionalRule, 0),
+		FileStartsWith:           make([]ConditionalRule, 0),
+		FolderStartsWith:         make([]ConditionalRule, 0),
+		NeverWatchPaths:          make(map[string]struct{}),
+		IncludeRootItems:         make(map[string]struct{}),
+		NoRules:                  len(rules) == 0,
+	}
+	// ... existing loop body from setConditionals ...
+	return resolved
+}

 func setConditionals(config *Source) {
-	rules := config.Config.Rules
-	resolved := ResolvedRulesConfig{ ... }
-	for _, rule := range rules { ... }
-	config.Config.ResolvedRules = resolved
+	config.Config.ResolvedRules = ResolveRules(config.Config.Rules)
 }
 func setupConditionalTestIndex(rules []settings.ConditionalRule) *Index {
 	source := &settings.Source{
 		Name: "test",
 		Path: "/test/path",
 		Config: settings.SourceConfig{
 			Rules: rules,
+			ResolvedRules: settings.ResolveRules(rules),
 		},
 	}
-	resolved := settings.ResolvedRulesConfig{ ... }
-	for _, rule := range rules { ... }
-	source.Config.ResolvedRules = resolved
 	return &Index{Source: *source, mock: true}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/indexing/conditionalRules_test.go` around lines 11 - 90, The test
helper setupConditionalTestIndex is duplicating the resolved-rules construction
logic from settings.setConditionals, which creates drift risk. Extract the
shared rule-resolution logic into a single settings package helper, such as
ResolveRules or similar, and have both setConditionals and
setupConditionalTestIndex use it. Keep the helper responsible for building
ResolvedRulesConfig from ConditionalRule fields, including the root-level flags
and all name/path maps.

Source: Path instructions

🧹 Nitpick comments (4)
_docker/Dockerfile (1)

1-1: 🧹 Nitpick | 🔵 Trivial

Verify the new ffmpeg tag before merging.

This update changes the upstream binaries copied into the image. Please confirm 8.1.2-decode is intentional and that /ffmpeg and /ffprobe still exist in the base image.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@_docker/Dockerfile` at line 1, The Dockerfile’s ffmpeg base image tag needs
to be verified before merging because it changes the upstream binaries used by
the build. Check the FROM instruction that uses gtstef/ffmpeg:8.1.2-decode and
confirm the tag is intentional, then verify the ffmpeg and ffprobe assets are
still present at the expected locations in the base image so the later copy
steps continue to work.
backend/database/users/users.go (1)

136-154: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a marshal/unmarshal round-trip test for the embedded legacy struct.

Given the subtlety of anonymous-embedding + JSON tag interactions (see prior comment) and multiple downstream consumers (backend/cmd/user.go, backend/http/users.go, backend/state/users.go) relying on user.ApiKeys and the "apiKeys" JSON key still working after this refactor, a small unit test confirming json.Marshal/Unmarshal still round-trips ApiKeys correctly on User would guard against regressions if the embedding is changed again later.

As per path instructions, "ensure functional features include new unit tests where its easily possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/database/users/users.go` around lines 136 - 154, The embedded legacy
fields in User need a round-trip JSON regression test to ensure anonymous
embedding and the apiKeys tag still behave correctly. Add a unit test around
User (and UserLegacyFields if needed) that marshals then unmarshals a User with
ApiKeys populated, and verifies the "apiKeys" key and user.ApiKeys value survive
unchanged; use the User and UserLegacyFields types so future embedding/tag
changes don’t break downstream consumers.

Source: Path instructions

backend/http/search.go (1)

131-157: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add table-driven tests for parseRepeatedScopeParams. Cover the new sourceName:relativePath contract: empty-source rejection, missing-colon rejection, path sanitization, and the default / for blank paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/http/search.go` around lines 131 - 157, Add table-driven tests for
parseRepeatedScopeParams to cover the new sourceName:relativePath parsing
contract: verify it rejects inputs with no colon and with an empty source name,
confirm it sanitizes the path part before building scopedSourcePath, and check
that a blank path after the colon defaults to "/". Use parseRepeatedScopeParams
and scopedSourcePath in the test cases so the behavior stays tied to the
existing helper.

Source: Path instructions

backend/common/settings/config.go (1)

1362-1418: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a focused test for normalizeName trimming behavior.

The new normalizeName helper (trims / from FileName/FolderName) is exercised only indirectly through the broader ShouldSkip/IsViewable test suite in conditionalRules_test.go. A small table test asserting that a rule with FileName: "/foo/" or FolderName: "/bar/" gets normalized to "foo"/"bar" before being written back to config.Config.Rules would make this behavior explicit and regression-proof.

As per path instructions, "ensure functional features include new unit tests where its easily possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/common/settings/config.go` around lines 1362 - 1418, Add a focused
unit test for modifyExcludeInclude that directly verifies normalizeName behavior
on config.Config.Rules. Create a small table test covering FileName and
FolderName inputs like "/foo/" and "/bar/" and assert they are written back as
"foo" and "bar" after modifyExcludeInclude runs. Keep the test close to the
existing conditional rules tests so this normalization step is explicitly
covered, not only exercised indirectly through ShouldSkip or IsViewable.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@backend/indexing/conditionalRules_test.go`:
- Around line 11-90: The test helper setupConditionalTestIndex is duplicating
the resolved-rules construction logic from settings.setConditionals, which
creates drift risk. Extract the shared rule-resolution logic into a single
settings package helper, such as ResolveRules or similar, and have both
setConditionals and setupConditionalTestIndex use it. Keep the helper
responsible for building ResolvedRulesConfig from ConditionalRule fields,
including the root-level flags and all name/path maps.

In `@frontend/tests/playwright/noauth/share.spec.ts`:
- Around line 57-64: The share download single-file Playwright test still
expects a redirect-related API error via checkForErrors(0,1), but that legacy
redirect path has been removed. Update the test in share.spec.ts to match the
newer share flow used by the corresponding test in sharing/share.spec.ts by
removing the stale error expectation and calling checkForErrors() without
arguments after the Download action.

---

Nitpick comments:
In `@_docker/Dockerfile`:
- Line 1: The Dockerfile’s ffmpeg base image tag needs to be verified before
merging because it changes the upstream binaries used by the build. Check the
FROM instruction that uses gtstef/ffmpeg:8.1.2-decode and confirm the tag is
intentional, then verify the ffmpeg and ffprobe assets are still present at the
expected locations in the base image so the later copy steps continue to work.

In `@backend/common/settings/config.go`:
- Around line 1362-1418: Add a focused unit test for modifyExcludeInclude that
directly verifies normalizeName behavior on config.Config.Rules. Create a small
table test covering FileName and FolderName inputs like "/foo/" and "/bar/" and
assert they are written back as "foo" and "bar" after modifyExcludeInclude runs.
Keep the test close to the existing conditional rules tests so this
normalization step is explicitly covered, not only exercised indirectly through
ShouldSkip or IsViewable.

In `@backend/database/users/users.go`:
- Around line 136-154: The embedded legacy fields in User need a round-trip JSON
regression test to ensure anonymous embedding and the apiKeys tag still behave
correctly. Add a unit test around User (and UserLegacyFields if needed) that
marshals then unmarshals a User with ApiKeys populated, and verifies the
"apiKeys" key and user.ApiKeys value survive unchanged; use the User and
UserLegacyFields types so future embedding/tag changes don’t break downstream
consumers.

In `@backend/http/search.go`:
- Around line 131-157: Add table-driven tests for parseRepeatedScopeParams to
cover the new sourceName:relativePath parsing contract: verify it rejects inputs
with no colon and with an empty source name, confirm it sanitizes the path part
before building scopedSourcePath, and check that a blank path after the colon
defaults to "/". Use parseRepeatedScopeParams and scopedSourcePath in the test
cases so the behavior stays tied to the existing helper.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 63e7c398-8508-4fa7-a444-73e5a03f2797

📥 Commits

Reviewing files that changed from the base of the PR and between 0324f37 and ccb0824.

⛔ Files ignored due to path filters (3)
  • backend/swagger/docs/docs.go is excluded by !backend/swagger/**
  • backend/swagger/docs/swagger.json is excluded by !backend/swagger/**
  • backend/swagger/docs/swagger.yaml is excluded by !backend/swagger/**
📒 Files selected for processing (34)
  • CHANGELOG.md
  • _docker/Dockerfile
  • _docker/src/noauth/backend/config.yaml
  • backend/common/settings/config.go
  • backend/common/settings/generator_simple_test.go
  • backend/common/settings/generator_test.go
  • backend/common/settings/migration_test.go
  • backend/common/settings/structs.go
  • backend/database/activity/activity.go
  • backend/database/activity/event_type.go
  • backend/database/sqldb/activity.go
  • backend/database/sqldb/activity_test.go
  • backend/database/users/users.go
  • backend/http/activity_filter.go
  • backend/http/httpRouter.go
  • backend/http/search.go
  • backend/http/share.go
  • backend/icons/manifest_share.go
  • backend/icons/manifest_share_test.go
  • backend/indexing/conditionalRules_test.go
  • backend/indexing/indexingFiles.go
  • backend/indexing/indexingSchedulerLoop.go
  • backend/indexing/indexing_test.go
  • frontend/src/api/search.js
  • frontend/src/api/tools.js
  • frontend/src/utils/activityDetails.js
  • frontend/src/utils/appNotifications.js
  • frontend/src/views/tools/AdvancedSearch.vue
  • frontend/tests/playwright/noauth/share.mobile.spec.ts
  • frontend/tests/playwright/noauth/share.spec.ts
  • frontend/tests/playwright/previews/share.spec.ts
  • frontend/tests/playwright/sharing/navigation.spec.ts
  • frontend/tests/playwright/sharing/share.mobile.spec.ts
  • frontend/tests/playwright/sharing/share.spec.ts
💤 Files with no reviewable changes (7)
  • backend/icons/manifest_share.go
  • backend/icons/manifest_share_test.go
  • backend/indexing/indexingSchedulerLoop.go
  • backend/http/activity_filter.go
  • backend/http/httpRouter.go
  • backend/http/share.go
  • frontend/src/utils/activityDetails.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/prompts/UserEdit.vue`:
- Around line 322-346: `normalizeFormUser` in `UserEdit.vue` uses loose null
checks that violate `eqeqeq`; update the `user.permissions` and
`user.account?.permissions` conditionals to use strict null comparisons (`===
null` / `!== null`) while preserving the same fallback behavior. Keep the
changes local to `normalizeFormUser` and `defaultPermissions` so the permissions
normalization logic remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8c1f7ed-b99e-48c5-96bf-f9ab265de168

📥 Commits

Reviewing files that changed from the base of the PR and between ccb0824 and 0118279.

📒 Files selected for processing (4)
  • _docker/src/noauth/backend/config.yaml
  • frontend/src/components/prompts/UserEdit.vue
  • frontend/tests/playwright/noauth/share.spec.ts
  • frontend/tests/playwright/sharing/navigation.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/tests/playwright/sharing/navigation.spec.ts

Comment thread frontend/src/components/prompts/UserEdit.vue
@gtsteffaniak gtsteffaniak changed the title updated with changes removing legacy support v2.0.0 updated with changes removing legacy support Jul 2, 2026
@gtsteffaniak gtsteffaniak merged commit a58dc77 into dev/v2.0.0 Jul 2, 2026
22 checks passed
@gtsteffaniak gtsteffaniak deleted the additional-legacy-changes branch July 2, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant