Files
yellowjacket/.planning/milestones/v1.1-phases/11-per-library-scan-pipeline/11-03-PLAN.md
T
2026-03-16 16:08:27 -04:00

7.5 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
11-per-library-scan-pipeline 03 execute 2
11-01
backend/app.go
backend/library/library.go
true
LSCAN-01
LSCAN-02
truths artifacts key_links
App auto-scans all libraries on launch using ScanAllLibraries
Legacy LibraryConfigChanged event handler is removed or updated for multi-library
Library struct no longer requires Config.DirectoryPath to function
path provides
backend/app.go Updated OnDomReady or OnStartup to trigger ScanAllLibraries on launch
path provides
backend/library/library.go Updated NewLibrary constructor — Config no longer required
from to via pattern
backend/app.go backend/library/scan_queue.go ScanAllLibraries call on startup library.ScanAllLibraries
Wire the per-library scan pipeline into app startup and clean up legacy single-directory scanning paths.

Purpose: Ensure auto-scan on launch uses ScanAllLibraries() (same codepath as the UI button per CONTEXT.md), and remove/update legacy LibraryConfigChanged handler that assumed a single directory. Output: Updated app.go startup wiring, cleaned-up Library constructor.

<execution_context> @/home/caleb/.config/opencode/get-shit-done/workflows/execute-plan.md @/home/caleb/.config/opencode/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/11-per-library-scan-pipeline/11-CONTEXT.md @.planning/phases/11-per-library-scan-pipeline/11-01-SUMMARY.md From backend/library/scan_queue.go (created in Plan 01): ```go func (l *Library) ScanLibrary(id int64) error func (l *Library) ScanAllLibraries() error func (l *Library) CancelCurrentScan() func (l *Library) CancelAllScans() ```

From backend/app.go (current):

func (yj *YellowJacketApp) OnStartup(ctx context.Context)
// Currently: yj.library.SetContext(ctx)
// Currently: library is created with appConfig.Library (Config with DirectoryPath)

func NewYellowJacketApp(...) {
    lib, err := library.NewLibrary(
        yjApp.appContext,
        yjApp.logger,
        yjApp.appConfig.Library, // Config with DirectoryPath
        yjApp.database,
    )
}

From backend/library/library.go (current event handler):

func (l *Library) registerEventHandlers() {
    runtime.EventsOn(l.ctx, events.LibraryConfigChanged, func(data ...any) {
        // Parses DirectoryPath from event data, calls l.handleConfigUpdate
    })
}
Task 1: Wire auto-scan on startup and clean up legacy single-directory code backend/app.go backend/library/library.go 1. **Update `NewLibrary` constructor** in `backend/library/library.go`: - Make `*Config` parameter optional/removable. The Library no longer needs a pre-configured DirectoryPath because scan paths come from the database. - Keep the `*Config` parameter for backward compatibility but don't require `DirectoryPath` to be set. - Update validation: if `conf` is nil, create a default config with empty DirectoryPath (already handled).
  1. Update registerEventHandlers in backend/library/library.go:

    • Remove the LibraryConfigChanged event handler entirely. This handler assumed a single-directory model where changing the config triggers a scan. In the multi-library model:
      • Libraries are added/removed through the library CRUD API (Phase 12)
      • Scanning is triggered explicitly via ScanLibrary() or ScanAllLibraries()
    • The LibraryConfigChanged event and handleConfigUpdate method can be deleted or marked deprecated
    • Delete handleConfigUpdate method
    • Delete errLibraryDirNotConfigured sentinel error (no longer needed)
  2. Update NewYellowJacketApp in backend/app.go:

    • Change the library.NewLibrary(...) call. The Config parameter is less important now since DirectoryPath is ignored. Pass yjApp.appConfig.Library as before (it still has ScanConcurrency which is useful as a default).
  3. Add auto-scan on startup in backend/app.go:

    • In OnDomReady (or via a goroutine started in OnStartup that waits for DOM ready), trigger auto-scan.
    • Best approach: In OnDomReady, after the startup error check, launch a goroutine:
      go func() {
          if err := yj.library.ScanAllLibraries(); err != nil {
              yj.logger.Error("auto-scan failed", "err", err)
          }
      }()
      
    • This uses the same ScanAllLibraries() codepath as the UI button (per CONTEXT.md: "Auto-scan on launch should use the same ScanAllLibraries() codepath as the UI button — single implementation").
    • It runs in a goroutine so it doesn't block the DOM ready callback.
    • Only run if there are libraries in the DB: check l.db.Queries.CountLibraries(l.ctx) first (or let ScanAllLibraries handle the empty case gracefully by returning immediately when GetAllLibraries returns an empty slice).
  4. Clean up legacy Scan() method:

    • In Plan 01, the old Scan() was kept as backward-compatible wrapper. Now review: since we're removing handleConfigUpdate which was the only caller of the legacy Scan() via l.handleConfigUpdate → l.Scan(), we can either:
      • Keep Scan() for tests (it's used in scan_test.go)
      • Update it to call scanInternal with the library from l.conf.DirectoryPath if set, or return early if not set
    • Keep FullRescan() — it's still called from the config-page UI. It should work with the first/default library. Update it to look up the default library from DB rather than using l.conf.DirectoryPath.
  5. Update FullRescan() in backend/library/rescan.go:

    • Instead of using l.conf.DirectoryPath, look up the first library from DB: libs, err := l.db.Queries.GetAllLibraries(l.ctx) and use libs[0].
    • If no libraries exist, return an error.
    • Call scanInternal(lib.ID, lib.Name, lib.Path) instead of l.Scan().
    • Per-library FullRescan will be added in Phase 12 — for now this rescans the first/only library.

Linting requirements:

  • Doc comments ending with period
  • Blank line after early returns
  • Lines under 100 chars cd /mnt/vault/dev/golang/yellowjacket && go build ./... && go vet ./backend/... && go test ./backend/library/... -count=1 -timeout 60s
  • Auto-scan on startup calls ScanAllLibraries (same codepath as UI button)
  • Legacy LibraryConfigChanged handler removed
  • Legacy handleConfigUpdate removed
  • FullRescan uses library from DB instead of config DirectoryPath
  • go build passes, go vet passes, existing tests pass
```bash # Full build go build ./...

Vet

go vet ./backend/...

Tests pass (including scan_test.go)

go test ./backend/library/... -count=1 -timeout 60s

No references to removed handler

grep -rn "LibraryConfigChanged" backend/library/ | grep -v "_test.go"

Should return no hits (only events.go constant definition, not handler registration)

</verification>

<success_criteria>
- App auto-scans all libraries on launch via ScanAllLibraries
- LibraryConfigChanged handler removed from library package
- handleConfigUpdate removed
- FullRescan works with DB-sourced library (not config DirectoryPath)
- All tests pass, build passes
</success_criteria>

<output>
After completion, create `.planning/phases/11-per-library-scan-pipeline/11-03-SUMMARY.md`
</output>