# CLAUDE.md — DLink Service Migration Project

## Project Overview

This is a **Yii 1.1 → Yii 2 migration** of "Cumulus ERP", a D-Link RMA (Return Merchandise Authorization) and service management system. Both old and new projects share the same MySQL database (`dlinkmea_rma_service`).

- **Migration source:** `old_project/` (Yii 1.1, PHP 5.x era)
- **Migration target:** this directory (Yii 2 Advanced Template, PHP ≥ 8.2)

---

## Project Structure

```
dlinkservice/
├── backend/          # Admin application (maps to old_project/administrator.php)
├── frontend/         # Public application (maps to old_project/index.php)
├── common/           # Shared models, config, mail templates
├── console/          # CLI commands & database migrations
├── environments/     # dev / prod config overrides
├── vendor/           # Composer dependencies
└── old_project/      # Legacy Yii 1.1 source (read-only reference)
```

---

## Tech Stack

| Layer | Technology |
|-------|------------|
| Framework | Yii 2 Advanced Template (yiisoft/yii2 ~2.0.54) |
| PHP | >= 8.2 |
| Database | MySQL — `dlinkmea_rma_service` (host: localhost, user: root, no password) |
| Table prefix | `srv_` (inherited from old project) |
| Backend UI | AdminLTE 3.2, Bootstrap 4 (CDN — do NOT use Bootstrap 5) |
| Frontend UI | Bootstrap 4 / Yii2 default |
| Mail | yii2-symfonymailer |
| Testing | Codeception 5, PHPStan 2.1 |
| Asset management | Yii2 Asset Bundles |

---

## Database

- **DB name:** `dlinkmea_rma_service`
- **Config:** `common/config/main.php`
- **Table prefix:** `srv_` — all tables are prefixed; use `{{%table_name}}` in migrations and queries
- The old and new apps **share the exact same database — NEVER alter, add, or remove tables or columns**
- No database migrations should be written or run during this migration; the schema is fixed

---

## Old Project Reference (`old_project/`)

The legacy Yii 1.1 app lives at `old_project/`. Use it as the authoritative reference for business logic, SQL schema, and feature behaviour. Do not modify files inside `old_project/`.

### Entry points (old → new mapping)

| Old entry point | Maps to |
|-----------------|---------|
| `administrator.php` | `backend/` |
| `index.php` | `frontend/` |
| `register.php` | `frontend/` (registration flow) |

### Key feature areas to migrate

| Feature | Old controllers/modules | Notes |
|---------|------------------------|-------|
| RMA management | `protected/modules/rma/` | Core module |
| Customer management | `protected/controllers/admin/CustomerController.php` | |
| Dashboard | `protected/controllers/admin/DashboardController.php` | |
| Reports | `protected/controllers/admin/ReportsController.php` | Excel + PDF export |
| QR Code | `protected/controllers/admin/QRCode*.php` | Bulk upload & verification |
| Job / Activity tracking | `protected/modules/` (Activity module) | |
| User / Auth | `protected/controllers/admin/UserController.php` | Role-based, Google 2FA |
| Frontend portal | `protected/controllers/front/` (8 controllers) | Customer-facing |

### Old models (30+ ActiveRecord classes)

Location: `old_project/protected/models/` — includes `User`, `LoginForm`, `MasCompany`, `MasRegion`, `ProductRegistration`, `RmaSupportProductDetails`, and others.

### Old config reference

`old_project/protected/config/main.php` — contains SMTP settings, DB config, component definitions, and encryption config (AES-256-CBC).

---

## Backend (Admin) Guidelines

- UI framework: **AdminLTE 3.2** with **Bootstrap 4** — never introduce Bootstrap 5 components
- Assets registered in `backend/assets/AppAsset.php` and `backend/assets/AdminLTEAsset.php`
- Layout: `backend/views/layouts/main.php`
- Controllers extend `backend\controllers\BaseController` (or `yii\web\Controller`)
- URL manager configured for clean URLs

## Frontend Guidelines

- Public-facing application
- Bootstrap 4 (consistent with backend)
- Layout: `frontend/views/layouts/main.php`

---

## Common / Shared Code

- **Models:** `common/models/` — place AR models used by both backend and frontend here
- **Config:** `common/config/main.php` (shared), `main-local.php` (local overrides, not committed)
- **Mail templates:** `common/mail/`

---

## Console / Migrations

- Run migrations: `php yii migrate`
- Create migration: `php yii migrate/create <name>`
- Migrations live in `console/migrations/`
- Always use `{{%table_name}}` syntax (respects table prefix)

---

## Development Commands

```powershell
# Run backend dev server
php -S localhost:8080 -t backend/web

# Run frontend dev server
php -S localhost:8081 -t frontend/web

# Yii console (Windows)
yii.bat <command>

# Run migrations
php yii migrate

# Run tests
php vendor/bin/codecept run
```

---

## Migration Workflow

When migrating a feature from `old_project/` to the new Yii2 app:

1. Read the old controller(s) and model(s) in `old_project/protected/` to understand the full business logic
2. Create the corresponding Yii2 AR model in `common/models/` (same table, `tableName()` returns `'{{%table_name}}'`)
3. Create the controller in `backend/controllers/` or `frontend/controllers/`
4. Build views using AdminLTE 3.2 components (backend) or Bootstrap 4 (frontend)
5. Register routes in the relevant `config/main.php` `urlManager` if needed

> **NEVER create database migrations.** The database is shared with the old app and must not change.

---

## JavaScript Migration Rules

### Legacy jQuery Selectors — ID Format Change

Yii 1.1 generated HTML element IDs in `ModelName_attributeName` format (PascalCase model, camelCase attribute, joined by underscore). Yii 2 generates them in `modelname-attributename` format (all lowercase, hyphen-separated).

Any JavaScript copied or ported from the old project **must** have its selectors rewritten:

| Old Yii 1.1 (do NOT use) | New Yii 2 (correct) |
|--------------------------|---------------------|
| `#ModelName_attributeName` | `#modelname-attributename` |
| `#User_firstName` | `#user-firstname` |
| `#RmaJob_serial_no` | `#rmajob-serial_no` |
| `#LoginForm_password` | `#loginform-password` |

**Rule:** strip the old ID, lowercase the entire string, replace the first `_` (between model and attribute) with `-`. Attribute-internal underscores stay as-is.

```js
// WRONG — Yii 1 style
$('#RmaJob_serial_no').val();
$('#User_rma_company_id').on('change', fn);

// CORRECT — Yii 2 style
$('#rmajob-serial_no').val();
$('#user-rma_company_id').on('change', fn);
```

This applies everywhere: inline `<script>` blocks in views, external `.js` files, Ajax callbacks, and any `yii\widgets\ActiveForm` field references. Always verify generated IDs by inspecting the rendered HTML before writing selectors.

---

## Key Conventions

- Models in `common/models/` are shared; backend/frontend-only models go in their respective `models/` folder
- Use Yii2 ActiveRecord, not raw SQL, unless performance requires it
- Form models (non-AR) live alongside the controller that uses them, or in `models/` of that app
- Gii is available for scaffolding models and CRUD in dev mode
- Do not commit `common/config/main-local.php` or `backend/config/main-local.php` (gitignored)
- **Model names must match the old project exactly** — never rename a model class during migration (e.g. old `LoginForm` stays `LoginForm`, old `RmaJob` stays `RmaJob`). Only the namespace changes.
