# ERP CTE - Project Documentation for AI Agents

## Project Overview

**ERP CTE** (Career and Technical Education) is a multi-tenant ERP system built with **Laravel 11** and **Filament v3**. It manages business operations for creative/tech studios including project management, marketing/proposals, finance, HR, and KPI tracking.

- **Framework**: Laravel 11, PHP 8.2+
- **Admin Panel**: Filament v3 (3 panels: App, Admin, Mentor)
- **Frontend**: Tailwind CSS, Vite, Livewire (via Filament)
- **Database**: MySQL (`objidev_app`)
- **Multi-tenancy**: Team-based (Filament tenant)
- **Auth/RBAC**: Spatie Permission + FilamentShield
- **Queue/Cache/Session**: Database driver

---

## Architecture

### Multi-Panel Structure

| Panel | Path | Tenancy | Purpose |
|-------|------|---------|---------|
| **App** | `/app` | Team-scoped | Main operational panel for all team members |
| **Admin** | `/admin` | None (global) | Super-admin management (users, teams, categories) |
| **Mentor** | `/mentor` | None (global) | Cross-team oversight dashboards (KPI, Finance) |

### Multi-Tenancy

- Tenant model: `Team`
- Users with role `Koordinator` can access all teams
- All resources scope queries via `filament()->getTenant()->id`
- Team model has: `name`, `slug`, `logo`, `circle`, `business_address`, `business_email`

### Permissions

- Managed by **Spatie Permission** + **FilamentShield**
- Each resource has auto-generated CRUD permissions
- Custom pages gate access via `hasPermissionTo('page_PageName')`
- Admin panel restricted to `super admin` role

---

## Data Models (36 models)

### Core Business

| Model | Table | Key Fields | Relations |
|-------|-------|------------|-----------|
| `Team` | `teams` | name, slug, logo, circle, business_address, business_email | hasMany: all tenant-scoped models; belongsToMany: users |
| `User` | `users` | name, email, avatar, account_number, joined_at, phone_number, base_salary, housing/meal/internet_allowance | belongsToMany: teams; hasMany: objectives, sdms, salarySlips, earningTargets |
| `Project` | `projects` | name, description, status, start/end_date, project_type, project_rate, stacks (JSON), client_id | hasMany: documents, sprints, tasks, earnings, reports; belongsTo: client |
| `Client` | `clients` | name, email, phone, address, country, platform_id, status (1-6 lifecycle) | hasMany: projects; belongsTo: platform, team |
| `Platform` | `platforms` | name, description | hasMany: proposals, marketingReports, clients |

### Marketing & Proposals

| Model | Table | Key Fields | Relations |
|-------|-------|------------|-----------|
| `Proposal` | `proposals` | title, job_description, job_link, price, country, status (array), type, client_name, tanggal_proposal, lead_only, check_masuk_lead, deal_status, action (JSON), condition, date_bidding, date_lead | belongsTo: platform, team; belongsToMany: skills |
| `Skill` | `skills` | name | belongsToMany: proposals |
| `MarketingReport` | `marketing_reports` | date, badge_connect, total_profile_view, boost_profile, total_impression, click, platform_id | belongsTo: platform, team |

> **Note**: `Proposal` serves dual purpose — proposals (`lead_only=false`) via `ProposalResource` and leads (`check_masuk_lead=true`) via `LeadResource`.

### Finance

| Model | Table | Key Fields | Relations |
|-------|-------|------------|-----------|
| `FinanceReport` | `finance_reports` | date, total_income, total_expense, total_balance, initial_balance, saving | hasMany: transactions, incomes (filtered), expenses (filtered) |
| `Transaction` | `transactions` | transaction_category_id, description, amount (decimal 15,2), date, sort_order, finance_report_id | belongsTo: category, financeReport. Amount uses Indonesian format (dot=thousands, comma=decimal) |
| `TransactionCategory` | `transaction_categories` | name, description, type (income/expense), tags | hasMany: transactions |
| `Invoice` | `invoices` | client_id, invoice_number, invoice_date, due_date, total_amount, discount, tax, currency (IDR/USD/EUR/AUD), status, paid_at | hasMany: items; belongsTo: client |
| `InvoiceItem` | `invoice_items` | description, quantity, price, total | belongsTo: invoice |
| `SalarySlip` | `salary_slips` | user_id, period_start/end, basic_salary, performance_allowance, target_bonus, overtime_fee, housing/meal/internet_allowance, miscellaneous | belongsTo: user, team |
| `Forecasting` | `forecastings` | year, month, beginning_balance, 12 computed fields (3 scenarios x 4 metrics) | hasMany: estimatedIncomes, estimatedExpenses |
| `EstimatedIncome` | `estimated_incomes` | description, nominal_real, nominal_target, forecastings_id | belongsTo: forecasting |
| `EstimatedExpense` | `estimated_expenses` | description, nominal_real, nominal_target, forecastings_id | belongsTo: forecasting |

### Production & Tasks

| Model | Table | Key Fields | Relations |
|-------|-------|------------|-----------|
| `Sprint` | `sprints` | project_id, name, start_date, end_date, status | belongsTo: project; hasMany: tasks |
| `Task` | `tasks` | project_id, sprint_id, name, description, due_date, status (0=Pending, 1=In Progress, 2=Completed) | belongsTo: project, sprint; uses HasFilamentComments |
| `TaskStatus` | `task_statuses` | name, color | — |
| `ProjectDocument` | `project_documents` | project_id, name, file_path | belongsTo: project |
| `ProjectEarning` | `project_earnings` | project_id, (earnings data) | belongsTo: project |
| `ProjectReport` | `project_reports` | project_id, (report data) | belongsTo: project |

### KPI & Strategic Planning

| Model | Table | Key Fields | Relations |
|-------|-------|------------|-----------|
| `GroupObjective` | `group_objectives` | name, description, status (Active/Inactive) | hasMany: objectives |
| `Objective` | `objectives` | name, group_objective_id, description, start/end_date, target, realized, pic_user_id, unit | belongsTo: groupObjective; belongsToMany: picUser (users) |
| `StrategicPlan` | `strategic_plans` | team_id, quarter (Q1-Q4), year, goal (rich text), action_plan (rich text) | belongsTo: team; unique per team+quarter+year |

### HR

| Model | Table | Key Fields | Relations |
|-------|-------|------------|-----------|
| `Sdm` | `sdms` | user_id, date, new_update (rich text), future_target (rich text) | belongsTo: user, team |
| `UserEarningTarget` | `user_earning_targets` | user_id, (target data) | belongsTo: user |

### Auth

| Model | Table | Key Fields |
|-------|-------|------------|
| `Role` | `roles` | name, guard_name, team_id |
| `Permission` | `permissions` | name, guard_name, team_id |
| `TeamUser` | `team_user` | team_id, user_id (pivot) |

---

## Filament Resources

### App Panel (`/app`) - Team-scoped

| Resource | Model | Nav Group | Sort | Features |
|----------|-------|-----------|------|----------|
| `PlatformResource` | Platform | Marketing | 1 | Simple CRUD |
| `ClientResource` | Client | Marketing | 2 | Country flag picker, status lifecycle, CSV import |
| `MarketingReportResource` | MarketingReport | Marketing | 3 | Stats profile tracking, Excel/PDF export, CSV import |
| `ProposalResource` | Proposal | Marketing | 4 | Multi-step status tracking, country flags, skills tags, lead management section, import/export |
| `LeadResource` | Proposal | Marketing | 5 | Same model filtered to `check_masuk_lead=true`, lead-specific form layout |
| `ProjectResource` | Project | Projek | — | PIC users, stacks tags, relation managers (Reports, Earnings) |
| `FinanceReportResource` | FinanceReport | Finance | 1 | Single transactions TableRepeater with virtual type (income/expense) field, auto-calculate totals on save, CSV/PDF(BCA) import, PDF export, view page with Alpine.js tabs (All, Jurnal Keuangan, Posting Keuangan, Laba Rugi, Arus Kas, Neraca). See `memory/financial_reporting.md` for full details |
| `ForecastingResource` | Forecasting | Finance | 2 | 3-scenario forecasting, TableRepeaters, grouped by year, import/export (CSV/PDF/Excel) |
| `InvoiceResource` | Invoice | Finance | 3 | Hidden nav, multi-currency, item repeater, inline Pay action |
| `SalarySlipResource` | SalarySlip | Finance | 4 | Auto-fill from user profile, PDF export |
| `SdmResource` | Sdm | Management | 1 | Talent reports, grouped by date |
| `UserResource` | User | Management | — | Team member management, avatar, salary fields |
| `GroupObjectiveResource` | GroupObjective | Objektif | 1 | Simple CRUD for KPI groups |
| `ObjectiveResource` | Objective | Objektif | 1 | KPI tracking with progress badges (color-coded) |
| `StrategicPlanResource` | StrategicPlan | Objektif | 1 | Quarterly strategic plans, unique per team+quarter+year |
| `ProjectDocumentResource` | ProjectDocument | — | — | Project document management |
| `ProjectReportResource` | ProjectReport | — | — | Project reports |
| `TransactionResource` | Transaction | — | — | Finance transactions |

### Admin Panel (`/admin`) - Global

| Resource | Model | Features |
|----------|-------|----------|
| `ManagementStudioResource` | Team | Studio/team CRUD with logo |
| `UserResource` | User | Cross-team user management, password reset action |
| `TransactionCategoryResource` | TransactionCategory | Income/expense category management |
| `StrategicPlanResource` | StrategicPlan | Cross-team strategic plan management |

---

## Dashboard Pages

### App Panel Dashboards

| Page | Nav Label | Group | Permission | Widgets |
|------|-----------|-------|------------|---------|
| `WelcomePage` | Overview Bisnis | Dashboard | `page_MainDashboard` | Business overview |
| `DashboardProduction` | Overview Produksi | Dashboard | Open | ProjectByEarnings, Statssummary, Statsproject, WorkloadDeveloper |
| `Marketing` | Overview Marketing | Dashboard | `page_Marketing` | KeyMetricsWidget, PerformanceOverview, ProposalStatsWidget, RevenueByProposal, ProposalConversionFunnel |
| `DashboardKPI` | Overview KPI | Dashboard | `page_DashboardKPI` | Inline KPI table + KPIProgressChart |
| `Financial` | Overview Keuangan | Dashboard | `page_Financial` | FinancialReportTable, FinanceTop3ReportTable, InvoiceReportTable, FinanceChartBar, FinanceChartPie |
| `ForecastingDashboard` | Overview Forecasting | Dashboard | `page_ForecastingDashboard` | 9 forecasting widgets (summaries, charts, top items) |

### App Panel Statistics Pages

| Page | Nav Label | Group | Purpose |
|------|-----------|-------|---------|
| `ProposalStatistics` | Proposal Statistics | Marketing | Weekly proposal status breakdown by month |
| `LeadStatistics` | Lead Statistics | Marketing | Weekly lead type breakdown (warm/hot/hire) |
| `ProfileMetrics` | Profile Metrics | Marketing | Weekly marketing platform metrics |

### Mentor Panel Dashboards

| Page | Nav Label | Widgets | Purpose |
|------|-----------|---------|---------|
| `OverviewKPI` | KPI Overview | OverViewKPI (cross-team KPI table) | Cross-team KPI performance |
| `OverviewKeuangan` | Finance Overview | TotalFinance (aggregated stats), TeamFinancereport (per-team table) | Cross-team finance overview with month/year filter |

---

## Widgets (22 in `app/Filament/Widgets/`)

### General Charts
- `IncomeChart` — Monthly income bar chart (Laravel Trend)
- `ExpenseChart` — Monthly expense bar chart
- `ProfitChart` — Monthly profit chart
- `MarketingReportChart` — Marketing metrics line chart

### Production
- `ProjectByEarnings` — Projects ranked by earnings
- `Statsproject` — Project statistics
- `Statssummary` — Summary stats
- `WorkloadDeveloper` — Developer workload distribution

### Marketing
- `KeyMetricsWidget` — Key marketing metrics
- `PerformanceOverview` — Marketing performance overview
- `ProposalStatsWidget` — Proposal statistics
- `ProposalStatisticsWidget` — Detailed proposal statistics
- `RevenueByProposal` — Revenue breakdown by proposal
- `ProposalConversionFunnel` — Conversion funnel visualization
- `ProposalBySkills` — Proposals grouped by skills
- `ProfileMetricsWidget` — Marketing profile metrics

### KPI
- `KPITableWidget` — KPI data table
- `KPIProgressChart` — KPI progress visualization
- `OverallKPIPerformanceWidget` — Overall KPI performance

### Finance
- `OverallKasPerformanceWidget` — Cash performance overview
- `TotalSaving` — Total savings display

---

## Import/Export System

### CSV Importers (Filament Importer)

| Importer | Source Model | Notes |
|----------|-------------|-------|
| `ClientImporter` | Client | Standard field mapping |
| `FinanceReportImporter` | FinanceReport | Maps debit/credit columns to income/expense transactions |
| `ForecastingImporter` | Forecasting | Type (income/expense), description, nominal_real, nominal_target |
| `MarketingReportImporter` | MarketingReport | Standard field mapping |
| `ProposalImporter` | Proposal | Standard field mapping |

### Exporters

| Exporter | Format | Route/Method |
|----------|--------|-------------|
| `MarketingReportExporter` | Excel | Filament table action |
| `ProposalExporter` | Excel | Filament table action |
| `ExportForecasting` | Excel | `/forecasting/{id}/export-excel` |
| `FinanceReportMentorExporter` | Excel | Mentor panel finance export |
| Forecasting PDF | PDF (DomPDF) | `/forecasting/{id}/export-pdf` |
| Finance Report PDF | PDF (DomPDF) | `/finance-report/{id}/export-pdf` |
| Salary Slip PDF | PDF (DomPDF) | `/salary/{id}/export-pdf` |
| Marketing Report PDF | PDF (DomPDF) | `/marketing-reports/export-pdf` |

---

## Routes

### Web Routes (`routes/web.php`)

```
GET  /                                  → Redirect to /app
GET  /forecasting/{id}/export-pdf       → ForecastingExportController@export_pdf
GET  /forecasting/{id}/export-excel     → ForecastingExportController@export_excel
GET  /finance-report/{id}/export-pdf    → FinanceReportExportController@exportPdf
GET  /salary/{id}/export-pdf            → SalarySlipExportController@exportPdf
GET  /marketing-reports/export-pdf      → Closure (DomPDF)
GET  /finance-report/export-excel       → FinanceReportController@exportExcel
```

### Admin Routes (`routes/admin.php`)
- Empty middleware group (placeholder for future admin API routes)

---

## Policies (19 policies)

All policies use Spatie Permission pattern — `$user->can('permission_name')` for each CRUD action:

`ClientPolicy`, `FinanceReportPolicy`, `ForecastingPolicy`, `GroupObjectivePolicy`, `InvoicePolicy`, `MarketingReportPolicy`, `ObjectivePolicy`, `PlatformPolicy`, `ProjectDocumentPolicy`, `ProjectPolicy`, `ProposalPolicy`, `RolePolicy`, `SalarySlipPolicy`, `SdmPolicy`, `StrategicPlanPolicy`, `TeamPolicy`, `TransactionCategoryPolicy`, `UserPolicy`

---

## Key Patterns & Conventions

### Code Conventions
- **Language**: UI is in **Indonesian** (Bahasa Indonesia) — labels, navigation, notifications
- **Filament resources**: Standard pattern with `form()`, `table()`, `getEloquentQuery()` tenant scoping
- **Tenant scoping**: `->where('team_id', filament()->getTenant()->id)` in `getEloquentQuery()`
- **Money formatting**: Uses `mask('999,999,999')` pattern for currency inputs
- **Rich text**: Uses `RichEditor` for long-form content (goals, descriptions, notes)
- **Country picker**: Uses `lwwcas/laravel-countries` for country dropdowns with flags
- **Navigation badges**: Resources show tenant-scoped record counts via `getNavigationBadge()`

### Shared Model Pattern
- `Proposal` model is used by both `ProposalResource` (proposals) and `LeadResource` (leads)
- Differentiated by `lead_only` and `check_masuk_lead` boolean fields
- Both filter at `getEloquentQuery()` level

### Three-Scenario Forecasting
Forecasting tracks parallel metrics in 3 scenarios:
1. **Real** — actual income and expenses
2. **Target** — budgeted/planned amounts
3. **Real Income vs Estimated Expenses** — hybrid scenario for conservative planning

### Boot Cascade Deletes
- `Project` cascade-deletes: documents, sprints, tasks, earnings
- `FinanceReport` cascade-deletes: incomes, expenses (transactions)

---

## Directory Structure

```
app/
├── Exports/                    # Maatwebsite Excel export classes
├── Filament/
│   ├── Admin/Resources/        # Admin panel resources (Team, User, Categories, StrategicPlan)
│   ├── Exports/                # Filament exporters
│   ├── Imports/                # Filament CSV importers
│   ├── Mentor/
│   │   ├── Pages/              # Mentor dashboard pages
│   │   └── Widgets/            # Mentor cross-team widgets
│   ├── Pages/                  # App panel custom pages & dashboards
│   │   └── Tenancy/            # Team registration & profile
│   ├── Resources/              # App panel resources (17 resources)
│   │   └── {Resource}/
│   │       ├── Pages/          # List, Create, Edit, View pages
│   │       ├── RelationManagers/  # Related model managers
│   │       └── Widgets/        # Resource-specific widgets
│   └── Widgets/                # Global widgets (22 widgets)
├── Http/Controllers/           # Export controllers (PDF, Excel)
├── Imports/                    # Additional import classes
├── Jobs/                       # ImportProposalsJob
├── Mail/                       # Mail classes
├── Models/                     # 36 Eloquent models
├── Policies/                   # 19 authorization policies
├── Providers/                  # Panel providers (App, Admin, Mentor)
└── Traits/                     # HasTenantUsers helper
database/
├── migrations/                 # 133 migrations
├── factories/
└── seeders/
resources/
├── views/                      # Blade views (PDF templates, custom components)
├── css/
└── js/
routes/
├── web.php                     # Web routes (redirects + export endpoints)
├── admin.php                   # Admin routes (placeholder)
└── console.php                 # Console commands
```

---

## Navigation Map

### App Panel (`/app`)

```
Dashboard
  ├── Overview Bisnis          (WelcomePage)
  ├── Overview Produksi        (DashboardProduction)
  ├── Overview Marketing       (Marketing)
  ├── Overview KPI             (DashboardKPI)
  ├── Overview Keuangan        (Financial)
  └── Overview Forecasting     (ForecastingDashboard)

Projek
  └── Project                  (ProjectResource)

Marketing
  ├── Platform                 (PlatformResource)
  ├── Client                   (ClientResource)
  ├── Stats Profile            (MarketingReportResource)
  ├── Proposal                 (ProposalResource)
  ├── Leads                    (LeadResource)
  ├── Lead Statistics          (LeadStatistics page)
  ├── Profile Metrics          (ProfileMetrics page)
  └── Proposal Statistics      (ProposalStatistics page)

Management
  ├── Team                     (UserResource)
  └── Talent Report            (SdmResource)

Finance
  ├── Finance Report           (FinanceReportResource)
  ├── Forecasting              (ForecastingResource)
  ├── Invoice                  (InvoiceResource, hidden nav)
  └── Salary Slip              (SalarySlipResource)

Objektif
  ├── Objektif Grup            (GroupObjectiveResource)
  ├── KPI                      (ObjectiveResource)
  └── Strategic Plans          (StrategicPlanResource)

General
  └── Kanban Board             (TasksKanbanBoard, hidden nav)
```

### Admin Panel (`/admin`)

```
Management
  ├── Studios                  (ManagementStudioResource - Team CRUD)
  └── Users                    (UserResource - cross-team)

Finance
  └── Transaction Categories   (TransactionCategoryResource)

Objektif
  └── Strategic Plans          (StrategicPlanResource - cross-team)
```

### Mentor Panel (`/mentor`)

```
Dashboard
  ├── KPI Overview             (OverviewKPI)
  └── Finance Overview         (OverviewKeuangan)
```

---

## Key Dependencies

### PHP (composer.json)

| Package | Version | Purpose |
|---------|---------|---------|
| `filament/filament` | ^3.2 | Admin panel framework |
| `bezhansalleh/filament-shield` | ^3.3 | Role/permission UI for Filament |
| `awcodes/filament-table-repeater` | ^3.1 | Table repeater form component |
| `barryvdh/laravel-dompdf` | * | PDF generation |
| `maatwebsite/excel` | ^3.1 | Excel import/export |
| `flowframe/laravel-trend` | ^0.3.0 | Time-series trend data for charts |
| `mokhosh/filament-kanban` | ^2.9 | Kanban board UI |
| `parallax/filament-comments` | ^1.4 | Commentable models |
| `lwwcas/laravel-countries` | ^4.11 | Country data with flags |
| `phpoffice/phpspreadsheet` | ^1.29 | Spreadsheet processing |
| `doctrine/dbal` | ^4.2 | Database schema introspection |
| `eightynine/filament-excel-import` | ^3.1 | Excel import for Filament |

### JavaScript (package.json)

| Package | Version | Purpose |
|---------|---------|---------|
| `tailwindcss` | ^3.4 | Utility-first CSS |
| `vite` | ^6.0 | Build tool |
| `laravel-vite-plugin` | ^1.2 | Laravel Vite integration |
| `autoprefixer` | ^10.4 | CSS vendor prefixes |
| `postcss-nesting` | ^13.0 | CSS nesting support |
| `axios` | ^1.7 | HTTP client |
| `concurrently` | ^9.0 | Run multiple dev processes |

---

## Development

### Running the project

```bash
# Start all dev services (server, queue, logs, vite)
composer dev

# Or individually:
php artisan serve          # Laravel server
php artisan queue:listen   # Queue worker
npm run dev                # Vite dev server
```

### Database

```bash
php artisan migrate        # Run migrations
php artisan db:seed        # Seed data
```

### Filament

```bash
php artisan shield:generate --all   # Generate permissions for all resources
php artisan filament:upgrade        # Upgrade Filament assets
```

### After changing the blade code
- run "npm run build" to update the assets