Skip to content

feat(cli): add URL prefix fix command - #1600

Open
Octobug wants to merge 1 commit into
apache:devfrom
Octobug:feat/fix-cmd-for-uploaded-files
Open

feat(cli): add URL prefix fix command#1600
Octobug wants to merge 1 commit into
apache:devfrom
Octobug:feat/fix-cmd-for-uploaded-files

Conversation

@Octobug

@Octobug Octobug commented Aug 30, 2026

Copy link
Copy Markdown
Contributor
go run cmd/answer/main.go fix --help
Fix stored URL prefixes for branding, avatars, and post content.

WARNING: Stop Answer and back up your database before running this command.

Rows already using DST_PREFIX are skipped so the command can be rerun safely.
If a text field contains both prefixes, it will be skipped and reported.

After fixing branding data, the related site info cache will be invalidated.

Usage:
  answer fix [all|branding|avatar|post] SRC_PREFIX DST_PREFIX [flags]

Examples:
  # Preview what would change
  answer fix all /uploads/ /uploads/new/ --dry-run

  # Fix up to 50 rows
  answer fix all /uploads/ /cdn/ --limit 50

  # Fix only avatars
  answer fix avatar /uploads/ /cdn/

Flags:
      --dry-run     show what would be changed without modifying the database
  -h, --help        help for fix
      --limit int   stop after fixing NUM rows total across all selected fix types (0 = unlimited)

Global Flags:
  -C, --data-path string   data path, eg: -C ./data/ (default "/data/")

I've tested locally with fake data generated in sqlite db, including:

  • 50,000 question
  • 50,000 revision
  • 250,000 answer
  • 250,000 file records

It took about 10 minutes to complete the fixing.

3427590a0f1f000115bfed7d97c05bfc

closes apache#861

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 30, 2026 11:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new answer fix CLI command to rewrite stored URL prefixes across branding assets, user avatars, and post content (including revisions and file records), with support for dry-run and a global row limit. This fits into the codebase as an administrative maintenance tool for safely migrating stored paths (e.g., /uploads//cdn/) while Answer is stopped.

Changes:

  • Introduces URL-prefix classification and batched DB rewrite logic for branding, avatars, posts/revisions, and file_record URLs.
  • Adds cache invalidation for branding site-info when using file-backed cache storage.
  • Wires a new Cobra command (answer fix ...) with --dry-run and --limit flags.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/cli/fix.go Core fix orchestration, prefix classification/replacement utilities, batching, and summary output.
internal/cli/fix_post.go Applies prefix fixes to question/answer bodies, revisions, and post-related file records.
internal/cli/fix_filerecord.go Updates file_record.file_url for selected sources.
internal/cli/fix_cache.go Invalidates branding site-info cache in file-backed memory cache.
internal/cli/fix_branding.go Fixes branding JSON fields in site_info and related branding file records.
internal/cli/fix_avatar.go Fixes custom avatar URLs in user avatar JSON and related avatar file records.
cmd/command.go Adds the fix command and its flags to the CLI.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +74 to +76
if err := json.Unmarshal([]byte(user.Avatar), avatar); err != nil {
return nil
}
Comment thread internal/cli/fix_post.go
Comment on lines +164 to +175
switch classifyText(texts, opts.SrcPrefix, opts.DstPrefix, markers) {
case matchBoth:
fmt.Printf("[%s] WARN %s: has BOTH prefixes, skipping (manual fix needed)\n", label, target)
result.Skipped++
return nil
case matchSkip:
fmt.Printf("[%s] skip %s: already has DST_PREFIX\n", label, target)
result.Skipped++
return nil
case matchNone:
return nil
}
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.

2 participants