Ctrl K
ComunidadGuías…

docs/SYNC_HISTORY.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Sync History

## Overview

The sync history feature tracks all sync operations in a SQLite database, providing a queryable historical record for analysis, troubleshooting, and monitoring.

## Features

- **Persistent Storage**: All sync attempts stored in SQLite database
- **Rich Metadata**: Duration, account counts, error messages, correlation IDs
- **Query Interface**: Filter by server, date range, status
- **Statistics**: Success rates, averages, per-server metrics
- **Automatic Cleanup**: Configurable retention period
- **CLI Tool**: View history from command line

## Configuration

Configure sync history in `config/config.json`:

```json
{
  "syncHistory": {
    "dbPath": "data/sync-history.db",
    "retentionDays": 90
  }
}
```

### Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `dbPath` | string | `"data/sync-history.db"` | Path to SQLite database file |
| `retentionDays` | integer | `90` | Number of days to retain history (1-365) |

## Data Model

Each sync operation is recorded with:

| Field | Type | Description |
|-------|------|-------------|
| `id` | INTEGER | Auto-increment primary key |
| `timestamp` | TEXT | ISO 8601 timestamp |
| `server_name` | TEXT | Server name from config |
| `status` | TEXT | 'success' or 'failure' |
| `duration_ms` | INTEGER | Sync duration in milliseconds |
| `accounts_processed` | INTEGER | Total accounts processed |
| `accounts_succeeded` | INTEGER | Accounts synced successfully |
| `accounts_failed` | INTEGER | Accounts that failed |
| `accounts_skipped` | INTEGER | Accounts skipped (manual / closed) — see account syncability |
| `transactions_added` | INTEGER | Transactions the bank sync imported, summed over the run (#391) |
| `transactions_updated` | INTEGER | Existing transactions the bank sync matched and updated (#391) |
| `error_message` | TEXT | Error message if failed |
| `error_code` | TEXT | Error code if failed |
| `correlation_id` | TEXT | UUID for tracking |

### Per-account results (`sync_history_account`)

Each sync also writes one row per processed account, in the same transaction as
its `sync_history` row (#429):

| Field | Type | Description |
|-------|------|-------------|
| `sync_id` | INTEGER | `sync_history.id` of the sync |
| `account_id` | TEXT | Actual account id |
| `account_name` | TEXT | Account name (already stored in `account_metadata`) |
| `status` | TEXT | `synced`, `failed` or `skipped` |
| `transactions_added` | INTEGER | New transactions; `NULL` = unknown (late success), never `0` |
| `transactions_updated` | INTEGER | Updated transactions; `NULL` = unknown |

Only counts are stored: no payees, amounts, notes or per-account error text
(errors stay in `sync_history.error_message`). Rows are removed with their sync
by retention cleanup and by the history resets. The table is created with
`CREATE TABLE IF NOT EXISTS`, so existing databases gain it on startup with no
data loss; syncs recorded earlier simply have no account rows.

Read access: `getHistory({ includeAccounts: true })` attaches `accounts` to each
row, `getLastAccountResults(serverName)` returns the last sync's rows,
`GET /api/dashboard/history?includeAccounts=1` returns the `accounts` arrays
(without the flag the response is unchanged), and `/api/dashboard/status`
carries `lastAccountResults` per server.

> **Schema migrations:** New columns are added additively at startup. A database
> created by an older version is migrated in place via a guarded `ALTER TABLE`
> (checked against `PRAGMA table_info`), so the migration is idempotent and
> preserves existing rows — older rows read `NULL` for columns added later
> (e.g. `accounts_skipped`).

## Viewing History

### Command Line Interface

Use the `viewHistory.js` script to query sync history:

```bash
# Show recent history (default: last 20 records)
npm run history

# Filter by server
npm run history -- --server Main

# Show last 7 days
npm run history -- --days 7

# Show only failures
npm run history -- --status failure

# Limit results
npm run history -- --limit 50

# Show statistics
npm run history -- --stats

# Per-server statistics
npm run history -- --per-server

# Recent errors
npm run history -- --errors

# Combine filters
npm run history -- --server Main --days 30 --status failure
```

### Output Examples

**History View:**
```
Sync History (10 records):

────────────────────────────────────────────────────────────────────────────────
Timestamp                Server              Status      Duration    Accounts            Error
────────────────────────────────────────────────────────────────────────────────
12/5/2025, 10:30:00 AM   Main                ✓ success   4.5s        3/3                 
12/5/2025, 7:30:00 AM    Main                ✓ success   4.2s        3/3                 
12/5/2025, 4:30:00 AM    Main                ✗ failure   2.1s        0/3                 Connection timeout
12/4/2025, 10:30:00 PM   Secondary           ✓ success   5.1s        2/2                 
────────────────────────────────────────────────────────────────────────────────
```

**Statistics View:**
```
Sync Statistics:

────────────────────────────────────────────────────────
Total Syncs:         50
Successful Syncs:    47
Failed Syncs:        3
Success Rate:        94.00%

Average Duration:    4.3s
Min Duration:        2.1s
Max Duration:        8.7s

Total Accounts:      150

Earliest Sync:       11/5/2025, 10:30:00 AM
Latest Sync:         12/5/2025, 10:30:00 AM
────────────────────────────────────────────────────────
```

**Per-Server Statistics:**
```
Per-Server Statistics:

──────────────────────────────────────────────────────────────────────────────────────────────
Server              Total     Success   Failed    Rate        Avg Duration    Last Sync
──────────────────────────────────────────────────────────────────────────────────────────────
Main                25        24        1         96.00%      4.2s            12/5/2025, 10:30:00 AM
Secondary           25        23        2         92.00%      4.5s            12/5/2025, 10:25:00 AM
──────────────────────────────────────────────────────────────────────────────────────────────
```

## Programmatic Access

Access sync history from your own scripts:

```javascript
const { SyncHistoryService } = require('./src/services/syncHistory');

const syncHistory = new SyncHistoryService({
  dbPath: 'data/sync-history.db',
  retentionDays: 90
});

// Get recent history
const history = syncHistory.getHistory({
  serverName: 'Main',
  days: 7,
  limit: 10
});

// Get statistics
const stats = syncHistory.getStatistics({ serverName: 'Main' });
console.log(`Success rate: ${stats.success_rate}`);

// Get recent errors
const errors = syncHistory.getRecentErrors(5);

// Get last sync for server
const lastSync = syncHistory.getLastSync('Main');

// Per-server statistics
const perServer = syncHistory.getStatisticsByServer(30);

// Close when done
syncHistory.close();
```

## Integration with Health Check

Sync history data can be integrated with the health check `/metrics` endpoint by extending the HealthCheckService:

```javascript
// In future enhancement
app.get('/metrics', (req, res) => {
  const stats = syncHistory.getStatistics({ days: 7 });
  res.json({
    // ... existing metrics
    history: {
      last7Days: stats,
      recentErrors: syncHistory.getRecentErrors(3)
    }
  });
});
```

## Use Cases

### 1. Troubleshooting

**Find when a server last synced successfully:**
```bash
npm run history -- --server Main --status success --limit 1
```

**View all failures in last 24 hours:**
```bash
npm run history -- --days 1 --status failure
```

**Check error messages:**
```bash
npm run history -- --errors
```

### 2. Performance Monitoring

**Check if sync times are increasing:**
```bash
npm run history -- --server Main --days 30
# Compare duration_ms over time
```

**View average performance:**
```bash
npm run history -- --stats --days 7
```

### 3. Reliability Tracking

**Calculate 30-day success rate:**
```bash
npm run history -- --stats --days 30
```

**Compare servers:**
```bash
npm run history -- --per-server --days 30
```

### 4. Audit Trail

**Generate compliance report:**
```bash
npm run history -- --days 90 > sync-report.txt
```

**Export to CSV** (add to scripts):
```javascript
const history = syncHistory.getHistory({ days: 90 });
const csv = history.map(r => 
  `${r.timestamp},${r.server_name},${r.status},${r.duration_ms}`
).join('\n');
```

## Database Maintenance

### Automatic Cleanup

Old records are automatically cleaned up based on `retentionDays` setting:
- Runs on service startup
- Deletes records older than retention period
- Runs `VACUUM` to reclaim space

### Manual Cleanup

```javascript
const syncHistory = new SyncHistoryService({ dbPath: 'data/sync-history.db' });
const deletedCount = syncHistory.cleanup();
console.log(`Deleted ${deletedCount} old records`);
syncHistory.close();
```

### Backup

SQLite database can be backed up while service is running:

```bash
# Copy database file
cp data/sync-history.db data/sync-history-backup-$(date +%Y%m%d).db

# Or use SQLite backup command
sqlite3 data/sync-history.db ".backup data/sync-history-backup.db"
```

### Reset History

```bash
# Stop service first
rm data/sync-history.db
# Restart service - database will be recreated
```

## Storage Considerations

### Database Size

Approximate storage per sync record: **~500 bytes**

| Records | Approximate Size |
|---------|------------------|
| 1,000 | ~500 KB |
| 10,000 | ~5 MB |
| 100,000 | ~50 MB |
| 1,000,000 | ~500 MB |

### Retention Recommendations

| Use Case | Recommended Retention |
|----------|----------------------|
| Basic monitoring | 30 days |
| Performance analysis | 90 days (default) |
| Compliance/audit | 365 days |
| Development/testing | 7 days |

## Performance

- **Write Performance**: ~1ms per insert (includes indexes)
- **Query Performance**: Sub-millisecond for typical queries
- **Indexes**: Timestamp, server name, status, correlation ID
- **WAL Mode**: Enabled for better concurrent access

## Troubleshooting

### Database Locked

```
Error: database is locked
```

**Cause**: Multiple processes accessing database simultaneously
**Solution**: Ensure only one sync service instance is running

### Disk Space

```
Error: disk I/O error
```

**Cause**: Disk full or permissions issue
**Solution**: 
- Check available disk space
- Verify write permissions on data directory
- Reduce `retentionDays` if needed

### Corrupted Database

```
Error: database disk image is malformed
```

**Solution**: Restore from backup or delete and recreate:
```bash
mv data/sync-history.db data/sync-history-corrupt.db
# Restart service to create new database
```

## Advanced Queries

Direct SQLite queries for advanced analysis:

```bash
sqlite3 data/sync-history.db
```

### Average sync time by hour:
```sql
SELECT 
  strftime('%H', timestamp) as hour,
  AVG(duration_ms) as avg_ms,
  COUNT(*) as count
FROM sync_history
GROUP BY hour
ORDER BY hour;
```

### Failure rate by server:
```sql
SELECT 
  server_name,
  ROUND(100.0 * SUM(CASE WHEN status='failure' THEN 1 ELSE 0 END) / COUNT(*), 2) as failure_rate
FROM sync_history
GROUP BY server_name;
```

### Slowest syncs:
```sql
SELECT 
  timestamp,
  server_name,
  duration_ms,
  accounts_processed
FROM sync_history
WHERE duration_ms IS NOT NULL
ORDER BY duration_ms DESC
LIMIT 10;
```

## Best Practices

1. **Regular Monitoring**: Check statistics weekly
2. **Investigate Patterns**: Look for failures at specific times
3. **Backup Database**: Include in regular backup routine
4. **Appropriate Retention**: Balance storage vs history needs
5. **Use Correlation IDs**: Track operations across logs and history
6. **Export Reports**: Generate monthly summaries for review

## Future Enhancements

Potential features for future versions:

- Export to CSV/JSON
- Integration with `/metrics` endpoint
- Grafana dashboard templates
- Email reports for failures
- Trend analysis and predictions
- Configurable cleanup schedule
- Compression for old records