82d9a3324e
There was no documented way to repair a poisoned box. Two invented facts written during QA disabled world answering for every later turn (V-470), and revert voids the SQL row while leaving the vector behind (V-493). This is the operation that undoes both. Store.Wipe drops every table sqlite_master reports and rebuilds from schema.sql plus the migrations, rather than deleting from a hand-written list. A list has to be edited whenever a table is added, and the once it is not, the wipe leaves personal data behind while reporting success. It vacuums afterwards, because free pages still hold readable text. mavend -wipe prints every table and its row count and exits. That alone is a dry run and answers what a QA session actually asks: what is on this box. It deletes only with -confirm-wipe. Two flags, because the destructive reading of one flag is the reading a mistyped command gets. Nothing outside the database moves. Config, models, passkeys.json and the encryption key are files. QA isolation and onboarding are the other two thirds of V-494 and are not here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SoL7EBdYC5Mhz3DJd49GJy
46 lines
1.5 KiB
Go
46 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/kami/maven/internal/store"
|
|
)
|
|
|
|
// runWipe implements the -wipe flag: it prints what the database holds, and
|
|
// removes it only when the operator also passed -confirm-wipe (Vikunja #494).
|
|
//
|
|
// Two flags rather than one, because the destructive reading of a single flag
|
|
// is the reading a mistyped command gets. Without the confirmation this is a
|
|
// dry run that costs nothing and answers the question a QA session actually
|
|
// has — what is on this box right now.
|
|
//
|
|
// It runs before any daemon component is wired, so nothing is writing while
|
|
// the tables go. The daemon exits afterwards rather than serving a store it
|
|
// just emptied, because every component that read the old rows at boot would
|
|
// still be holding them.
|
|
func runWipe(ctx context.Context, st *store.Store, out io.Writer, confirmed bool) error {
|
|
counts, err := st.WipeCounts(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("wipe: read counts: %w", err)
|
|
}
|
|
total := 0
|
|
for _, c := range counts {
|
|
total += c.Rows
|
|
fmt.Fprintf(out, " %-24s %d\n", c.Table, c.Rows)
|
|
}
|
|
fmt.Fprintf(out, " %-24s %d rows in %d tables\n", "TOTAL", total, len(counts))
|
|
|
|
if !confirmed {
|
|
fmt.Fprintln(out, "\nnothing was deleted. pass -confirm-wipe to delete all of it.")
|
|
fmt.Fprintln(out, "config, models, passkeys and the encryption key are files and are never touched.")
|
|
return nil
|
|
}
|
|
if err := st.Wipe(ctx); err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintf(out, "\nwiped. %d rows gone, the schema is intact, mavend knows nobody.\n", total)
|
|
return nil
|
|
}
|