# Contributing to Web Dolphin Japan

Thank you for contributing to the Web Dolphin Japan project! This guide will help you understand our development workflow and standards.

> **Backend API-Only Project:** This is a REST API server. All contributions should focus on backend development only.

## Code of Conduct

- Be respectful and professional
- Focus on code quality and maintainability
- Help other team members succeed
- Follow the established patterns and conventions

## Getting Started

1. **Fork & Clone**
   ```bash
   git clone https://github.com/yourusername/web-dolphin-japan.git
   cd web-dolphin-japan
   ```

2. **Follow Setup Guide**
   - See [SETUP.md](SETUP.md) for detailed installation instructions
   - Or run: `composer run setup`

3. **Create Feature Branch**
   ```bash
   git checkout -b feature/your-feature-name
   ```

## Development Workflow

### 1. Before You Start

- Check existing issues and PRs to avoid duplication
- Discuss major changes with the team first
- Review the [AGENTS.md](AGENTS.md) architecture guide

### 2. Making Changes

Follow the **3-Layer Architecture** for new features:

```
Controller → Service → Repository → Model
```

**Example:** Creating a new `Category` endpoint

#### Step 1: Database Migration
```bash
php artisan make:migration create_categories_table
```

Edit `database/migrations/2026_xx_xx_xxxxxx_create_categories_table.php`:
```php
Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->string('name', 100)->unique();
    $table->text('description')->nullable();
    $table->timestamps();
});
```

#### Step 2: Create Model
File: `app/Models/Category.php`
```php
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $fillable = ['name', 'description'];
}
```

#### Step 3: Create Repository
File: `app/Http/Repository/CategoryRepository.php`
```php
<?php
namespace App\Http\Repository;

class CategoryRepository extends CommonRepository
{
    public static function getAllCategories()
    {
        return Category::all();
    }

    public static function addCategory($data)
    {
        return Category::create($data);
    }
}
```

#### Step 4: Create Service
File: `app/Http/Service/CategoryService.php`
```php
<?php
namespace App\Http\Service;

use App\Traits\RespondsWithHttpStatus;
use App\Http\Repository\CategoryRepository;

class CategoryService
{
    use RespondsWithHttpStatus;

    public function index()
    {
        $data = CategoryRepository::getAllCategories();
        return $this->sendResponse($data, 'Categories retrieved successfully');
    }

    public function add($request)
    {
        $data = CategoryRepository::addCategory($request->validated());
        return $this->sendResponse($data, 'Category created successfully');
    }
}
```

#### Step 5: Create Request Validation
File: `app/Http/Requests/CategoryRequest.php`
```php
<?php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CategoryRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true; // Implement your auth logic
    }

    public function rules(): array
    {
        return [
            'name' => 'required|string|max:100|unique:categories',
            'description' => 'nullable|string|max:1000',
        ];
    }
}
```

#### Step 6: Create Resource (JSON Transformation)
File: `app/Http/Resources/CategoryResource.php`
```php
<?php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class CategoryResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'created_at' => $this->created_at->format('Y-m-d H:i:s'),
        ];
    }
}
```

#### Step 7: Create Controller
File: `app/Http/Controllers/Admin/CategoryController.php`
```php
<?php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\CategoryRequest;
use App\Http\Service\CategoryService;

class CategoryController extends Controller
{
    public function __construct(private CategoryService $categoryService) {}

    public function index()
    {
        return $this->categoryService->index();
    }

    public function add(CategoryRequest $request)
    {
        return $this->categoryService->add($request);
    }
}
```

#### Step 8: Add Routes
File: `routes/web.php`
```php
Route::group(['prefix' => 'api/v1'], function () {
    Route::group(['prefix' => 'category'], function () {
        Route::get('/', [CategoryController::class, 'index']);
        Route::post('/add', [CategoryController::class, 'add']);
    });
});
```

### 3. Code Standards

#### PSR-12 Formatting

```bash
# Check code style
./vendor/bin/pint --test

# Auto-fix code style
./vendor/bin/pint
```

#### Naming Conventions

| Component | Pattern | Example |
|-----------|---------|---------|
| Controllers | `{Entity}Controller` | `CategoryController` |
| Services | `{Entity}Service` | `CategoryService` |
| Repositories | `{Entity}Repository` | `CategoryRepository` |
| Models | Singular, PascalCase | `Category` |
| Requests | `{Entity}Request` | `CategoryRequest` |
| Resources | `{Entity}Resource` | `CategoryResource` |
| Routes | Lowercase, plural | `/api/v1/category/` |
| Methods | camelCase | `getAllCategories()` |

#### Comments & Documentation

```php
/**
 * Retrieve all categories with pagination
 * 
 * @return \Illuminate\Pagination\LengthAwarePaginator
 */
public function index()
{
    // Implementation
}
```

### 4. Testing Your Code

#### Write Tests

Create tests in `tests/Feature/` for API endpoints:

```bash
php artisan make:test CategoryTest --feature
```

File: `tests/Feature/CategoryTest.php`
```php
<?php
namespace Tests\Feature;

use Tests\TestCase;

class CategoryTest extends TestCase
{
    public function test_can_get_all_categories()
    {
        $response = $this->getJson('/api/v1/category/');
        $response->assertStatus(200);
        $response->assertJsonStructure(['code', 'hasError', 'result']);
    }

    public function test_can_create_category()
    {
        $response = $this->postJson('/api/v1/category/add', [
            'name' => 'Electronics',
            'description' => 'Electronic items',
        ]);

        $response->assertStatus(200);
        $this->assertDatabaseHas('categories', ['name' => 'Electronics']);
    }
}
```

#### Run Tests

```bash
# Run all tests
composer run test

# Run specific test
php artisan test tests/Feature/CategoryTest.php

# Run with coverage
php artisan test --coverage
```

### 5. Database Migrations

**Important:** Always create migrations for database changes.

```bash
# Create migration
php artisan make:migration create_table_name

# Run migrations
php artisan migrate

# Rollback last migration
php artisan migrate:rollback

# Reset all migrations
php artisan migrate:fresh
```

### 6. Git Workflow

```bash
# 1. Create feature branch
git checkout -b feature/category-management

# 2. Make changes and commit
git add .
git commit -m "Add category management feature

- Create Category model
- Add CategoryRepository with CRUD operations
- Implement CategoryService for business logic
- Create CategoryController endpoints
- Add API tests"

# 3. Push branch
git push origin feature/category-management

# 4. Create Pull Request on GitHub
# - Describe changes clearly
# - Reference related issues (#123)
# - Request reviews from team members

# 5. After approval, merge to main
# (Team lead will handle merge)
```

#### Commit Message Guidelines

Use clear, descriptive commit messages:

```
Format: [Type] Short description

Types:
- feat: New feature
- fix: Bug fix
- refactor: Code refactoring
- test: Adding or updating tests
- docs: Documentation updates
- style: Code style changes
- chore: Maintenance tasks

Examples:
✅ feat: Add category management endpoints
✅ fix: Resolve brand image upload issue
✅ refactor: Simplify BrandService logic
❌ update stuff
❌ fixed
❌ changes
```

## Pull Request Process

### Before Submitting

- [ ] Tests pass: `composer run test`
- [ ] Code formatted: `./vendor/bin/pint`
- [ ] Follow 3-layer architecture
- [ ] Updated documentation if needed
- [ ] No console.log() or var_dump() left in code
- [ ] Database migrations included

### PR Template

```markdown
## Description
Brief description of changes

## Related Issue
Fixes #123

## Changes Made
- Change 1
- Change 2
- Change 3

## How to Test
1. Step 1
2. Step 2
3. Expected result

## Screenshots (if applicable)
[Insert images here]

## Checklist
- [ ] Tests added/updated
- [ ] Code formatted
- [ ] Documentation updated
```

## Code Review Checklist

Reviewers should verify:

- [ ] Follows 3-layer architecture
- [ ] All layers implemented (Controller, Service, Repository)
- [ ] Proper error handling
- [ ] Input validation in Request class
- [ ] Database migrations included
- [ ] Tests provide good coverage
- [ ] Code style is consistent (PSR-12)
- [ ] Documentation is clear
- [ ] No breaking changes

## Debugging Tips

### Use Laravel Tinker

```bash
php artisan tinker

>>> App\Models\Category::all()
>>> App\Models\Category::create(['name' => 'Test'])
>>> exit
```

### Check Routes

```bash
php artisan route:list
# or filter:
php artisan route:list --name=category
```

### View Logs

```bash
# Real-time logs
php artisan pail

# Historical logs
tail -f storage/logs/laravel.log
```

### Database Inspection

```bash
# For SQLite
sqlite3 database/database.sqlite

# For MySQL
mysql -u root -p web_dolphin_japan
```

## Questions?

- Review [AGENTS.md](AGENTS.md) for architecture guidelines
- Check [README.md](README.md) for project overview
- Review existing features in `app/Http/Controllers/Admin/`
- Ask team members in discussions

---

**Thank you for contributing to Web Dolphin Japan!** 🎉

Last Updated: May 5, 2026
