Skip to content

#3: Clean and Reset Commands #3

@AliiiBenn

Description

@AliiiBenn

Issue #3: Clean and Reset Commands

Problem

Users currently have no safe way to:

  • Clean database: Remove all data but keep structure (for re-importing)
  • Reset project: Start fresh with a clean slate
  • Selective cleanup: Remove specific tables or data ranges

Current workarounds are:

  • Manually deleting warehouse.db file (risky, no confirmation)
  • Running SQL DELETE commands manually (error-prone)
  • Deleting entire project folder and re-running init (drastic)

This leads to:

  • Accidental data loss
  • No safety mechanisms or confirmations
  • No way to undo destructive operations
  • Inconsistent project state

Proposed Solution

Implement two safety-focused commands:

  1. wareflow clean - Clean database data (with options)
  2. wareflow reset - Reset entire project (with safeguards)

Part 1: Clean Command

Command Signature

wareflow clean [--db] [--table TABLE] [--dry-run] [--force] [--backup]

Options

Option Description Default
--db Clean all tables (keep schema) False
--table TABLE Clean specific table only None
--dry-run Show what would be deleted without doing it False
--force Skip confirmation prompt False
--backup Create backup before cleaning True

Usage Examples

Clean all tables (with confirmation):

$ wareflow clean --db

⚠️  WARNING: This will delete all data from the database

Database: warehouse.db (12.4 MB)
Tables to clean:
  produits:    1,234 rows
  mouvements:  45,678 rows
  commandes:     789 rows
Total: 47,701 rows

Backup will be created: warehouse.db.backup_20250121_143015

Type 'yes' to confirm: yes

✓ Creating backup: warehouse.db.backup_20250121_143015
✓ Cleaning table: produits (1,234 rows deleted)
✓ Cleaning table: mouvements (45,678 rows deleted)
✓ Cleaning table: commandes (789 rows deleted)
✓ Vacuuming database...

✅ Database cleaned successfully
   Schema preserved, all data removed
   Database size: 192 KB (empty)

💡 Next step:
   Run 'wareflow import' to import fresh data

Clean specific table:

$ wareflow clean --table mouvements

⚠️  This will delete all data from 'mouvements' table

Table: mouvements (45,678 rows)
Backup will be created: warehouse.db.backup_20250121_143100

Type 'yes' to confirm: yes

✓ Creating backup: warehouse.db.backup_20250121_143100
✓ Cleaning table: mouvements (45,678 rows deleted)
✓ Vacuuming database...

✅ Table cleaned successfully
   Other tables preserved: produits (1,234 rows), commandes (789 rows)

Dry-run mode (preview):

$ wareflow clean --db --dry-run

🔍 Dry-run mode: No changes will be made

Database: warehouse.db (12.4 MB)

Would clean:
  produits:    1,234 rows
  mouvements:  45,678 rows
  commandes:     789 rows
Total: 47,701 rows

Would create backup: warehouse.db.backup_20250121_143200
Resulting database size: ~192 KB

💡 Remove --dry-run to proceed

Force mode (skip confirmation):

$ wareflow clean --db --force

✓ Creating backup: warehouse.db.backup_20250121_143300
✓ Cleaning table: produits (1,234 rows deleted)
✓ Cleaning table: mouvements (45,678 rows deleted)
✓ Cleaning table: commandes (789 rows deleted)
✓ Vacuuming database...

✅ Database cleaned successfully

No backup (risky):

$ wareflow clean --db --no-backup --force

⚠️  WARNING: No backup will be created!

This operation cannot be undone.

Type 'I_UNDERstand_the_risks' to confirm: I_UNDERstand_the_risks

✓ Cleaning table: produits (1,234 rows deleted)
✓ Cleaning table: mouvements (45,678 rows deleted)
✓ Cleaning table: commandes (789 rows deleted)
✓ Vacuuming database...

✅ Database cleaned successfully
   No backup created

Error Cases

Database not found:

❌ Database not found

  File: warehouse.db does not exist

💡 Solution:
  Run 'wareflow import' to create the database
  Or run 'wareflow init <name>' to create a new project

Table doesn't exist:

❌ Table not found

  Table: unknown_table does not exist

Available tables:
  produits
  mouvements
  commandes

💡 Use --table with a valid table name

Part 2: Reset Command

Command Signature

wareflow reset [--hard] [--dry-run] [--force]

Options

Option Description Default
--hard Delete entire project directory False
--dry-run Show what would be deleted False
--force Skip confirmation prompts False

Usage Examples

Soft reset (clean database only):

$ wareflow reset

⚠️  WARNING: This will reset the project database

Project: my-warehouse/
Location: /path/to/my-warehouse

Will be deleted:
  warehouse.db (12.4 MB)
  warehouse.db.backup_* (3 backup files, 45.2 MB)
  output/ (reports and exports, 8.7 MB)

Will be preserved:
  config.yaml (configuration)
  schema.sql (database schema)
  data/ (Excel source files)

Backup will be created: .backup_reset_20250121_143500

Type 'yes' to confirm: yes

✓ Creating project backup: .backup_reset_20250121_143500
✓ Deleting database: warehouse.db
✓ Deleting backup files: 3 files
✓ Cleaning output directory: output/

✅ Project reset successfully
   Configuration and source files preserved

💡 Next steps:
   - Run 'wareflow import' to re-import data
   - Or restore backup: cp -r .backup_reset_*/* .

Hard reset (delete everything):

$ wareflow reset --hard

🚨 CRITICAL WARNING: This will delete the entire project!

Project: my-warehouse/
Location: /path/to/my-warehouse

Will be COMPLETELY DELETED:
  All files and folders
  No recovery possible after deletion

⚠️  You will need to run 'wareflow init' to create a new project

This action cannot be undone!

Type 'DELETE_ALL_MY_DATA' to confirm: DELETE_ALL_MY_DATA

✓ Deleting project directory: my-warehouse/

✅ Project deleted
   To start fresh, run: wareflow init my-warehouse

Dry-run mode:

$ wareflow reset --dry-run

🔍 Dry-run mode: No changes will be made

Project: my-warehouse/
Location: /path/to/my-warehouse

Would delete (soft reset):
  warehouse.db (12.4 MB)
  warehouse.db.backup_* (3 files, 45.2 MB)
  output/ (8.7 MB)
Total: 66.3 MB

Would preserve:
  config.yaml
  schema.sql
  data/*.xlsx

Would create backup: .backup_reset_20250121_143600

💡 Remove --dry-run to proceed

Force mode (automation/scripting):

$ wareflow reset --force

✓ Creating project backup: .backup_reset_20250121_143700
✓ Deleting database: warehouse.db
✓ Deleting backup files: 3 files
✓ Cleaning output directory: output/

✅ Project reset successfully (no confirmation)

Error Cases

Not in a wareflow project:

❌ Not a wareflow project

  Current directory: /path/to/dir
  Missing: config.yaml

💡 Solution:
  Navigate to a wareflow project directory
  Or run 'wareflow init <name>' to create a new project

Project already empty:

ℹ️  Project is already reset

  No database to delete
  No backup files to delete
  Output directory is empty

Nothing to do.

Implementation Requirements

File Structure

src/wareflow_analysis/
├── cli.py                      # Add clean and reset commands
└── commands/
    └── cleanup/                # New module
        ├── __init__.py
        ├── clean.py            # Database cleaning logic
        ├── reset.py            # Project reset logic
        ├── backup.py           # Backup creation
        ├── confirmation.py     # User confirmation prompts
        └── reporters.py        # Progress and result display

Key Components

1. Database Cleaner

class DatabaseCleaner:
    def __init__(self, db_path: Path, backup: bool = True):
        self.db_path = db_path
        self.backup = backup

    def clean_all_tables(self, force: bool = False) -> CleanResult
    def clean_table(self, table_name: str) -> CleanResult
    def create_backup(self) -> Path
    def vacuum_database(self) -> None
    def get_table_row_counts(self) -> Dict[str, int]

2. Project Resetter

class ProjectResetter:
    def __init__(self, project_path: Path):
        self.project_path = project_path
        self.config = self._load_config()

    def soft_reset(self) -> ResetResult
    def hard_reset(self) -> ResetResult
    def create_backup(self) -> Path
    def delete_database_files(self) -> List[Path]
    def clean_output_directory(self) -> None
    def verify_is_project(self) -> bool

3. Backup Manager

class BackupManager:
    def create_backup(self, source: Path, backup_type: str) -> Path
    def backup_database(self, db_path: Path) -> Path
    def backup_project(self, project_path: Path) -> Path
    def list_backups(self, project_path: Path) -> List[Path]
    def restore_backup(self, backup_path: Path, target: Path) -> bool

4. Confirmation Handler

class ConfirmationHandler:
    def prompt_yes_no(self, message: str, default: bool = False) -> bool
    def prompt_dangerous(self, message: str, confirmation_text: str) -> bool
    def prompt_dry_run_continuation(self) -> bool

Backup Strategy

Database backups:

warehouse.db.backup_YYYYMMDD_HHMMSS
Example: warehouse.db.backup_20250121_143015

Project backups:

.backup_reset_YYYYMMDD_HHMMSS/
├── warehouse.db
├── warehouse.db.backup_*
├── output/
└── .backup_info.txt

Backup info file:

Backup created: 2025-01-21 14:30:15
Backup type: reset
Project: my-warehouse
Files backed up:
  - warehouse.db (12.4 MB)
  - warehouse.db.backup_* (3 files)
  - output/ (8.7 MB)

Safety Mechanisms

  1. Default to backup creation (opt-out with --no-backup)
  2. Confirmation prompts (opt-out with --force)
  3. Dry-run mode for preview
  4. Special confirmation text for dangerous operations
  5. Backup before deletion
  6. Verification files are deletable before operation
  7. Rollback capability from backups

Acceptance Criteria

Clean Command

  • wareflow clean --db cleans all tables
  • Preserves database schema (doesn't DROP tables)
  • --table TABLE cleans only specified table
  • Creates backup by default
  • --dry-run shows what would be deleted
  • --force skips confirmation
  • --no-backup requires special confirmation
  • VACUUM database after cleaning
  • Shows before/after statistics
  • Handles missing database gracefully
  • Handles invalid table name with error
  • List of available tables on error
  • Works on Windows, macOS, Linux

Reset Command

  • wareflow reset performs soft reset
  • Deletes database and backups
  • Cleans output directory
  • Preserves config.yaml and schema.sql
  • Preserves data/ directory
  • --hard deletes entire project
  • --hard requires extra confirmation
  • Creates project backup by default
  • --dry-run shows what would be deleted
  • --force skips confirmation
  • Verifies is a valid project
  • Error if not in project directory
  • Handles already-reset state gracefully

Safety

  • Confirmation prompts for all destructive operations
  • Special confirmation for --no-backup
  • Special confirmation for --hard reset
  • Dry-run mode for both commands
  • Backup creation before deletion
  • Clear warnings about data loss
  • Lists exactly what will be deleted

Output

  • Clear before/after statistics
  • File sizes shown
  • Color-coded warnings (⚠️) and errors (❌)
  • Progress indicators for long operations
  • Next steps suggestions
  • Exit code 0 on success, 1 on error

Technical Notes

Database Cleaning Process

-- Instead of DROP TABLE, use DELETE
DELETE FROM produits;
DELETE FROM mouvements;
DELETE FROM commandes;

-- Then VACUUM to reclaim space
VACUUM;

-- Reset sequences
DELETE FROM sqlite_sequence;

File Deletion Strategy

# Use safe deletion
def safe_delete(path: Path) -> bool:
    if not path.exists():
        return False
    if path.is_file():
        path.unlink()
    elif path.is_dir():
        shutil.rmtree(path)
    return True

Backup Strategy

# Create timestamped backup
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_name = f"{name}.backup_{timestamp}"

# Copy with progress
shutil.copy2(src, dst)

Confirmation Prompts

# Standard confirmation
response = input("Type 'yes' to confirm: ").strip().lower()
return response == 'yes'

# Dangerous operation confirmation
expected = "DELETE_ALL_MY_DATA"
response = input(f"Type '{expected}' to confirm: ").strip()
return response == expected

Dependencies

  • sqlite3 - Database operations
  • shutil - File operations
  • Existing project structure detection

Out of Scope

  • Selective row deletion (by date, ID range, etc.)
  • Data migration between projects
  • Cloud backup integration
  • Scheduled cleanup

Testing Requirements

# tests/test_clean.py
def test_clean_all_tables()
def test_clean_single_table()
def test_clean_creates_backup()
def test_clean_dry_run()
def test_clean_force_skip_confirmation()
def test_clean_no_backup_special_confirmation()
def test_clean_database_not_found()
def test_clean_table_not_found()
def test_clean_vacuum_database()
def test_clean_preserves_schema()

# tests/test_reset.py
def test_soft_reset()
def test_soft_reset_preserves_config()
def test_soft_reset_preserves_data()
def test_hard_reset()
def test_hard_reset_deletes_project()
def test_reset_creates_backup()
def test_reset_dry_run()
def test_reset_force_skip_confirmation()
def test_reset_not_in_project()
def test_reset_already_empty()
def test_reset_hard_special_confirmation()

Priority

Priority: HIGH - Essential for testing, debugging, and project management

Estimated Effort: 4-6 hours

Complexity: MEDIUM - Requires careful safety mechanisms and file operations

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions