# Activity Log - Audit Trail System

Sistem Activity Log untuk tracking semua perubahan data di database secara otomatis.

## 📋 Fitur

- ✅ Otomatis mencatat semua operasi Create, Update, Delete
- ✅ Menyimpan data lama dan baru dalam format JSON
- ✅ Tracking user yang melakukan perubahan
- ✅ Menyimpan IP address dan user agent
- ✅ Interface untuk melihat history perubahan
- ✅ Filter dan search activity log
- ✅ Clean up log lama

## 🚀 Cara Penggunaan

### 1. Tambahkan Behavior ke Model

Untuk mengaktifkan activity log pada model, tambahkan `ActivityLogBehavior` di method `behaviors()`:

```php
<?php

namespace common\models;

use yii\db\ActiveRecord;
use common\behaviors\ActivityLogBehavior;

class YourModel extends ActiveRecord
{
    public function behaviors()
    {
        return [
            // ... behaviors lainnya
            [
                'class' => ActivityLogBehavior::class,
                'skipAttributes' => ['updated_at', 'created_at'], // Optional: atribut yang tidak perlu di-log
                'logCreate' => true,  // Optional: default true
                'logUpdate' => true,  // Optional: default true
                'logDelete' => true,  // Optional: default true
            ],
        ];
    }
}
```

### 2. Contoh Implementasi pada Model yang Sudah Ada

#### Contoh 1: Model Barang

```php
// filepath: common/models/Barang.php

public function behaviors()
{
    return [
        [
            'class' => TimestampBehavior::class,
            // ... config lainnya
        ],
        [
            'class' => ActivityLogBehavior::class,
            'skipAttributes' => ['updated_at', 'created_at', 'created_by', 'updated_by'],
        ],
    ];
}
```

#### Contoh 2: Model User

```php
// filepath: common/models/User.php

public function behaviors()
{
    return [
        [
            'class' => TimestampBehavior::class,
        ],
        [
            'class' => ActivityLogBehavior::class,
            'skipAttributes' => ['updated_at', 'created_at', 'auth_key', 'password_hash'],
        ],
    ];
}
```

### 3. Mengakses Activity Logs

#### Di Controller/View:

```php
// Mendapatkan semua log untuk model tertentu
$logs = ActivityLog::find()
    ->where(['model_class' => Barang::class, 'model_id' => $id])
    ->orderBy(['created_at' => SORT_DESC])
    ->all();

// Atau menggunakan relasi (jika sudah menambahkan method getActivityLogs di model)
$model = Barang::findOne($id);
$logs = $model->activityLogs;
```

#### Menambahkan Relasi di Model (Optional):

```php
public function getActivityLogs()
{
    return $this->hasMany(ActivityLog::class, ['model_id' => 'id'])
        ->andWhere(['model_class' => self::class])
        ->orderBy(['created_at' => SORT_DESC]);
}
```

### 4. Menampilkan Activity Log di View

```php
<?php foreach ($model->activityLogs as $log): ?>
    <div class="activity-item">
        <strong><?= $log->getEventLabel() ?></strong>
        oleh <?= $log->user ? $log->user->username : 'System' ?>
        pada <?= Yii::$app->formatter->asDatetime($log->created_at) ?>
        
        <?php if ($log->event === 'updated'): ?>
            <div class="changes">
                <?php foreach ($log->getChanges() as $attr => $change): ?>
                    <div>
                        <strong><?= $attr ?>:</strong>
                        <span class="old"><?= $change['old'] ?></span>
                        →
                        <span class="new"><?= $change['new'] ?></span>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>
    </div>
<?php endforeach; ?>
```

## 📊 Melihat Activity Logs

Akses halaman activity log melalui:
```
http://your-domain/activity-log
```

Atau tambahkan menu di sidebar:
```php
[
    'label' => 'Activity Log',
    'icon' => 'fa fa-history',
    'url' => ['/activity-log/index'],
],
```

## 🧹 Maintenance

### Hapus Log Lama

Secara manual via web interface:
- Buka `/activity-log/index`
- Klik tombol "Clear Old Logs"

Atau via console:
```bash
# Hapus log lebih dari 30 hari
php yii activity-log/clear 30

# Hapus log lebih dari 90 hari
php yii activity-log/clear 90
```

### Setup Cron Job untuk Auto Cleanup

Tambahkan di crontab:
```bash
# Cleanup setiap hari jam 2 pagi
0 2 * * * cd /path/to/project && php yii activity-log/clear 90
```

## 🎨 Customization

### Memodifikasi Data yang Disimpan

Edit file `common/behaviors/ActivityLogBehavior.php`:

```php
protected function saveLog($event, $oldAttributes, $newAttributes)
{
    // Tambahkan custom logic di sini
    // Misalnya: filter attribute tertentu, format data, dll
    
    $log = new ActivityLog();
    // ... konfigurasi lainnya
    
    return $log->save(false);
}
```

### Menambahkan Event Handler

```php
// Di model Anda
public function behaviors()
{
    return [
        [
            'class' => ActivityLogBehavior::class,
            'logCreate' => true,
            'logUpdate' => true,
            'logDelete' => false,  // Nonaktifkan log delete
        ],
    ];
}
```

## 🔍 Query Examples

```php
// Log hari ini
$today = ActivityLog::find()
    ->where(['>=', 'created_at', strtotime('today')])
    ->all();

// Log dari user tertentu
$userLogs = ActivityLog::find()
    ->where(['user_id' => $userId])
    ->all();

// Log untuk model dan event tertentu
$deletedItems = ActivityLog::find()
    ->where([
        'model_class' => Barang::class,
        'event' => 'deleted'
    ])
    ->all();

// Log dengan perubahan pada attribute tertentu
$logs = ActivityLog::find()
    ->where(['like', 'new_attributes', '"status"'])
    ->all();
```

## 📝 Database Schema

```sql
CREATE TABLE `activity_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `model_class` varchar(255) NOT NULL,
  `model_id` int(11) NOT NULL,
  `event` varchar(50) NOT NULL,
  `old_attributes` text,
  `new_attributes` text,
  `user_id` int(11),
  `ip_address` varchar(45),
  `user_agent` varchar(255),
  `created_at` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx-activity_log-model` (`model_class`,`model_id`),
  KEY `idx-activity_log-user` (`user_id`),
  KEY `idx-activity_log-event` (`event`),
  KEY `idx-activity_log-created` (`created_at`)
);
```

## 🛡️ Security & Performance

### Tips:
1. **Exclude sensitive data**: Gunakan `skipAttributes` untuk password, token, dll
2. **Regular cleanup**: Setup cron job untuk hapus log lama
3. **Index optimization**: Table sudah dilengkapi index, pastikan query menggunakan index
4. **Async logging**: Untuk high-traffic apps, pertimbangkan queue system

### Exclude Sensitive Attributes:
```php
'skipAttributes' => [
    'password',
    'password_hash',
    'auth_key',
    'access_token',
    'verification_token',
    'password_reset_token',
]
```

## 🐛 Troubleshooting

### Log tidak tersimpan:
1. Cek behavior sudah ditambahkan dengan benar
2. Cek table activity_log sudah ada
3. Cek error di log: `runtime/logs/app.log`

### Performance lambat:
1. Cleanup log lama
2. Pertimbangkan archiving ke table terpisah
3. Gunakan queue untuk async logging

### Error permission:
Pastikan user sudah login atau handle case guest user di behavior.

## 📚 Files Structure

```
common/
├── behaviors/
│   └── ActivityLogBehavior.php      # Behavior untuk auto logging
├── models/
│   └── ActivityLog.php              # Model activity log
backend/
├── controllers/
│   └── ActivityLogController.php    # Controller untuk CRUD
├── models/
│   └── ActivityLogSearch.php        # Search model
└── views/
    └── activity-log/
        ├── index.php                # List activity logs
        ├── view.php                 # Detail log
        ├── _attributes.php          # Partial untuk attributes
        └── _changes.php             # Partial untuk changes
console/
└── migrations/
    └── m260213_000000_create_activity_log_table.php
```

## 📖 API Reference

### ActivityLog Model

**Methods:**
- `getUser()` - Relasi ke user
- `getOldAttributesArray()` - Get old attributes as array
- `getNewAttributesArray()` - Get new attributes as array
- `getModelName()` - Get short model name
- `getEventLabel()` - Get formatted event label
- `getChanges()` - Get changes between old and new

### ActivityLogBehavior

**Properties:**
- `$skipAttributes` - Array of attributes to skip
- `$logCreate` - Enable/disable create logging
- `$logUpdate` - Enable/disable update logging
- `$logDelete` - Enable/disable delete logging

---

**Dibuat:** 13 Februari 2026  
**Version:** 1.0.0
