Skip to content

fix: prevent cleanup command from deleting legacy IP log entries - #98

Merged
konradmichalik merged 2 commits into
mainfrom
fix/iplog-cleanup-legacy-entries
Jul 8, 2026
Merged

fix: prevent cleanup command from deleting legacy IP log entries#98
konradmichalik merged 2 commits into
mainfrom
fix/iplog-cleanup-legacy-entries

Conversation

@konradmichalik

@konradmichalik konradmichalik commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes already-reported IPs being reported as "new" again after running typo3loginwarning:iplog:cleanup: entries created by extension versions ≀ 1.0.3 were inserted without a last-seen timestamp (tstamp = 0, the column default), so the first cleanup run deleted them all regardless of the configured retention period.
  • The cleanup command now backfills such legacy entries with the current time instead of deleting them, granting a full retention period before they become cleanup candidates. The run output reports how many entries were initialized.
  • --dry-run reports both the would-be-initialized and would-be-deleted counts without modifying anything.
  • As defense in depth, the count/delete repository queries now exclude tstamp = 0 rows entirely.

Changes

  • Classes/Domain/Repository/IpLogRepository.php - New initializeMissingTimestamps() and countEntriesWithMissingTimestamp() methods; tstamp > 0 guard in countEntriesLastSeenBefore() and deleteEntriesLastSeenBefore()
  • Classes/Command/CleanupIpLogCommand.php - Initialize legacy entries before deleting; extended dry-run and run output
  • Tests/Unit/Domain/Repository/IpLogRepositoryTest.php - Tests for the new methods and the tstamp > 0 guard
  • Tests/Unit/Command/CleanupIpLogCommandTest.php - Tests for initialization, dry-run reporting, and suppressed output when no legacy entries exist
  • README.md - Document cleanup behavior for legacy entries

Summary by CodeRabbit

  • New Features

    • Cleanup now preserves legacy IP log entries without a timestamp by initializing them first, giving them a full retention period before deletion.
    • Dry-run output now reports how many legacy entries would be initialized, along with how many entries would be deleted.
  • Bug Fixes

    • Entries with missing timestamps are no longer counted as eligible for immediate cleanup.
    • Cleanup messaging now reflects legacy-entry handling more accurately.
  • Documentation

    • Updated the IP log cleanup notes to describe the new legacy-entry behavior.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

πŸ“ Walkthrough

Walkthrough

This PR adds legacy-entry handling to IP log cleanup: entries with tstamp = 0 (from pre-1.0.3 versions) are now initialized to the current time rather than deleted immediately. IpLogRepository gains countEntriesWithMissingTimestamp() and initializeMissingTimestamps(), and excludes tstamp = 0 from before-threshold counts. CleanupIpLogCommand invokes initialization and reports counts in both dry-run and execute modes. Documentation and unit tests are updated accordingly.

Changes

Legacy IP log timestamp initialization

Layer / File(s) Summary
Repository support for legacy timestamp detection and initialization
Classes/Domain/Repository/IpLogRepository.php
Adds countEntriesWithMissingTimestamp() and initializeMissingTimestamps(), updates docblock, and excludes tstamp = 0 rows from countEntriesLastSeenBefore().
Cleanup command uses legacy initialization before deletion
Classes/Command/CleanupIpLogCommand.php
Command calls initialization/counting methods and prints legacy-entry messaging in both dry-run and execute modes before deletion.
Repository and command test coverage
Tests/Unit/Domain/Repository/IpLogRepositoryTest.php, Tests/Unit/Command/CleanupIpLogCommandTest.php
Reworks existing tests for callback-based named parameters excluding legacy rows, and adds new tests for counting, initializing, and reporting legacy entries in dry-run/execute paths.
Documentation update
README.md
Documents that legacy entries without a last-seen timestamp are initialized rather than deleted on cleanup.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CleanupIpLogCommand
  participant IpLogRepository
  participant Database

  CleanupIpLogCommand->>IpLogRepository: countEntriesWithMissingTimestamp()
  IpLogRepository->>Database: SELECT count WHERE tstamp = 0
  Database-->>IpLogRepository: legacy count
  IpLogRepository-->>CleanupIpLogCommand: legacy count

  alt dry-run
    CleanupIpLogCommand->>CleanupIpLogCommand: print "would initialize N"
    CleanupIpLogCommand->>IpLogRepository: countEntriesLastSeenBefore(threshold)
    IpLogRepository-->>CleanupIpLogCommand: delete count
    CleanupIpLogCommand->>CleanupIpLogCommand: print "would delete N"
  else execute
    CleanupIpLogCommand->>IpLogRepository: initializeMissingTimestamps()
    IpLogRepository->>Database: UPDATE tstamp = time() WHERE tstamp = 0
    Database-->>IpLogRepository: updated count
    IpLogRepository-->>CleanupIpLogCommand: updated count
    CleanupIpLogCommand->>CleanupIpLogCommand: print "Initialized N"
    CleanupIpLogCommand->>IpLogRepository: deleteEntriesLastSeenBefore(threshold)
  end
Loading

Possibly related PRs

  • move-elevator/typo3-login-warning#95: Introduces the base typo3loginwarning:iplog:cleanup command and IpLogRepository cleanup/count logic that this PR directly extends with legacy timestamp handling.
πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly summarizes the main change: preventing cleanup from deleting legacy IP log entries.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check βœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check βœ… Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/iplog-cleanup-legacy-entries

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
Tests/Unit/Command/CleanupIpLogCommandTest.php (1)

113-126: πŸ“ Maintainability & Code Quality | πŸ”΅ Trivial | ⚑ Quick win

Consider using expects(self::once()) instead of method() for methods that must be called.

Both testDoesNotReportInitializationWhenNoLegacyEntriesExist and testDryRunDoesNotReportInitializationWhenNoLegacyEntriesExist use method() to stub repository calls, which allows zero or more invocations. Since the command should always call these methods (in execute mode: initializeMissingTimestamps and deleteEntriesLastSeenBefore; in dry-run mode: countEntriesWithMissingTimestamp and countEntriesLastSeenBefore), using expects(self::once()) would catch regressions where the command accidentally skips these calls.

♻️ Proposed refactor for stricter expectations
 public function testDoesNotReportInitializationWhenNoLegacyEntriesExist(): void
 {
     $this->ipLogRepository
-            ->method('initializeMissingTimestamps')
+            ->expects(self::once())
+            ->method('initializeMissingTimestamps')
             ->willReturn(0);
 
     $this->ipLogRepository
-            ->method('deleteEntriesLastSeenBefore')
+            ->expects(self::once())
+            ->method('deleteEntriesLastSeenBefore')
             ->willReturn(5);
 public function testDryRunDoesNotReportInitializationWhenNoLegacyEntriesExist(): void
 {
     $this->ipLogRepository
-            ->method('countEntriesWithMissingTimestamp')
+            ->expects(self::once())
+            ->method('countEntriesWithMissingTimestamp')
             ->willReturn(0);
 
     $this->ipLogRepository
-            ->method('countEntriesLastSeenBefore')
+            ->expects(self::once())
+            ->method('countEntriesLastSeenBefore')
             ->willReturn(7);

Also applies to: 156-169

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/Unit/Command/CleanupIpLogCommandTest.php` around lines 113 - 126, The
repository stubs in CleanupIpLogCommandTest are too permissive for calls that
must always happen. Update the relevant test methods, including
testDoesNotReportInitializationWhenNoLegacyEntriesExist and
testDryRunDoesNotReportInitializationWhenNoLegacyEntriesExist, to use
expects(self::once()) on the IpLogRepository methods invoked by
CleanupIpLogCommand so the test fails if the command skips
initializeMissingTimestamps, deleteEntriesLastSeenBefore,
countEntriesWithMissingTimestamp, or countEntriesLastSeenBefore.
πŸ€– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Classes/Command/CleanupIpLogCommand.php`:
- Around line 62-71: The `CleanupIpLogCommand` dry-run messaging is outdated
because the command now reports both deletions and legacy timestamp
initializations. Update the `--dry-run` option description in
`CleanupIpLogCommand` so it accurately reflects the behavior shown in the
dry-run branch that calls `countEntriesWithMissingTimestamp()` and
`countEntriesLastSeenBefore()`.

---

Nitpick comments:
In `@Tests/Unit/Command/CleanupIpLogCommandTest.php`:
- Around line 113-126: The repository stubs in CleanupIpLogCommandTest are too
permissive for calls that must always happen. Update the relevant test methods,
including testDoesNotReportInitializationWhenNoLegacyEntriesExist and
testDryRunDoesNotReportInitializationWhenNoLegacyEntriesExist, to use
expects(self::once()) on the IpLogRepository methods invoked by
CleanupIpLogCommand so the test fails if the command skips
initializeMissingTimestamps, deleteEntriesLastSeenBefore,
countEntriesWithMissingTimestamp, or countEntriesLastSeenBefore.
πŸͺ„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 985f3c09-13c7-4dcf-9dc8-78383e0ec340

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 016c1e3 and 46a7484.

πŸ“’ Files selected for processing (5)
  • Classes/Command/CleanupIpLogCommand.php
  • Classes/Domain/Repository/IpLogRepository.php
  • README.md
  • Tests/Unit/Command/CleanupIpLogCommandTest.php
  • Tests/Unit/Domain/Repository/IpLogRepositoryTest.php

Comment on lines +62 to 71
$missing = $this->ipLogRepository->countEntriesWithMissingTimestamp();
if ($missing > 0) {
$io->writeln(sprintf('%d legacy IP log entries without a last-seen timestamp would be initialized.', $missing));
}

$count = $this->ipLogRepository->countEntriesLastSeenBefore($threshold);
$io->writeln(sprintf('%d IP log entries would be deleted (not seen for more than %d days).', $count, $days));

return Command::SUCCESS;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

Update the --dry-run option description to reflect new initialization reporting.

The option description at Line 45 still reads "Only report how many entries would be deleted", but the dry-run branch now also reports how many legacy entries would be initialized. This user-facing string should be updated for accuracy.

πŸ“ Suggested fix
- ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Only report how many entries would be deleted');
+ ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Only report what would be changed without making modifications');
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Classes/Command/CleanupIpLogCommand.php` around lines 62 - 71, The
`CleanupIpLogCommand` dry-run messaging is outdated because the command now
reports both deletions and legacy timestamp initializations. Update the
`--dry-run` option description in `CleanupIpLogCommand` so it accurately
reflects the behavior shown in the dry-run branch that calls
`countEntriesWithMissingTimestamp()` and `countEntriesLastSeenBefore()`.

@konradmichalik
konradmichalik merged commit 4cf7651 into main Jul 8, 2026
30 checks passed
@konradmichalik
konradmichalik deleted the fix/iplog-cleanup-legacy-entries branch July 31, 2026 08:09
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.

1 participant