# DETAILED FEATURE GAP ANALYSIS
## Missing Features & Implementation Roadmap

---

## 1. EMAIL & NOTIFICATION SYSTEM

### ❌ Currently Missing:

**A. Welcome Email on Registration**
```php
// Currently: User registers, no email sent
// Should: AutoReplyMail or WelcomeMail class exists but not used

// Expected Implementation:
After user registration:
1. Send welcome email
2. Request email verification
3. Welcome message with first steps
```

**B. Payment Confirmation Emails**
```
// Missing completely
// After successful payment on Midtrans:
1. Email with transaction details
2. Subscription activation confirmation
3. Receipt/invoice PDF
4. Next renewal date info
```

**C. Subscription Expiry Reminders**
```
// Missing completely
// Should send:
- 30 days before expiry: "Your subscription expiring soon"
- 7 days before: "Final reminder"
- On expiry: "Your subscription has expired"
- 3 days after: "Re-subscribe now"
```

**D. Analysis Completion Notification**
```
// Missing
// After analysis saved:
- Email to user: "Your analysis is ready"
- Link to view results
- PDF attachment option
```

**E. Admin Alerts**
```
// Missing
// Notify admin on:
- Failed payments
- New subscription
- User banned
- Abuse detected
- System errors
```

### ✅ What's Already There:
- Mail classes: ContactMail, AdminReplyMail, AutoReplyMail
- Queue system configured (but not active)
- Midtrans notifications route (but webhook incomplete)

### 🔧 What Needs to be Done:

```php
// Create new Mailable classes:
app/Mail/WelcomeMail.php
app/Mail/EmailVerificationMail.php
app/Mail/SubscriptionConfirmation.php
app/Mail/SubscriptionExpiry.php
app/Mail/AnalysisCompletedMail.php
app/Mail/AdminAlertMail.php

// Update .env configuration:
MAIL_MAILER=smtp  // Change from 'log'
MAIL_HOST=smtp.mailtrap.io  // or production SMTP
MAIL_PORT=587
MAIL_USERNAME=xxx
MAIL_PASSWORD=xxx

// Trigger emails from:
Listeners/Events:
- UserRegistered event → send welcome email
- SubscriptionCreated event → send confirmation
- SubscriptionExpiring event → send reminder

// OR directly in controllers:
RegisterController@register() → Mail::send()
PaymentController@handleWebhook() → Mail::send()
```

---

## 2. DATA IMPORT & EXPORT SYSTEM

### ❌ Currently Missing:

**A. Export Analysis as CSV**
```
Missing:
- CSV export for single analysis
- CSV export for all analyses
- CSV export dengan formatting
- Scheduled exports
- Email exported files

Expected Columns:
Company Name, Period, Currency, Total Assets, 
Total Debt, Revenue, Z-Score, Category, Recommendation
```

**B. Bulk Export**
```
Missing:
- Export multiple analyses sekaligus
- Batch processing untuk large datasets
- Download as ZIP
```

**C. PDF Batch Export**
```
Missing:
- Export multiple analyses sebagai PDF
- Merge into single document
- or separate PDFs in ZIP
```

**D. Excel Import Template**
```
Missing:
- Download template Excel
- User fill financial data
- Upload & auto-calculate
- Error validation & reporting
```

**E. Data Backup**
```
Missing:
- User backup personal data
- Admin backup all data
- Scheduled backups
- Download backup files
```

### ✅ What's Already There:
- Dashboard export button (non-functional stub)
- Basic PDF generation working

### 🔧 Implementation Todo:

```php
// Create new classes:
app/Services/ExportService.php  // CSV, Excel, ZIP
app/Services/ImportService.php  // Parse uploaded files

// Create controllers:
app/Http/Controllers/ExportController.php
  - exportAnalysisCSV($id)
  - exportAnalysesCSV()
  - exportAnalysesPDF()
  - downloadBackup()

app/Http/Controllers/ImportController.php
  - downloadTemplate()
  - uploadFile()
  - validateData()
  - previewData()
  - importData()

// Create models/jobs:
app/Jobs/ExportAnalysesJob.php
app/Jobs/ImportAnalysesJob.php

// Create views:
resources/views/export/index.blade.php
resources/views/import/index.blade.php

// Update routes:
Route::post('/export/csv', [ExportController::class, 'csv']);
Route::post('/export/excel', [ExportController::class, 'excel']);
Route::get('/import/template', [ImportController::class, 'template']);
Route::post('/import/upload', [ImportController::class, 'upload']);
```

---

## 3. EMAIL VERIFICATION

### ❌ Currently Missing:

**Workflow:**
```
Current: 
User registers → immediately logged in

Should be:
User registers → 
  1. Email with verification link sent
  2. User redirected to "Check your email" page
  3. User clicks link in email
  4. Account verified
  5. Allowed to login/access

Free features: Limited until verified
Pro features: Blocked until verified
```

### 🔧 Implementation:

```php
// 1. Create migration:
// Add columns to users table (already exists in User model):
// - email_verified_at (already exists)

// 2. Create Mailable:
app/Mail/VerifyEmailMail.php

// 3. Update RegisterController:
public function register(Request $request)
{
    // ... validation ...
    $user = User::create([...]);
    
    // Send verification email
    Mail::send(new VerifyEmailMail($user));
    
    return redirect('email-verify-pending')
        ->with('email', $user->email);
}

// 4. Create email verification controller:
app/Http/Controllers/EmailVerificationController.php
  - showVerificationNotice()
  - verify($request)  // Validate token and verify email
  - resendVerificationEmail($request)

// 5. Add routes:
Route::middleware('auth')->group(function () {
    Route::get('/email/verify', 'EmailVerificationController@show')
        ->name('verification.notice');
    Route::post('/email/verify/{id}/{hash}', 'EmailVerificationController@verify')
        ->name('verification.verify');
    Route::post('/email/resend', 'EmailVerificationController@resend')
        ->name('verification.resend');
});

// 6. Add middleware to protect features:
// Only allow non-verified users to do:
// - View public pages
// - Update email
// - Resend verification

// Block non-verified from:
// - Create analyses (Pro features)
// - Subscribe to premium
// - Download reports
```

---

## 4. PASSWORD RESET SYSTEM

### ❌ Currently Missing:

**Route exists but:**
```
- View at routes/web.php line ~60
- Route::get('/forgot-password', fn() => view('auth.forgot-password'))
- BUT: resources/views/auth/forgot-password.blade.php DOES NOT EXIST
- Password reset logic not fully implemented
```

### 🔧 Implementation:

```php
// Create missing resources:

// 1. resources/views/auth/forgot-password.blade.php
// - Form untuk input email
// - Submit button
// - Validation errors

// 2. resources/views/auth/reset-password.blade.php
// - Form untuk input new password
// - Token field (hidden)
// - Password confirmation
// - Submit button

// 3. Create migration (jika belum):
// Schema::create('password_reset_tokens', function (Blueprint $table) {
//     $table->string('email')->primary();
//     $table->string('token');
//     $table->timestamp('created_at')->nullable();
// });

// 4. Create controller:
app/Http/Controllers/Auth/PasswordResetController.php
  - showForgotForm()
  - sendResetLink($request)
  - showResetForm($token)
  - reset($request)

// 5. Create Mailable:
app/Mail/PasswordResetMail.php

// 6. Update routes:
Route::middleware('guest')->group(function () {
    Route::get('/forgot-password', 'PasswordResetController@showForgotForm')
        ->name('password.request');
    Route::post('/forgot-password', 'PasswordResetController@sendResetLink')
        ->name('password.email');
    Route::get('/reset-password/{token}', 'PasswordResetController@showResetForm')
        ->name('password.reset');
    Route::post('/reset-password', 'PasswordResetController@reset')
        ->name('password.update');
});
```

---

## 5. SUBSCRIPTION LIMITS & ENFORCEMENT

### ❌ Currently Missing:

**Problem:**
```
- Free users dapat unlimited analyses (should be limited)
- No enforcement di controller
- No tracking usage
- No blocking when limit reached
```

**Expected:**
```
Free Plan:
  - 5 analyses per month
  - 1 company max
  - No PDF export
  - Watermarked reports
  - No API access
  - Community support

Pro Plan (IDR 299,000/month):
  - Unlimited analyses
  - 10 companies
  - PDF export & download
  - Premium reporting
  - Email support
  - Basic API access

Enterprise Plan:
  - Unlimited everything
  - Unlimited companies
  - Full API access
  - Custom features
  - Priority support
  - Dedicated account manager
```

### 🔧 Implementation:

```php
// 1. Add usage tracking table:
Schema::create('usage_tracking', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->integer('analyses_count')->default(0);
    $table->integer('analyses_month')->default(0);
    $table->integer('companies_count')->default(0);
    $table->date('month_start_date');
    $table->timestamps();
});

// 2. Add methods to User model:
public function canCreateAnalysis(): bool
{
    $subscription = $this->subscription();
    
    if (!$subscription || $subscription->plan === 'free') {
        $monthsAnalyses = AnalysisResult::where('user_id', $this->id)
            ->whereMonth('created_at', now()->month)
            ->count();
        return $monthsAnalyses < 5;
    }
    
    return true;
}

public function canCreateCompany(): bool
{
    $subscription = $this->subscription();
    $limit = match($subscription?->plan ?? 'free') {
        'free' => 1,
        'pro' => 10,
        'enterprise' => 999
    };
    
    return $this->companies()->count() < $limit;
}

public function getFeatureAccess(string $feature): bool
{
    $plan = $this->subscription()?->plan ?? 'free';
    
    $features = [
        'free' => ['analyses', 'companies' => 1],
        'pro' => ['analyses', 'companies' => 10, 'pdf_export', 'email_support', 'api_basic'],
        'enterprise' => ['*']
    ];
    
    return in_array('*', $features[$plan])
        || in_array($feature, $features[$plan]);
}

// 3. Create middleware:
// app/Http/Middleware/CheckSubscriptionLimit.php
public function handle($request, Closure $next)
{
    $user = auth()->user();
    
    if (!$user->canCreateAnalysis()) {
        return back()->with('error', 'Limit analisis bulanan tercapai');
    }
    
    return $next($request);
}

// 4. Apply middleware to routes:
Route::middleware(['auth', 'check.subscription.limit'])
    ->post('/analysis/step1', [AnalysisController::class, 'saveStep1']);

// 5. Show feature availability in UI:
@if(auth()->user()->getFeatureAccess('pdf_export'))
    <button>Export PDF</button>
@else
    <button disabled title="Feature not available in current plan">
        Upgrade untuk export PDF
    </button>
@endif
```

---

## 6. AUDIT & LOGGING SYSTEM

### ❌ Currently Missing:

```
No visibility untuk:
- Siapa yang create/update/delete apa
- Kapan perubahan terjadi
- Apa yang berubah (old value → new value)
- Admin action tracking
- Login tracking
- Failed login attempts
- User activity timeline
```

### 🔧 Implementation:

```php
// 1. Create audit log table:
Schema::create('audit_logs', function (Blueprint $table) {
    $table->id();
    $table->string('model_class');
    $table->unsignedBigInteger('model_id')->nullable();
    $table->string('event');  // created, updated, deleted
    $table->foreignId('user_id')->nullable()->constrained();
    $table->string('user_email')->nullable();
    $table->string('user_ip')->nullable();
    $table->string('user_agent')->nullable();
    $table->json('old_values')->nullable();
    $table->json('new_values')->nullable();
    $table->text('description')->nullable();
    $table->timestamps();
    $table->index(['model_class', 'model_id', 'created_at']);
});

// 2. Create observer trait:
// app/Traits/HasAuditLog.php
trait HasAuditLog
{
    protected static function booted()
    {
        static::created(function ($model) {
            AuditLog::log('created', $model, 
                oldValues: [], 
                newValues: $model->attributesToArray()
            );
        });
        
        static::updated(function ($model) {
            AuditLog::log('updated', $model,
                oldValues: $model->getOriginal(),
                newValues: $model->getChanges()
            );
        });
        
        static::deleted(function ($model) {
            AuditLog::log('deleted', $model,
                oldValues: $model->attributesToArray(),
                newValues: []
            );
        });
    }
}

// 3. Use in models:
class AnalysisResult extends Model
{
    use HasAuditLog;
}

// 4. Create audit log viewer:
// app/Http/Controllers/Admin/AuditLogController.php
// resources/views/admin/audit-logs/index.blade.php

// 5. Admin routes:
Route::get('/admin/audit-logs', [AuditLogController::class, 'index']);
Route::get('/admin/audit-logs/{id}', [AuditLogController::class, 'show']);
```

---

## 7. SHARING & COLLABORATION

### ❌ Currently Missing:

**Model has share_token but:**
```
- No UI to generate share link
- No route to view shared analysis
- No permission system
- No time-limited shares
- No password protection for shares
```

### Expected Features:
```
User clicks "Share" on analysis:
1. Dialog appears with options:
   - Create shareable link
   - Set expiry (24h, 7d, 30d, never)
   - Set password (optional)
   - Allow download (checkbox)
   - Copy link to clipboard

2. Shared link can be:
   - Opened without login
   - View-only (read-only)
   - Download allowed/not
   - Expires after set time
   - Protected by password

3. Recipient sees:
   - Full analysis & results
   - Not full company info (privacy)
   - Can download if allowed
   - Cannot edit
```

### 🔧 Implementation:

```php
// 1. Create sharing table:
Schema::create('analysis_shares', function (Blueprint $table) {
    $table->id();
    $table->foreignId('analysis_result_id')->constrained();
    $table->foreignId('owner_id')->constrained('users');
    $table->string('share_token')->unique();
    $table->string('password_hash')->nullable();
    $table->enum('permission', ['view', 'download'])->default('view');
    $table->timestamp('expires_at')->nullable();
    $table->integer('views_count')->default(0);
    $table->timestamps();
});

// 2. Create controller:
// app/Http/Controllers/ShareController.php
public function create(AnalysisResult $analysis)
{
    // Show form to create share
}

public function store(Request $request, AnalysisResult $analysis)
{
    $validated = $request->validate([
        'expires_at' => 'nullable|date|after:now',
        'password' => 'nullable|string|min:4',
        'permission' => 'in:view,download',
    ]);
    
    $share = AnalysisShare::create([
        'analysis_result_id' => $analysis->id,
        'owner_id' => auth()->id(),
        'share_token' => Str::random(32),
        'password_hash' => $validated['password'] 
            ? Hash::make($validated['password']) 
            : null,
        'permission' => $validated['permission'],
        'expires_at' => $validated['expires_at'],
    ]);
    
    return response()->json([
        'share_link' => route('share.view', $share->share_token),
        'token' => $share->share_token
    ]);
}

public function view($token)
{
    $share = AnalysisShare::where('share_token', $token)
        ->where(function ($query) {
            $query->whereNull('expires_at')
                ->orWhere('expires_at', '>', now());
        })
        ->firstOrFail();
    
    if ($share->password_hash && !session("share.{$token}.authenticated")) {
        return view('share.password-prompt', ['token' => $token]);
    }
    
    $share->increment('views_count');
    
    return view('share.view', ['analysis' => $share->analysis_result]);
}

// 3. Create routes:
Route::get('/share/{token}', [ShareController::class, 'view'])->name('share.view');
Route::post('/share/{token}/verify', [ShareController::class, 'verifyPassword']);

Route::middleware('auth')->group(function () {
    Route::post('/analysis/{id}/share', [ShareController::class, 'store']);
    Route::get('/my-shares', [ShareController::class, 'myShares']);
    Route::delete('/share/{token}', [ShareController::class, 'revoke']);
});
```

---

## 8. REAL-TIME NOTIFICATIONS

### ❌ Currently Missing:

```
- In-app notifications (toast/bell icon)
- Real-time updates
- Notification center
- Mark as read
- Delete notifications
```

### Expected:
```
Notifications for:
- Payment received
- Subscription expiring soon
- Analysis ready (if async)
- Admin messages
- System alerts
```

### 🔧 Implementation (Using Livewire):

```php
// 1. Create notification table:
Schema::create('notifications', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->string('type');  // payment, subscription, system, message
    $table->string('title');
    $table->text('message');
    $table->string('action_url')->nullable();
    $table->timestamp('read_at')->nullable();
    $table->json('data')->nullable();
    $table->timestamps();
});

// 2. Create Notification model:
class Notification extends Model
{
    // ...
    public function markAsRead()
    {
        $this->update(['read_at' => now()]);
    }
}

// 3. Create Livewire component:
// app/Livewire/NotificationsCenter.php
class NotificationsCenter extends Component
{
    public $notifications;
    
    public function mount()
    {
        $this->loadNotifications();
    }
    
    #[On('notification:new')]
    public function loadNotifications()
    {
        $this->notifications = auth()->user()
            ->notifications()
            ->latest()
            ->take(10)
            ->get();
    }
    
    public function markAsRead($id)
    {
        Notification::find($id)?->markAsRead();
        $this->loadNotifications();
    }
    
    public function render()
    {
        return view('livewire.notifications-center');
    }
}

// 4. Create event:
class NotificationCreated
{
    public function __construct(public Notification $notification) {}
}

// 5. Fire event when needed:
Notification::create([...]);
dispatch(new NotificationCreated($notification));

// 6. View component in header
<livewire:notifications-center />
```

---

## 9. API ENDPOINTS

### ❌ Currently Missing:

```
No API for third-party integration:
- Cannot create analyses via API
- Cannot get analysis results
- Cannot manage companies
- No webhook support
- No API documentation
```

### Expected API Structure:

```
GET    /api/v1/analyses
POST   /api/v1/analyses
GET    /api/v1/analyses/{id}
PUT    /api/v1/analyses/{id}
DELETE /api/v1/analyses/{id}

GET    /api/v1/companies
POST   /api/v1/companies
GET    /api/v1/companies/{id}

GET    /api/v1/subscriptions
GET    /api/v1/subscriptions/{id}

Webhooks:
POST   /api/v1/webhooks/payment
POST   /api/v1/webhooks/subscription
```

### 🔧 Implementation:

```php
// 1. Create API resources:
app/Http/Resources/AnalysisResource.php
app/Http/Resources/CompanyResource.php
app/Http/Resources/SubscriptionResource.php

// 2. Create API controllers:
app/Http/Controllers/Api/V1/AnalysisController.php
app/Http/Controllers/Api/V1/CompanyController.php
app/Http/Controllers/Api/V1/SubscriptionController.php

// 3. Create API routes:
// routes/api.php
Route::prefix('v1')->middleware('auth:sanctum')->group(function () {
    Route::apiResource('analyses', Api\V1\AnalysisController::class);
    Route::apiResource('companies', Api\V1\CompanyController::class);
    Route::get('subscriptions', [Api\V1\SubscriptionController::class, 'show']);
});

// 4. Authentication (Laravel Sanctum):
// User creates API token via:
// Settings → API Tokens → Create Token

// Usage:
// curl -H "Authorization: Bearer TOKEN" https://app.com/api/v1/analyses

// 5. Rate limiting:
RateLimiter::for('api', function (Request $request) {
    return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});

// 6. Create OpenAPI/Swagger docs:
// resources/docs/openapi.yaml
// or use laravel-swagger package
```

---

## 10. TWO-FACTOR AUTHENTICATION (2FA)

### ❌ Currently Missing:

```
No 2FA implementation
- No TOTP setup (authenticator apps)
- No backup codes
- No SMS option
- No user control over 2FA
```

### 🔧 Implementation (Using Laravel):

```php
// 1. Create 2FA table:
Schema::create('two_factor_authentications', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->string('two_factor_secret');
    $table->json('backup_codes');
    $table->timestamp('confirmed_at')->nullable();
    $table->timestamps();
});

// 2. Add to User model:
class User extends Authenticatable
{
    use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider;
    
    public function twoFactorAuth()
    {
        return $this->hasOne(TwoFactorAuthentication::class);
    }
}

// 3. Create controller:
// app/Http/Controllers/Auth/TwoFactorController.php
public function enable()
{
    // Generate TOTP secret and backup codes
}

public function confirm(Request $request)
{
    // Validate TOTP code and save
}

public function disable(Request $request)
{
    // Remove 2FA
}

// 4. Use Laravel Fortify package:
composer require laravel/fortify

// 5. Configure 2FA in middleware
```

---

## SUMMARY TABLE

| Feature | Status | Priority | Est. Hours |
|---------|--------|----------|-----------|
| Email Notifications | ❌ Missing | 🔴 Critical | 16 |
| Data Export/Import | ❌ Missing | 🔴 Critical | 24 |
| Email Verification | ❌ Missing | 🔴 Critical | 12 |
| Password Reset | 🟡 Partial | 🔴 Critical | 8 |
| Subscription Limits | ❌ Missing | 🔴 Critical | 16 |
| Audit Logging | ❌ Missing | 🟡 Important | 12 |
| Sharing | ❌ Missing | 🟡 Important | 16 |
| Real-time Notifications | ❌ Missing | 🟡 Important | 12 |
| API Endpoints | ❌ Missing | 🟡 Important | 24 |
| 2FA Security | ❌ Missing | 🟠 Nice-to-have | 8 |
| **TOTAL** | | | **148 hours** |

---

**Estimated Timeline:**
- **1 developer, full-time:** ~4-5 weeks
- **2 developers, full-time:** ~2-3 weeks  
- **3 developers, full-time:** ~1-2 weeks

