Architecture - luckydeva03/desa_karangrejo GitHub Wiki
Arsitektur dan struktur aplikasi Website Desa Karangrejo.
Website Desa Karangrejo dibangun menggunakan arsitektur MVC (Model-View-Controller) dengan Laravel 12 framework, mengikuti best practices dan design patterns modern.
┌─────────────────────────────────────────────────────────────┐
│ Presentation Layer │
├─────────────────────────────────────────────────────────────┤
│ Frontend (Blade + Tailwind) │ Admin Panel (Blade + JS) │
│ - Public Website │ - Dashboard │
│ - Responsive Design │ - Content Management │
│ - SEO Optimized │ - User Management │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────────────────────────┤
│ Laravel Controllers │
│ - Frontend Controllers │ - Admin Controllers │
│ - API Controllers │ - Auth Controllers │
│ - Resource Controllers │ - CRUD Operations │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Business Logic Layer │
├─────────────────────────────────────────────────────────────┤
│ Models & Services │
│ - Eloquent Models │ - Business Services │
│ - Relationships │ - Helper Classes │
│ - Validation Rules │ - Custom Logic │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Data Access Layer │
├─────────────────────────────────────────────────────────────┤
│ Database (MySQL) │ File Storage │
│ - Migrations │ - Local Storage │
│ - Seeders │ - Image Processing │
│ - Indexes │ - Backup System │
└─────────────────────────────────────────────────────────────┘
desa-karangrejo/
├── app/
│ ├── Console/Commands/ # Artisan commands
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── Admin/ # Admin panel controllers
│ │ │ ├── Auth/ # Authentication controllers
│ │ │ └── Frontend/ # Public website controllers
│ │ ├── Middleware/ # Custom middleware
│ │ └── Requests/ # Form requests & validation
│ ├── Models/ # Eloquent models
│ ├── Helpers/ # Helper classes
│ ├── Notifications/ # Custom notifications
│ ├── Providers/ # Service providers
│ └── View/Components/ # Blade components
├── bootstrap/ # Bootstrap files
├── config/ # Configuration files
├── database/
│ ├── migrations/ # Database migrations
│ ├── seeders/ # Database seeders
│ └── factories/ # Model factories
├── public/ # Public assets
│ ├── css/ # Compiled CSS
│ ├── js/ # Compiled JS
│ └── images/ # Static images
├── resources/
│ ├── css/ # Source CSS (Tailwind)
│ ├── js/ # Source JavaScript
│ └── views/ # Blade templates
│ ├── admin/ # Admin panel views
│ ├── frontend/ # Public website views
│ ├── components/ # Reusable components
│ └── layouts/ # Layout templates
├── routes/ # Route definitions
├── storage/ # Application storage
└── vendor/ # Composer dependencies
// app/Models/Post.php
class Post extends Model
{
use HasFactory, LogsActivity;
protected $fillable = [
'title', 'content', 'excerpt', 'featured_image',
'status', 'category_id', 'user_id'
];
// Relationships
public function category() {
return $this->belongsTo(Category::class);
}
public function user() {
return $this->belongsTo(User::class);
}
// Scopes
public function scopePublished($query) {
return $query->where('status', 'published');
}
}
{{-- resources/views/frontend/posts/index.blade.php --}}
@extends('layouts.frontend')
@section('content')
<div class="container mx-auto px-4">
<h1 class="text-3xl font-bold mb-8">Berita Desa</h1>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@foreach($posts as $post)
<x-post-card :post="$post" />
@endforeach
</div>
{{ $posts->links() }}
</div>
@endsection
// app/Http/Controllers/Frontend/PostController.php
class PostController extends Controller
{
public function index()
{
$posts = Post::published()
->with(['category', 'user'])
->latest()
->paginate(12);
return view('frontend.posts.index', compact('posts'));
}
public function show(Post $post)
{
$relatedPosts = Post::published()
->where('category_id', $post->category_id)
->where('id', '!=', $post->id)
->limit(3)
->get();
return view('frontend.posts.show', compact('post', 'relatedPosts'));
}
}
// Multi-guard authentication
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'users',
],
],
- Spatie Laravel Permission untuk role-based access control
- Hierarchical roles: Super Admin → Admin → Operator → User
- Granular permissions untuk setiap feature
- Spatie Laravel Activitylog untuk audit trail
- Track semua perubahan data penting
- User activity monitoring
- Intervention Image untuk image processing
- Organized storage structure
- Automatic thumbnail generation
- File validation dan security
// app/Http/Requests/PostRequest.php
class PostRequest extends FormRequest
{
public function rules()
{
return [
'title' => 'required|string|max:255',
'content' => 'required|string',
'category_id' => 'required|exists:categories,id',
'featured_image' => 'nullable|image|max:2048',
'status' => 'required|in:draft,published',
];
}
}
- Laravel built-in CSRF protection
- Token verification untuk semua forms
- AJAX request protection
- Blade automatic escaping
- HTMLPurifier untuk rich text content
- Input sanitization
- Eloquent ORM dengan parameter binding
- Query builder yang aman
- No raw queries kecuali necessary
{
"laravel/framework": "^12.0",
"spatie/laravel-permission": "^6.20",
"spatie/laravel-activitylog": "^4.10",
"spatie/laravel-backup": "^9.3",
"intervention/image-laravel": "^1.5",
"laravel/telescope": "^5.10",
"yajra/laravel-datatables-oracle": "^12.4"
}
{
"tailwindcss": "^3.1.0",
"alpinejs": "^3.4.2",
"chart.js": "^4.5.0",
"sweetalert2": "11.4.8",
"swiper": "^11.2.10"
}
User Request → Route → Frontend Controller → Model → Database
↓
View (Blade) ← Controller ← Model ← Database Response
Admin Request → Middleware (Auth + Permission) → Route → Admin Controller
↓
Database ← Model ← Controller (Process + Validate)
↓
Response → Model → Controller → View (Admin Panel) → Admin
API Request → Route (api.php) → API Controller → Model → Database
↓
JSON Response ← Controller ← Model ← Database Response
/* Base styles */
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
/* Custom components */
@layer components {
.btn-primary {
@apply bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700;
}
}
// Alpine.js for interactive components
document.addEventListener('alpine:init', () => {
Alpine.data('dropdown', () => ({
open: false,
toggle() {
this.open = !this.open;
}
}));
});
{{-- Reusable Blade components --}}
<x-card>
<x-slot name="header">{{ $title }}</x-slot>
{{ $content }}
</x-card>
<x-form.input name="title" label="Judul" required />
<x-form.textarea name="content" label="Konten" />
Users ←→ Posts ←→ Categories
↓ ↓
Roles Comments
↓
Permissions
Gallery ←→ Categories
↓
Media Files
Village Data ←→ Data Types
Settings (Key-Value pairs)
Contact Messages
Activity Log
-- Performance indexes
CREATE INDEX idx_posts_status_created ON posts(status, created_at);
CREATE INDEX idx_posts_category ON posts(category_id);
CREATE INDEX idx_gallery_category ON galleries(category_id);
CREATE INDEX idx_activity_log_subject ON activity_log(subject_type, subject_id);
- Query Result Caching untuk data yang jarang berubah
- View Caching untuk compiled blade templates
- Route Caching untuk production
- Config Caching untuk application config
- Proper indexing pada kolom yang sering di-query
- Eager loading untuk relationships
- Query optimization dengan explain plans
- Database connection pooling
- Vite bundling untuk CSS/JS
- Image optimization dengan Intervention Image
- Lazy loading untuk images
- CDN ready structure
Development → Staging → Production
↓ ↓ ↓
Local DB → Test DB → Prod DB
↓ ↓ ↓
Debug ON → Debug OFF → Debug OFF
- PSR-12 coding standards
- PHPStan static analysis
- Laravel Pint code formatting
- Automated testing structure
Architecture mengikuti Laravel best practices dan modern PHP development standards 🏗️