# Legacy Sync System — Removal Manifest

**DO NOT execute these deletions until v2 has run successfully in production for 7 days
and `sync_runs` table holds zero `status='running'` rows.**

The v2 pipeline (`SyncDashboardController` + `Bus::batch` + `ProcessXJob`) fully replaces
every capability the legacy `RunMondaySyncJob` had. This manifest documents the safe order
in which to remove the legacy footprint.

---

## Pre-flight verification (run BEFORE any deletion)

```bash
# 1. Confirm v2 has handled the last 3+ syncs successfully
php artisan tinker --execute="
\App\Models\SyncState::orderByDesc('id')->limit(5)->get(['id','type','status','finished_at'])->dump();
"

# 2. Confirm no legacy SyncRun is mid-flight (or pending)
php artisan tinker --execute="
echo 'legacy SyncRuns active: ' .
    \App\Models\SyncRun::whereIn('status', ['pending','running'])->count() . PHP_EOL;
"

# 3. Confirm no queue worker is watching the legacy `default` queue
ps aux | grep 'queue:work.*default'   # should be empty (or 0 results)

# 4. Confirm no sidebar / route / scheduler still uses legacy
grep -RnE "RunMondaySyncJob|StartupsSyncService|InvestorsSyncService|admin\.sync\.runs\.|admin\.sync\.startups|admin\.sync\.investors|admin\.sync\.active|admin\.sync\.index" \
    app/ resources/ routes/ database/ config/ --include="*.php" --include="*.blade.php"
# should match only:
#   - app/Console/Commands/Monday/SyncStartupsCommand.php (DELETING in step 2)
#   - app/Console/Commands/Monday/SyncInvestorsCommand.php (DELETING in step 2)
#   - app/Http/Controllers/Admin/SyncController.php (DELETING in step 1)
#   - app/Jobs/RunMondaySyncJob.php (DELETING in step 1)
#   - app/Services/Monday/StartupsSyncService.php (DELETING in step 2)
#   - app/Services/Monday/InvestorsSyncService.php (DELETING in step 2)
#   - app/Models/SyncRun.php (DELETING in step 3)
#   - resources/views/admin/sync/index.blade.php (DELETING in step 1)
#   - resources/views/admin/sync/show.blade.php (DELETING in step 1)
#   - routes/web.php (EDITING in step 4)
#   - app/Jobs/Sync/ProcessCompanyJob.php (KEEP — comment-only reference)
#   - app/Services/Monday/MondayAssetDownloader.php (KEEP — comment-only reference)
```

---

## Step 1 — Remove the legacy controller + views (low risk)

Removes the orchestration UI. Routes already redirect to v2.

```bash
git rm app/Http/Controllers/Admin/SyncController.php
git rm resources/views/admin/sync/index.blade.php
git rm resources/views/admin/sync/show.blade.php

# Verify nothing references them anymore (must produce zero output):
grep -Rn "SyncController\|admin/sync/show\|admin/sync/index" \
    app/ resources/ routes/ --include="*.php" --include="*.blade.php"
```

If the grep is clean, commit:
```
git commit -m "remove legacy SyncController + views (replaced by /sync/v2)"
```

Then in `routes/web.php`, the redirect names (`sync.index`, etc.) will still
work because they no longer reference the deleted controller.

---

## Step 2 — Remove the legacy services + commands (medium risk)

These are the orchestrators the legacy job uses. The v2 jobs use mappers + repos directly.

```bash
git rm app/Services/Monday/StartupsSyncService.php
git rm app/Services/Monday/InvestorsSyncService.php
git rm app/Console/Commands/Monday/SyncStartupsCommand.php
git rm app/Console/Commands/Monday/SyncInvestorsCommand.php
```

Comment-only references (in `ProcessCompanyJob.php` line 15 and
`MondayAssetDownloader.php` line 214) are documentation; clean them up
in the same commit:

```php
// In app/Jobs/Sync/ProcessCompanyJob.php — remove this line from the docblock:
//   * Mirrors the existing `StartupsSyncService::syncSingleItem()` logic but

// In app/Services/Monday/MondayAssetDownloader.php — remove "and any older callers"
//   from the docblock for `ingestForStartup()`.
```

Verify:
```bash
grep -RlE "StartupsSyncService|InvestorsSyncService" app/
# expected: zero matches
```

Commit:
```
git commit -m "remove legacy StartupsSyncService + InvestorsSyncService + console commands"
```

---

## Step 3 — Remove the legacy job + model (medium risk)

The job hasn't been dispatched anywhere since the v2 cutover — verify with the failed-jobs grep below before pulling the trigger.

```bash
# First check failed_jobs for any RunMondaySyncJob still showing up
php artisan tinker --execute="
echo 'failed RunMondaySyncJob in last 30d: ' . \DB::table('failed_jobs')
    ->where('failed_at', '>=', now()->subDays(30))
    ->where('payload', 'like', '%RunMondaySyncJob%')
    ->count() . PHP_EOL;
"
# Expected: 0
```

```bash
git rm app/Jobs/RunMondaySyncJob.php
git rm app/Models/SyncRun.php

git commit -m "remove legacy RunMondaySyncJob + SyncRun model"
```

---

## Step 4 — Drop legacy redirects + DB tables (final, irreversible)

After 30 days of no incoming requests to the redirect routes, drop them and
the underlying `sync_runs` table.

### 4a. Routes

In `routes/web.php`, delete the entire "Legacy sync routes (DEPRECATED, kept
only as redirects)" block:

```php
Route::redirect('sync',            '/sync/v2', 301)->name('sync.index');
Route::redirect('sync/active',     '/sync/v2', 301)->name('sync.active');
Route::redirect('sync/runs/{run}', '/sync/v2', 301)->name('sync.runs.show');
```

### 4b. Drop the table via a new migration

```bash
php artisan make:migration drop_sync_runs_table
```

Then in the new migration:
```php
public function up(): void {
    \Schema::dropIfExists('sync_runs');
}
public function down(): void {
    // Intentionally non-reversible. Restore from a backup if you need
    // the schema again.
}
```

```bash
php artisan migrate
git commit -m "remove legacy sync_runs table + redirect routes"
```

---

## Files preserved on purpose

| File | Why kept |
|---|---|
| `database/migrations/2026_05_06_000015_create_sync_runs_table.php` | Migration history is immutable. The drop migration in step 4b makes the table go away; deleting the create migration would break `migrate:rollback`. |
| `database/migrations/2026_05_06_000016_extend_sync_runs_for_streaming.php` | Same reason. |
| `app/Jobs/Sync/ProcessCompanyJob.php` | v2 — keep. Only the docblock string needs trimming. |
| `app/Services/Monday/MondayAssetDownloader.php` | v2 — keep. Only the docblock string needs trimming. |

---

## Rollback plan

If after step 1 or 2 something breaks:

```bash
git revert HEAD                      # restores the deleted files
php artisan route:clear              # repopulates legacy route cache
```

Step 3 onward is safe to revert as long as no DB migration has run — the
moment step 4b's migration runs, `sync_runs` data is gone (no rollback).
Take a DB backup before step 4b.
