base-api-scramble-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -0
- package/docs/AI-GUIDE-COMPLETE.md +372 -0
- package/docs/EXCEL-EXPORT-SERVICE.md +349 -0
- package/docs/EXPORT-DATA-PROVIDERS.md +340 -0
- package/docs/EXPORT-TEMPLATES.md +459 -0
- package/docs/LARAVEL-API-TEST.md +355 -0
- package/docs/MAKE-EXPORT-EXCEL-COMMAND.md +215 -0
- package/docs/README.md +678 -0
- package/docs/STRUCTURE.md +540 -0
- package/docs/starting_point.md +423 -0
- package/index.js +968 -0
- package/package.json +17 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
# Starting Point - Base API Scramble
|
|
2
|
+
|
|
3
|
+
> Kickoff guide untuk clone base project dan memulai development baru.
|
|
4
|
+
> Optimized agar AI (Claude, Cursor, dll) langsung paham arsitektur dan konvensi project.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Quick Start (5 Menit)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# 1. Clone & masuk
|
|
12
|
+
git clone <repo-url> nama-project
|
|
13
|
+
cd nama-project
|
|
14
|
+
|
|
15
|
+
# 2. Install dependencies
|
|
16
|
+
composer install
|
|
17
|
+
|
|
18
|
+
# 3. Setup environment
|
|
19
|
+
cp .env.example .env
|
|
20
|
+
php artisan key:generate
|
|
21
|
+
|
|
22
|
+
# 4. Konfigurasi database di .env
|
|
23
|
+
DB_CONNECTION=mysql
|
|
24
|
+
DB_HOST=127.0.0.1
|
|
25
|
+
DB_PORT=3306
|
|
26
|
+
DB_DATABASE=nama_database
|
|
27
|
+
DB_USERNAME=root
|
|
28
|
+
DB_PASSWORD=
|
|
29
|
+
|
|
30
|
+
# 5. Migrasi & seed
|
|
31
|
+
php artisan migrate
|
|
32
|
+
php artisan db:seed
|
|
33
|
+
|
|
34
|
+
# 6. Jalankan server
|
|
35
|
+
php artisan serve
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Default Login:**
|
|
39
|
+
| Email | Password |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `admin@gmail.com` | `password` |
|
|
42
|
+
| `dev@gotrasoft.com` | `gotradev` |
|
|
43
|
+
|
|
44
|
+
**Base URL:** `http://localhost:8000/api/v1`
|
|
45
|
+
**API Docs:** `http://localhost:8000/docs/api` (Scramble)
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Tech Stack
|
|
50
|
+
|
|
51
|
+
| Komponen | Package | Versi |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| Framework | Laravel | ^10.10 |
|
|
54
|
+
| PHP | | ^8.1 |
|
|
55
|
+
| Auth | Laravel Sanctum | ^3.3 |
|
|
56
|
+
| API Docs | Scramble (auto-docs) | ^1.0 |
|
|
57
|
+
| Query Builder | Spatie Query Builder | ^6.3 |
|
|
58
|
+
| Role & Permission | Spatie Permission | ^6.13 |
|
|
59
|
+
| Activity Log | Spatie Activity Log | ^4.9 |
|
|
60
|
+
| Excel Export | PhpSpreadsheet | ^5.4 |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Arsitektur & Pola Utama
|
|
65
|
+
|
|
66
|
+
### Flow Request
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Request → Route → FormRequest (validasi) → Controller → Query/Model → Response (ApiResponse trait)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Struktur Direktori Penting
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
app/
|
|
76
|
+
├── Console/Commands/
|
|
77
|
+
│ ├── GC.php # CRUD Generator (artisan gc)
|
|
78
|
+
│ └── GCFromMigration.php # Generate dari migration existing
|
|
79
|
+
├── Exports/ # Excel export system
|
|
80
|
+
│ ├── BaseExport.php # Abstract base export
|
|
81
|
+
│ └── ...DataProvider.php # Interface-based data providers
|
|
82
|
+
├── Helpers/
|
|
83
|
+
│ ├── ApiResponse.php # Trait: responseSuccess/Data/Created/Deleted/Error
|
|
84
|
+
│ └── FileManagerHelper.php # File management utilities
|
|
85
|
+
├── Http/
|
|
86
|
+
│ ├── Controllers/Api/V1/ # Semua controller API v1
|
|
87
|
+
│ ├── Middleware/ # Standard Laravel middleware
|
|
88
|
+
│ └── Requests/Api/V1/ # Form Request validasi per-endpoint
|
|
89
|
+
├── Models/ # Eloquent models (semua pakai UUID + Queryable trait)
|
|
90
|
+
├── Observers/ # Activity log observers (User, Role, Permission)
|
|
91
|
+
├── Queries/ # Query classes (Spatie QueryBuilder)
|
|
92
|
+
├── Services/ # Business logic (FileService, Payment gateways)
|
|
93
|
+
└── Traits/
|
|
94
|
+
└── Queryable.php # Trait utama: filter, sort, search, include
|
|
95
|
+
|
|
96
|
+
routes/
|
|
97
|
+
├── api.php # Base API routing
|
|
98
|
+
└── api_v1.php # Semua route v1 (prefix /api/v1)
|
|
99
|
+
|
|
100
|
+
config/
|
|
101
|
+
├── export_info.php # Custom: konfigurasi Excel export
|
|
102
|
+
├── services.php # Payment gateway credentials (Midtrans, Xendit, PayPal, Doku)
|
|
103
|
+
└── ... # Standard Laravel configs
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Konvensi & Pattern Wajib
|
|
109
|
+
|
|
110
|
+
### 1. Model
|
|
111
|
+
|
|
112
|
+
Semua model **WAJIB** menggunakan:
|
|
113
|
+
- `HasUuids` trait (UUID sebagai primary key, BUKAN auto-increment)
|
|
114
|
+
- `Queryable` trait (integrasi Spatie QueryBuilder)
|
|
115
|
+
|
|
116
|
+
```php
|
|
117
|
+
use App\Traits\Queryable;
|
|
118
|
+
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
|
119
|
+
|
|
120
|
+
class NamaModel extends Model
|
|
121
|
+
{
|
|
122
|
+
use HasFactory, HasUuids, Queryable;
|
|
123
|
+
|
|
124
|
+
protected $fillable = ['field1', 'field2'];
|
|
125
|
+
|
|
126
|
+
// Opsional: kolom yang bisa di-search via ?search=keyword
|
|
127
|
+
protected $searchable = ['field1', 'field2'];
|
|
128
|
+
|
|
129
|
+
// Opsional: relasi yang bisa di-include via ?include=relation
|
|
130
|
+
protected $relationIncludes = ['relation1', 'relation2'];
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 2. Migration
|
|
135
|
+
|
|
136
|
+
Semua migration menggunakan **UUID primary key**:
|
|
137
|
+
|
|
138
|
+
```php
|
|
139
|
+
Schema::create('table_name', function (Blueprint $table) {
|
|
140
|
+
$table->uuid('id')->primary();
|
|
141
|
+
// ... kolom lain
|
|
142
|
+
$table->foreignUuid('parent_id')->constrained('parents')->cascadeOnDelete(); // foreign key
|
|
143
|
+
$table->timestamps();
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 3. Query Class
|
|
148
|
+
|
|
149
|
+
Setiap model punya Query class di `app/Queries/`:
|
|
150
|
+
|
|
151
|
+
```php
|
|
152
|
+
namespace App\Queries;
|
|
153
|
+
|
|
154
|
+
use App\Models\NamaModel;
|
|
155
|
+
use Spatie\QueryBuilder\AllowedFilter;
|
|
156
|
+
use Spatie\QueryBuilder\AllowedInclude;
|
|
157
|
+
use Spatie\QueryBuilder\QueryBuilder;
|
|
158
|
+
|
|
159
|
+
class NamaModelQuery extends QueryBuilder
|
|
160
|
+
{
|
|
161
|
+
public function __construct()
|
|
162
|
+
{
|
|
163
|
+
parent::__construct(NamaModel::query());
|
|
164
|
+
|
|
165
|
+
$this
|
|
166
|
+
->allowedIncludes([
|
|
167
|
+
AllowedInclude::relationship('relation1'),
|
|
168
|
+
])
|
|
169
|
+
->allowedFilters([
|
|
170
|
+
AllowedFilter::exact('id'),
|
|
171
|
+
AllowedFilter::partial('name'),
|
|
172
|
+
AllowedFilter::exact('foreign_id'),
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 4. Controller
|
|
179
|
+
|
|
180
|
+
Extends `Controller` (sudah include `ApiResponse` trait + `baseQuery()` method):
|
|
181
|
+
|
|
182
|
+
```php
|
|
183
|
+
namespace App\Http\Controllers\Api\V1;
|
|
184
|
+
|
|
185
|
+
use App\Http\Controllers\Controller;
|
|
186
|
+
use App\Models\NamaModel;
|
|
187
|
+
use App\Queries\NamaModelQuery;
|
|
188
|
+
use App\Http\Requests\Api\V1\IndexRequest;
|
|
189
|
+
use App\Http\Requests\Api\V1\NamaModelStoreRequest;
|
|
190
|
+
use App\Http\Requests\Api\V1\NamaModelUpdateRequest;
|
|
191
|
+
|
|
192
|
+
class NamaModelController extends Controller
|
|
193
|
+
{
|
|
194
|
+
public function index(IndexRequest $request)
|
|
195
|
+
{
|
|
196
|
+
$query = new NamaModelQuery();
|
|
197
|
+
return $this->responseData($this->baseQuery($query, $request), 'NamaModel retrieved successfully');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public function show(string $id)
|
|
201
|
+
{
|
|
202
|
+
$query = new NamaModelQuery();
|
|
203
|
+
return $this->responseSuccess($query->findOrFail($id), 'NamaModel retrieved successfully');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
public function store(NamaModelStoreRequest $request)
|
|
207
|
+
{
|
|
208
|
+
$data = $request->validated();
|
|
209
|
+
$model = NamaModel::create($data);
|
|
210
|
+
return $this->responseSuccess($model, 'NamaModel created successfully', 201);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
public function update(NamaModelUpdateRequest $request, NamaModel $namaModel)
|
|
214
|
+
{
|
|
215
|
+
$data = array_filter($request->validated(), fn($v) => $v !== null);
|
|
216
|
+
$namaModel->update($data);
|
|
217
|
+
return $this->responseSuccess($namaModel, 'NamaModel updated successfully');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
public function destroy(NamaModel $namaModel)
|
|
221
|
+
{
|
|
222
|
+
$namaModel->delete();
|
|
223
|
+
return $this->responseSuccess(null, 'NamaModel deleted successfully');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### 5. Form Request
|
|
229
|
+
|
|
230
|
+
```php
|
|
231
|
+
namespace App\Http\Requests\Api\V1;
|
|
232
|
+
|
|
233
|
+
use Illuminate\Foundation\Http\FormRequest;
|
|
234
|
+
|
|
235
|
+
class NamaModelStoreRequest extends FormRequest
|
|
236
|
+
{
|
|
237
|
+
public function authorize(): bool
|
|
238
|
+
{
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public function rules(): array
|
|
243
|
+
{
|
|
244
|
+
return [
|
|
245
|
+
/** @example John Doe */
|
|
246
|
+
'name' => 'required|string|max:255',
|
|
247
|
+
/** @example john@example.com */
|
|
248
|
+
'email' => 'required|email|unique:App\Models\NamaModel,email',
|
|
249
|
+
];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
> Gunakan PHPDoc `@example` pada setiap rule agar Scramble auto-generate contoh di API docs.
|
|
255
|
+
|
|
256
|
+
### 6. Route
|
|
257
|
+
|
|
258
|
+
Tambahkan di `routes/api_v1.php` di dalam group `auth:sanctum`:
|
|
259
|
+
|
|
260
|
+
```php
|
|
261
|
+
Route::apiResource('nama-model', Controllers\NamaModelController::class);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### 7. API Response Format
|
|
265
|
+
|
|
266
|
+
Semua response menggunakan format konsisten via `ApiResponse` trait:
|
|
267
|
+
|
|
268
|
+
**Success:**
|
|
269
|
+
```json
|
|
270
|
+
{ "success": true, "message": "...", "code": 200, "data": { } }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Paginated:**
|
|
274
|
+
```json
|
|
275
|
+
{ "success": true, "message": "...", "code": 200, "data": [], "pagination": { "current_page": 1, "total": 50, "per_page": 10, "last_page": 5, "..." : "..." } }
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Error:**
|
|
279
|
+
```json
|
|
280
|
+
{ "success": false, "message": "...", "code": 400 }
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Query Parameters (Built-in)
|
|
286
|
+
|
|
287
|
+
Semua endpoint `index` otomatis support:
|
|
288
|
+
|
|
289
|
+
| Parameter | Contoh | Keterangan |
|
|
290
|
+
|---|---|---|
|
|
291
|
+
| `search` | `?search=keyword` | Full-text search di kolom `$searchable` |
|
|
292
|
+
| `filter` | `?filter[name]=john&filter[status]=active` | Filter per kolom |
|
|
293
|
+
| `sort_by` | `?sort_by=name&sort_order=asc` | Sorting (default: `created_at` desc) |
|
|
294
|
+
| `include` | `?include=roles,permissions` | Eager load relasi |
|
|
295
|
+
| `paginate` | `?paginate=20&page=2` | Pagination (default: 10) |
|
|
296
|
+
| `paginate=false` | `?paginate=false` | Ambil semua tanpa pagination |
|
|
297
|
+
| `first` | `?first=true` | Ambil hanya 1 data pertama |
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## CRUD Generator (Artisan GC)
|
|
302
|
+
|
|
303
|
+
Generate module lengkap (Migration + Model + Query + Controller + Requests + Route) dalam 1 command:
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
# Basic
|
|
307
|
+
php artisan gc Product --fields="name:string,price:decimal,description:text"
|
|
308
|
+
|
|
309
|
+
# Dengan relasi
|
|
310
|
+
php artisan gc Product --fields="name:string,price:decimal,image:file" --belongsTo="Category,User" --hasMany="Review"
|
|
311
|
+
|
|
312
|
+
# Preview dulu sebelum generate
|
|
313
|
+
php artisan gc Product --fields="name:string,price:decimal" --preview
|
|
314
|
+
|
|
315
|
+
# Lihat migration text saja
|
|
316
|
+
php artisan gc Product --fields="name:string,price:decimal" --migration
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Field types:** `string`, `text`, `integer`/`int`, `decimal`/`float`, `boolean`/`bool`, `date`, `datetime`, `file`/`image`
|
|
320
|
+
|
|
321
|
+
**Setelah generate:**
|
|
322
|
+
```bash
|
|
323
|
+
php artisan migrate
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Generate dari Migration Existing
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
php artisan gc:from-migration
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Fitur Bawaan yang Sudah Tersedia
|
|
335
|
+
|
|
336
|
+
### Authentication (Sanctum)
|
|
337
|
+
- `POST /api/v1/login` - Login, dapat token
|
|
338
|
+
- `POST /api/v1/logout` - Logout (auth required)
|
|
339
|
+
- `GET /api/v1/me` - Profile user login
|
|
340
|
+
- `PUT /api/v1/me` - Update profile
|
|
341
|
+
- `PUT /api/v1/change-password` - Ganti password
|
|
342
|
+
|
|
343
|
+
### Role & Permission (Spatie)
|
|
344
|
+
- CRUD Role: `/api/v1/role`
|
|
345
|
+
- CRUD Permission: `/api/v1/permission`
|
|
346
|
+
- Assign: `/api/v1/user-role/attach`, `detach`, `sync-roles`, `sync-users`
|
|
347
|
+
- Assign: `/api/v1/role-permission/attach`, `detach`, `sync-permissions`, `sync-roles`
|
|
348
|
+
|
|
349
|
+
### File Management
|
|
350
|
+
- CRUD File & Folder dengan soft-delete, restore, force-delete
|
|
351
|
+
- Upload dengan auto-compression (Imagick)
|
|
352
|
+
- Support S3 dan local disk
|
|
353
|
+
|
|
354
|
+
### Excel Export
|
|
355
|
+
- Flexible, Multi-Sheet, Multi-Table template
|
|
356
|
+
- Data Provider pattern (interface-based)
|
|
357
|
+
- Custom styling via `config/export_info.php`
|
|
358
|
+
|
|
359
|
+
### Activity Log
|
|
360
|
+
- Auto-log perubahan via Observers (User, Role, Permission)
|
|
361
|
+
- `GET /api/v1/log-activity` - Lihat semua log
|
|
362
|
+
|
|
363
|
+
### Payment Gateways
|
|
364
|
+
- Midtrans, Xendit, PayPal, Doku (service classes tersedia di `app/Services/`)
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Langkah Memulai Project Baru
|
|
369
|
+
|
|
370
|
+
### Checklist Setup
|
|
371
|
+
|
|
372
|
+
1. **Clone & install** (lihat Quick Start di atas)
|
|
373
|
+
2. **Update `.env`:**
|
|
374
|
+
- `APP_NAME` - Nama project
|
|
375
|
+
- `APP_URL` - URL production
|
|
376
|
+
- `DB_DATABASE` - Nama database
|
|
377
|
+
3. **Hapus module contoh** (opsional):
|
|
378
|
+
- Hapus migration, model, controller, query, request untuk: `Post`, `Label`, `Folder`, `File` jika tidak dibutuhkan
|
|
379
|
+
4. **Buat module baru** via `php artisan gc NamaModule --fields="..."`
|
|
380
|
+
5. **Jalankan** `php artisan migrate`
|
|
381
|
+
6. **Test** via Scramble docs di `/docs/api`
|
|
382
|
+
|
|
383
|
+
### Instruksi untuk AI
|
|
384
|
+
|
|
385
|
+
Saat meminta AI membuat fitur baru, gunakan prompt seperti ini:
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
Buatkan module [NamaModule] dengan fields: [daftar fields].
|
|
389
|
+
Ikuti pattern yang ada di project ini:
|
|
390
|
+
- Model: UUID + Queryable trait
|
|
391
|
+
- Query class di app/Queries/
|
|
392
|
+
- Controller extends Controller (gunakan baseQuery + ApiResponse)
|
|
393
|
+
- FormRequest dengan @example untuk Scramble docs
|
|
394
|
+
- Route di routes/api_v1.php dalam group auth:sanctum
|
|
395
|
+
- Migration dengan uuid('id')->primary()
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Atau lebih simpel, gunakan artisan gc dulu lalu minta AI untuk menyesuaikan:
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
Jalankan: php artisan gc Product --fields="name:string,price:decimal" --belongsTo="Category"
|
|
402
|
+
Lalu sesuaikan validasi dan business logic-nya.
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Referensi File Penting
|
|
408
|
+
|
|
409
|
+
| Kebutuhan | File |
|
|
410
|
+
|---|---|
|
|
411
|
+
| Response format | `app/Helpers/ApiResponse.php` |
|
|
412
|
+
| Base controller | `app/Http/Controllers/Controller.php` |
|
|
413
|
+
| Queryable trait | `app/Traits/Queryable.php` |
|
|
414
|
+
| Contoh controller | `app/Http/Controllers/Api/V1/UserController.php` |
|
|
415
|
+
| Contoh query | `app/Queries/UserQuery.php` |
|
|
416
|
+
| Contoh model | `app/Models/User.php` |
|
|
417
|
+
| Contoh request | `app/Http/Requests/Api/V1/UserStoreRequest.php` |
|
|
418
|
+
| Route API v1 | `routes/api_v1.php` |
|
|
419
|
+
| CRUD generator | `app/Console/Commands/GC.php` |
|
|
420
|
+
| File upload service | `app/Services/FileService.php` |
|
|
421
|
+
| Excel export service | `app/Services/ExcelExportService.php` |
|
|
422
|
+
| Export config | `config/export_info.php` |
|
|
423
|
+
| Payment services | `app/Services/{Midtrans,Xendit,PayPal,Doku}/` |
|