@extends('layouts.app') @php $pageTitle = 'Guide'; $pageHeading = 'Guide'; $pageDescription = 'Panduan singkat untuk integrasi API publik dan operasional ADMS.'; @endphp @section('content')

Integrasi API Publik (Tanpa Login)

Endpoint ini dibuat untuk dipanggil aplikasi lain (misalnya tombol "Sync" di aplikasi external) tanpa perlu session login.

Endpoint

Method URL Query Keterangan
GET /api/public/transactions
start_date, end_date (YYYY-MM-DD)
sn, emp_code, limit, after_id
Ambil transaksi attendance dalam range tanggal (termasuk today).
GET /api/public/users
start_date, end_date (YYYY-MM-DD)
emp_code, limit, after_id
Ambil data employee yang berubah pada range tanggal berdasarkan update_time.

API Key (Opsional)

Status API Key: @if (!empty($apiKeyEnabled)) AKTIF (server akan menolak request tanpa key). @else NONAKTIF (endpoint bisa dipanggil tanpa key). @endif
Cara set API key di server
Set environment variable WDMS_PUBLIC_API_KEY di file .env (atau setting environment Windows service).
WDMS_PUBLIC_API_KEY=your-secret-key
Cara pakai API key di client
Pilih salah satu:
1) Header: X-API-KEY
2) Query param: api_key
# Pakai header
curl -H "X-API-KEY: your-secret-key" ^
  "http://localhost:8004/api/public/transactions?start_date=2026-04-01&end_date=2026-04-09"

# Pakai query param
curl "http://localhost:8004/api/public/users?start_date=2026-04-01&end_date=2026-04-09&api_key=your-secret-key"

Contoh Integrasi (Laravel Client App)

Contoh ringkas untuk aplikasi lain yang punya tombol "Sync" untuk tarik data dari WDMS API. Prosedur data besar: split tanggal maksimal 31 hari, lalu paging pakai after_id sampai has_more=false.
ENV di aplikasi client
WDMS_BASE_URL=http://localhost:8004
WDMS_API_KEY=your-secret-key
Route (aplikasi client)
use App\Http\Controllers\WdmsSyncController;

Route::post('/wdms-sync/preview', [WdmsSyncController::class, 'preview']);
Route::post('/wdms-sync/run', [WdmsSyncController::class, 'run']);
Controller Preview (ringkas)
<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class WdmsSyncController extends Controller
{
    public function preview(Request $request)
    {
        $mode = $request->input('mode', 'transactions'); // transactions | users
        $start = Carbon::parse($request->input('start_date'))->startOfDay();
        $end = Carbon::parse($request->input('end_date'))->startOfDay();
        if ($end->lt($start)) { [$start, $end] = [$end, $start]; }

        $baseUrl = rtrim(env('WDMS_BASE_URL', 'http://localhost:8004'), '/');
        $apiKey = (string) env('WDMS_API_KEY', '');
        $endpoint = $mode === 'users' ? '/api/public/users' : '/api/public/transactions';

        $client = Http::timeout(30);
        if ($apiKey !== '') {
            $client = $client->withHeaders(['X-API-KEY' => $apiKey]);
        }

        $chunkDays = 31;
        $total = 0;
        $sample = [];

        for ($cursor = $start->copy(); $cursor->lte($end); $cursor = $cursor->addDays($chunkDays)) {
            $chunkStart = $cursor->copy();
            $chunkEnd = $cursor->copy()->addDays($chunkDays - 1);
            if ($chunkEnd->gt($end)) { $chunkEnd = $end->copy(); }

            $afterId = null;
            do {
                $resp = $client->get($baseUrl . $endpoint, [
                    'start_date' => $chunkStart->toDateString(),
                    'end_date' => $chunkEnd->toDateString(),
                    'limit' => 5000,
                    'after_id' => $afterId,
                ]);

                if (! $resp->ok()) {
                    return response()->json(['ok' => false, 'error' => $resp->body()], 500);
                }

                $json = $resp->json();
                $rows = $json['data'] ?? [];
                $total += count($rows);
                foreach ($rows as $row) {
                    if (count($sample) < 20) { $sample[] = $row; }
                }

                $afterId = $json['next_after_id'] ?? null;
                $hasMore = (bool) ($json['has_more'] ?? false);
            } while ($hasMore && $afterId);
        }

        return response()->json(['ok' => true, 'total' => $total, 'sample' => $sample]);
    }
}

Server Requirement (Ubuntu)

Rekomendasi OS: Ubuntu 22.04 LTS atau Ubuntu 24.04 LTS. Minimal PHP yang didukung di project ini adalah PHP 8.2+ (lihat composer.json).
Minimal Package
Untuk menjalankan Laravel + MySQL + build asset (Vite). Ekstensi php-zip dan php-xml penting untuk fitur import/export XLSX.
sudo apt update

# Web + DB
sudo apt install -y nginx mysql-server

# PHP 8.2+ + ekstensi Laravel umum
sudo apt install -y \
  php php-fpm php-cli php-mysql php-mbstring php-xml php-curl php-zip php-bcmath php-intl

# Tools
sudo apt install -y git unzip zip curl ca-certificates
Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Node.js (Vite)
Untuk build asset, project ini butuh Node.js >= 20.19 (rekomendasi: Node 22 LTS) + npm untuk menjalankan npm install dan npm run build.
# Ubuntu (NodeSource) - install Node 22 LTS
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs

node -v
npm -v
Kalau Node versi lama (misal v18.x), Vite biasanya gagal dengan pesan seperti: Vite requires Node.js version 20.19+ or 22.12+.
Opsional (Queue & Scheduler)
Kalau pakai queue worker jangka panjang, rekomendasi pakai supervisor. Redis opsional.
sudo apt install -y supervisor redis-server

Status Cek Server (Auto)

Checklist otomatis dari server tempat WDMS berjalan. Ini membantu melihat package/extension yang kurang.
@php $missing = collect($systemChecks ?? [])->filter(fn ($row) => empty($row['optional']) && empty($row['ok']))->values(); @endphp
@if ($missing->isEmpty()) Sesuai Semua kebutuhan utama terpenuhi. @else Belum Sesuai Ada {{ $missing->count() }} item yang belum terpenuhi. @endif
@foreach (($systemChecks ?? []) as $row) @endforeach
Status Item Detail Fix
@if (!empty($row['optional'])) Optional @elseif (!empty($row['ok'])) OK @else Missing @endif {{ $row['label'] ?? '-' }} {{ $row['detail'] ?? '-' }} {{ $row['fix'] ?? '-' }}
@if ($missing->isNotEmpty())
Yang Kurang (Wajib)
@foreach ($missing as $row)
{{ $row['label'] ?? '-' }}
{{ $row['fix'] ?? '-' }}
@endforeach
@endif

Deploy & Aktifkan di Ubuntu (Nginx + PHP-FPM)

Contoh prosedur taruh project ke /var/www/html/wdms (default), install dependency, build asset Vite, lalu aktifkan via Nginx. Sesuaikan versi PHP-FPM (Ubuntu 22.04 umumnya php8.2-fpm, Ubuntu 24.04 umumnya php8.3-fpm).
1) Taruh Project
sudo mkdir -p /var/www/wdms
sudo chown -R $USER:$USER /var/www/wdms

# contoh: clone repo (atau copy folder project)
cd /var/www/html/wdms
# git clone <repo_url> .

# masuk ke folder Laravel
cd laravel_app
2) Setup Laravel
composer install --no-dev --optimize-autoloader

cp .env.example .env
php artisan key:generate

# edit .env: APP_URL, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD
php artisan migrate --force
Tips:
1) Jangan jalankan composer sebagai root. Gunakan user biasa (misal mesin24).
2) Kalau composer install gagal karena versi PHP, berarti lock file tidak cocok dengan PHP server. Solusi paling aman: update project ke versi terbaru (pull/replace file) lalu jalankan composer install ulang.
3) Build Asset (Vite)
npm install
npm run build
Kalau muncul error ENOENT ... package.json, berarti kamu menjalankan npm di folder yang salah. Pastikan kamu berada di folder yang ada file package.json (di project ini ada di laravel_app/).
Kalau muncul error engine / native binding (contoh @tailwindcss/oxide) setelah upgrade Node, lakukan clean install:
rm -rf node_modules package-lock.json
npm install
npm run build
# contoh struktur yang benar
cd /var/www/wdms/laravel_app
ls -la package.json

npm install
npm run build
Kalau lupa project-nya ada di mana, kamu bisa cari cepat:
sudo find / -maxdepth 4 -name package.json 2>/dev/null | head
4) Permission
Pastikan folder storage dan bootstrap/cache bisa ditulis oleh web server.
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
5) Nginx Site
Buat file /etc/nginx/sites-available/wdms lalu symlink ke sites-enabled.
server {
    listen 80;
    server_name _;

    root /var/www/html/wdms/laravel_app/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \\.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock; # sesuaikan versi
    }

    location ~ /\\.ht {
        deny all;
    }
}
sudo ln -s /etc/nginx/sites-available/wdms /etc/nginx/sites-enabled/wdms
sudo nginx -t
sudo systemctl reload nginx
6) Queue Worker & Scheduler (Opsional)
Kalau ada proses background, jalankan queue worker dan scheduler. Praktisnya pakai supervisor + cron.
# Cron (tiap menit)
* * * * * cd /var/www/wdms/laravel_app && php artisan schedule:run >> /dev/null 2>&1

# Queue (contoh manual)
cd /var/www/wdms/laravel_app
php artisan queue:work --sleep=1 --tries=1 --timeout=0

Kalau Project Ditaruh di Home

Default disarankan tetap di /var/www/html/. Tapi kalau terpaksa taruh di home (misal /home/mesin24/wdms/laravel_app), ada 2 opsi: mode dev pakai php artisan serve, atau mode production pakai Nginx.
Opsi A (Dev): php artisan serve
cd /home/mesin24/wdms/laravel_app
php artisan serve --host=0.0.0.0 --port=8004

# akses dari browser
# http://IP_UBUNTU:8004
Jika firewall aktif: sudo ufw allow 8004/tcp
Opsi B (Prod): Nginx + PHP-FPM
Root Nginx harus menunjuk ke folder public/. Pastikan user web server bisa baca folder home.
# permission Laravel wajib
sudo chown -R www-data:www-data /home/mesin24/wdms/laravel_app/storage /home/mesin24/wdms/laravel_app/bootstrap/cache
sudo chmod -R 775 /home/mesin24/wdms/laravel_app/storage /home/mesin24/wdms/laravel_app/bootstrap/cache

# permission agar nginx bisa akses home
sudo chmod 755 /home/mesin24
sudo chmod -R 755 /home/mesin24/wdms
# /etc/nginx/sites-available/wdms
server {
  listen 80;
  server_name _;

  root /home/mesin24/wdms/laravel_app/public;
  index index.php;

  location / { try_files $uri $uri/ /index.php?$query_string; }
  location ~ \\.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
  }
}

Portal Root + Banyak Laravel (Subpath)

Referensi untuk build mesin baru: root / menampilkan portal HTML, lalu beberapa project Laravel di subpath seperti /adms dan /hris. Pola ini enak untuk server internal (satu IP, banyak aplikasi).
Struktur Folder (Disarankan)
/var/www/html/
  index.html              # portal root
  adms/public/            # Laravel ADMS (document root = public)
  hris/public/            # Laravel HRIS (document root = public)
Nginx Config (Portal + /adms + /hris)
Buat file /etc/nginx/sites-available/portal, lalu enable dan reload. Sesuaikan versi PHP-FPM (Ubuntu 24.04 umumnya php8.3-fpm).
server {
  listen 80;
  server_name 192.168.11.201;

  # ROOT PORTAL
  root /var/www/html;
  index index.html index.htm;
  location = / { try_files /index.html =404; }

  # ADMS: /adms -> /var/www/html/adms/public
  location ^~ /adms {
    alias /var/www/html/adms/public;
    try_files $uri $uri/ /adms/index.php?$query_string;
  }
  location ~ ^/adms/index\\.php(/|$) {
    include snippets/fastcgi-php.conf;
    fastcgi_param SCRIPT_FILENAME /var/www/html/adms/public/index.php;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
  }
  location ~ ^/adms/(?!index\\.php).+\\.php$ { return 404; }

  # HRIS: /hris -> /var/www/html/hris/public
  location ^~ /hris {
    alias /var/www/html/hris/public;
    try_files $uri $uri/ /hris/index.php?$query_string;
  }
  location ~ ^/hris/index\\.php(/|$) {
    include snippets/fastcgi-php.conf;
    fastcgi_param SCRIPT_FILENAME /var/www/html/hris/public/index.php;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
  }
  location ~ ^/hris/(?!index\\.php).+\\.php$ { return 404; }

  # optional: blok file sensitif
  location ~* \\.(env|log|sql)$ { deny all; }
}
sudo ln -s /etc/nginx/sites-available/portal /etc/nginx/sites-enabled/portal
sudo nginx -t
sudo systemctl reload nginx
ENV & Permission
Pastikan masing-masing Laravel set APP_URL sesuai subpath, dan permission storage/bootstrap/cache benar.
# adms/.env
APP_URL=http://192.168.11.201/adms

# hris/.env
APP_URL=http://192.168.11.201/hris
sudo chown -R www-data:www-data /var/www/html/adms/storage /var/www/html/adms/bootstrap/cache
sudo chmod -R 775 /var/www/html/adms/storage /var/www/html/adms/bootstrap/cache

sudo chown -R www-data:www-data /var/www/html/hris/storage /var/www/html/hris/bootstrap/cache
sudo chmod -R 775 /var/www/html/hris/storage /var/www/html/hris/bootstrap/cache

Cek Paket Terinstall (Ubuntu)

Beberapa perintah cepat untuk melihat paket apa saja yang sudah terinstall dan mencari paket tertentu.
# list semua paket terinstall (dpkg)
dpkg -l

# cari paket tertentu
dpkg -l | grep -i mysql
dpkg -l | grep -i php
dpkg -l | grep -i nginx

# list paket terinstall via apt
apt list --installed
apt list --installed | grep -i mysql

# lihat paket yang baru diinstall terakhir (log)
grep " install " /var/log/dpkg.log | tail -n 50
zgrep " install " /var/log/dpkg.log* | tail -n 50

Catatan

@endsection