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 |
|
|
true |
|
|
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
})
}
-
Update
registerEventHandlersinbackend/library/library.go:- Remove the
LibraryConfigChangedevent 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()orScanAllLibraries()
- The
LibraryConfigChangedevent andhandleConfigUpdatemethod can be deleted or marked deprecated - Delete
handleConfigUpdatemethod - Delete
errLibraryDirNotConfiguredsentinel error (no longer needed)
- Remove the
-
Update
NewYellowJacketAppinbackend/app.go:- Change the
library.NewLibrary(...)call. The Config parameter is less important now since DirectoryPath is ignored. PassyjApp.appConfig.Libraryas before (it still has ScanConcurrency which is useful as a default).
- Change the
-
Add auto-scan on startup in
backend/app.go:- In
OnDomReady(or via a goroutine started inOnStartupthat 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).
- In
-
Clean up legacy
Scan()method:- In Plan 01, the old
Scan()was kept as backward-compatible wrapper. Now review: since we're removinghandleConfigUpdatewhich was the only caller of the legacyScan()vial.handleConfigUpdate → l.Scan(), we can either:- Keep
Scan()for tests (it's used inscan_test.go) - Update it to call
scanInternalwith the library froml.conf.DirectoryPathif set, or return early if not set
- Keep
- 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 usingl.conf.DirectoryPath.
- In Plan 01, the old
-
Update
FullRescan()inbackend/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 uselibs[0]. - If no libraries exist, return an error.
- Call
scanInternal(lib.ID, lib.Name, lib.Path)instead ofl.Scan(). - Per-library FullRescan will be added in Phase 12 — for now this rescans the first/only library.
- Instead of using
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
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>