# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview
Enterprise Resource Planning (ERP) system focused on employee management, attendance tracking, and user administration. Built with Laravel 12, Inertia.js v2, Vue 3 (TypeScript), and Tailwind CSS v4.

**App URL:** http://localhost:8000
**Database:** MySQL (erp)
**Current Branch:** dev
**Main Branch:** master

## Development Commands

### Running the Application
```bash
# Start all services (server, queue, logs, vite)
composer run dev

# SSR mode
composer run dev:ssr

# Frontend only
npm run dev

# Build frontend
npm run build
```

### Code Quality
```bash
# Format PHP code (run before finalizing)
vendor/bin/pint --dirty

# Format frontend code
npm run format

# Lint frontend
npm run lint

# Check formatting
npm run format:check
```

### Testing
```bash
# Run all tests
php artisan test --compact

# Run specific test file
php artisan test --compact tests/Feature/UserManagementTest.php

# Filter specific test
php artisan test --compact --filter=testName
```

### Database
```bash
# Run migrations
php artisan migrate

# Rollback
php artisan migrate:rollback

# Fresh migration with seeding
php artisan migrate:fresh --seed
```

## Architecture Overview

### Authentication System
Uses **Laravel Fortify** with these features:
- Login/Logout (registration disabled - admin-only user creation)
- Email verification
- Password reset
- Two-Factor Authentication (2FA) with recovery codes
- Confirm password for sensitive actions

### Authorization Pattern
Custom single-role implementation using Spatie Permissions:
- Each user has **ONE role** via `role_id` foreign key (not polymorphic)
- Custom methods on User model: `hasRole()`, `getRoleNames()`
- Role middleware: `EnsureUserHasRole` (alias: `role`)
- Usage: `Route::middleware(['role:Admin'])->group(...)`

### User Model Extensions
The User model includes several custom features:
- **Employment status tracking** with status history
- **Computed attributes**: `status_days_remaining`, `days_until_increment`
- **Scopes**: `search()` for name/email/emp_no, `sortBy()` with numeric emp_no sorting
- **Status history logging**: `logStatusChange()` method

### Frontend Architecture
- **Inertia.js v2** for SPA experience without building an API
- **Vue 3 with TypeScript** using Composition API
- **Wayfinder** for type-safe routing (no manual URL strings)
- **Reka UI** component library (fork of Radix Vue)
- **Tailwind CSS v4** (CSS-first config via `@theme`, not `tailwind.config.js`)

### Directory Structure
```
app/
├── Actions/                    # Laravel Actions pattern
│   ├── Fortify/               # Fortify action customizations
│   └── ImportAttendanceAction.php
├── Http/
│   ├── Controllers/           # Route controllers
│   │   ├── Settings/          # Settings-related controllers
│   │   ├── UserController.php
│   │   └── AttendanceUploadController.php
│   ├── Middleware/
│   │   ├── EnsureUserHasRole.php  # Custom role middleware
│   │   ├── HandleAppearance.php   # Dark mode persistence
│   │   └── HandleInertiaRequests.php
│   └── Requests/              # Form Request validation
│       ├── Settings/
│       ├── UserStoreRequest.php
│       └── UserUpdateRequest.php
├── Models/
│   ├── User.php               # Extended with employment features
│   ├── UserStatusHistory.php
│   └── AttendanceRecord.php

resources/js/
├── actions/                   # Wayfinder-generated controller mappings
├── routes/                    # Wayfinder-generated named routes
├── pages/                     # Inertia page components
│   ├── auth/                  # Authentication pages
│   ├── settings/              # Settings pages
│   ├── users/                 # User management pages
│   └── attendance/            # Attendance pages
├── components/                # Shared Vue components
│   ├── ui/                    # Reka UI components
│   ├── DataTable.vue          # Reusable table with sorting/filtering
│   ├── UserForm.vue           # Shared form for create/edit
│   └── ...
├── composables/               # Vue composables
│   ├── useAppearance.ts       # Dark mode handling
│   └── useTwoFactorAuth.ts    # 2FA logic
├── layouts/                   # Inertia layouts
└── types/                     # TypeScript types

routes/
├── web.php                    # Main application routes
└── settings.php               # Settings routes (separate file)
```

### Key Middleware Configuration
Middleware configured in `bootstrap/app.php` (Laravel 12 style):
- Web middleware chain includes: `HandleAppearance`, `HandleInertiaRequests`
- Cookies NOT encrypted: `appearance`, `sidebar_state`
- Middleware alias: `role` → `EnsureUserHasRole`

### UI Component System
Built on **Reka UI** (Radix Vue fork) with custom components in `components/ui/`:
- Alert, Avatar, Badge, Button, Card, Checkbox
- Calendar, DatePicker, Dialog, Dropdown, Input
- Label, Select, Switch, Tabs, Toast, etc.

**DataTable Component**: Reusable table with:
- Server-side sorting and filtering
- Column configuration with custom cell rendering
- Pagination support
- Used throughout the app (Users, Attendance, etc.)

### Wayfinder Usage
Type-safe routing - never use URL strings:
```typescript
// Import controller actions
import { store, update } from '@/actions/App/Http/Controllers/UserController'

// Get route object
store() // { url: "/users", method: "post" }

// Use with Inertia Form component
<Form v-bind="store.form()">
```

Run `php artisan wayfinder:generate` after route changes (if Vite plugin isn't active).

### Testing Strategy
- **Pest v4** for all tests
- Feature tests for user flows (Auth, Settings, User Management)
- Always test validation rules, authorization, and database changes
- Use factories for model creation: `User::factory()->create()`
- Run relevant tests after changes, offer to run full suite when done

### Attendance System
Current implementation:
- **Batch uploads** (Excel/CSV) by Admin users
- `AttendanceBatch` and `AttendanceRecord` models
- `ImportAttendanceAction` handles Excel processing
- Basic attendance list view (in development)

## Important Conventions

### Validation
Always use **Form Request classes**, never inline validation:
```php
// UserStoreRequest, UserUpdateRequest, etc.
public function rules(): array { ... }
public function messages(): array { ... }
```

### Eloquent Relationships
Always use proper return type hints:
```php
public function role(): BelongsTo
{
    return $this->belongsTo(Role::class);
}
```

### Vue Component Style
- TypeScript for all new components
- Composition API preferred
- Check sibling files for naming patterns
- Import Wayfinder actions, not manual routes

### CSS Styling
- Use Tailwind utility classes
- Dark mode support via `dark:` prefix
- Gap utilities for spacing (not margins in flex/grid)
- Follow Tailwind v4 syntax (no deprecated utilities)

### File Naming
- Vue pages: lowercase directories (`pages/users/`, `pages/attendance/`)
- Components: PascalCase filenames (`UserForm.vue`, `DataTable.vue`)
- Controllers: PascalCase with `Controller` suffix
- Requests: PascalCase with `Request` suffix

## Current Features & Status

**Completed:**
- Authentication system (Login, 2FA, Email Verification, Password Reset)
- User management CRUD (admin-only creation)
- Single-role authorization system
- Employment status tracking with history
- Attendance batch uploads (admin-only)
- Settings module (Profile, Password, 2FA, Appearance)
- Dashboard (basic implementation)

**In Progress:**
- Attendance tracking and reporting

**Notable Decisions:**
- Public registration disabled (admin-only user creation)
- User profile deletion disabled
- "Users" terminology changed to "Employees" in some UI contexts
- Employee ID (`emp_no`) sortable numerically, not alphabetically

## Database Notes
- Many empty tables related to customs/trade management exist (future integration planned)
- Core tables in active use: users, roles, permissions, attendance_batches, attendance_records, user_status_histories
