index.html
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
teguh nugroho 2026-08-22 21:36:53 +07:00
parent 216825cb2f
commit 1c3a2dea19

167
docs/index.html Normal file
View File

@ -0,0 +1,167 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cargo ERP Backend API Docs</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{--bg:#0f172a;--bg2:#1e293b;--bg3:#334155;--text:#e2e8f0;--text2:#94a3b8;--border:#475569;--get:#3b82f6;--post:#22c55e;--put:#f59e0b;--delete:#ef4444;--accent:#60a5fa}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,monospace;background:var(--bg);color:var(--text);display:flex;min-height:100vh}
.sidebar{width:280px;background:var(--bg2);border-right:1px solid var(--border);position:fixed;top:0;left:0;bottom:0;overflow-y:auto;padding:16px 0;z-index:10}
.sidebar h2{padding:0 16px 12px;font-size:16px;color:var(--accent);border-bottom:1px solid var(--border);margin-bottom:8px}
.sidebar .search{margin:12px 16px}
.sidebar input{width:100%;padding:8px 12px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);font-size:13px}
.sidebar nav a{display:block;padding:6px 16px;color:var(--text2);text-decoration:none;font-size:12px;border-left:3px solid transparent;transition:.15s}
.sidebar nav a:hover{background:var(--bg3);color:var(--text)}
.sidebar nav .cat{font-size:13px;font-weight:700;color:var(--text);padding:12px 16px 4px;text-transform:uppercase;letter-spacing:.5px}
.main{margin-left:280px;flex:1;padding:24px 32px;max-width:960px}
.main h1{font-size:24px;margin-bottom:8px}
.main .subtitle{color:var(--text2);margin-bottom:24px;font-size:14px}
.server-bar{display:flex;gap:12px;margin-bottom:24px;flex-wrap:wrap}
.server-bar .srv{padding:8px 14px;border-radius:6px;background:var(--bg2);border:1px solid var(--border);font-size:13px;cursor:pointer;transition:.15s}
.server-bar .srv.active{border-color:var(--accent);color:var(--accent)}
.endpoints{display:flex;flex-direction:column;gap:12px}
.ep{background:var(--bg2);border:1px solid var(--border);border-radius:8px;overflow:hidden}
.ep-head{display:flex;align-items:center;gap:12px;padding:12px 16px;cursor:pointer}
.ep-head:hover{background:var(--bg3)}
.method{padding:3px 10px;border-radius:4px;font-size:12px;font-weight:700;color:#fff;min-width:64px;text-align:center;text-transform:uppercase}
.method.get{background:var(--get)}.method.post{background:var(--post)}.method.put{background:var(--put)}.method.delete{background:var(--delete)}
.ep-path{font-size:14px;font-family:monospace;color:var(--text)}
.ep-summary{color:var(--text2);font-size:12px;margin-left:auto}
.ep-body{display:none;padding:16px;border-top:1px solid var(--border);font-size:13px;line-height:1.6}
.ep.open .ep-body{display:block}
.section-label{color:var(--accent);font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;margin:12px 0 6px}
.section-label:first-child{margin-top:0}
.params table{width:100%;border-collapse:collapse}
.params td,.params th{text-align:left;padding:6px 10px;border-bottom:1px solid var(--border);font-size:13px}
.params th{color:var(--text2);font-size:11px;text-transform:uppercase}
pre{background:var(--bg);border:1px solid var(--border);border-radius:6px;padding:12px 16px;overflow-x:auto;font-size:12px;line-height:1.5;margin-bottom:8px}
pre code{color:var(--text2)}
.cat-section{margin-top:24px}
.cat-title{font-size:18px;font-weight:700;color:var(--accent);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border)}
.footer{text-align:center;padding:32px;color:var(--text2);font-size:12px}
@media(max-width:768px){.sidebar{display:none}.main{margin-left:0;padding:16px}}
</style>
</head>
<body>
<div class="sidebar">
<h2>Cargo ERP API</h2>
<div class="search"><input type="text" id="search" placeholder="Search endpoints..."></div>
<nav id="nav"></nav>
</div>
<div class="main">
<h1>Cargo ERP Backend API</h1>
<p class="subtitle">Master Data, Cost Components, Basic Pricing. Auth ignored for docs.</p>
<div class="server-bar">
<div class="srv active" onclick="setBase('http://localhost:8080')">Local (localhost:8080)</div>
<div class="srv" onclick="setBase('http://145.79.11.200:8080')">VPS (145.79.11.200:8080)</div>
</div>
<div id="eps"></div>
<div class="footer">Cargo ERP Backend API Docs</div>
</div>
<script>
let BASE='http://localhost:8080';
function setBase(u){BASE=u;document.querySelectorAll('.srv').forEach(s=>s.classList.toggle('active',s.textContent.includes(u.split(':')[1]||'localhost')));render()}
const E=[
{cat:"Auth",method:"get",path:"/ping",summary:"Health Check",params:[],req:null},
{cat:"Master Data / Province",method:"get",path:"/master-data/provinces/",summary:"Get All Province",params:[{n:"id",t:"string",req:false,d:"id"},{n:"name",t:"string",req:false,d:"name"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"}],req:null},
{cat:"Master Data / Province",method:"post",path:"/master-data/provinces/",summary:"Create Province",params:[],req:"ProvinceCreateRequest"},
{cat:"Master Data / Province",method:"post",path:"/master-data/provinces/list",summary:"Get Province List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Master Data / Province",method:"get",path:"/master-data/provinces/<id>",summary:"Get Province by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Province",method:"put",path:"/master-data/provinces/<id>",summary:"Update Province",params:[{n:"id",t:"string",req:true,d:"id"}],req:"ProvinceCreateRequest"},
{cat:"Master Data / Province",method:"delete",path:"/master-data/provinces/<id>",summary:"Delete Province",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Province",method:"get",path:"/master-data/provinces/template",summary:"Download Province Import Template",params:[],req:null},
{cat:"Master Data / Province",method:"post",path:"/master-data/provinces/import",summary:"Import Province Data",params:[],req:"_multipart_"},
{cat:"Master Data / Province",method:"post",path:"/master-data/provinces/import/stop",summary:"Stop Province Import",params:[],req:"StopImportRequest"},
{cat:"Master Data / Province",method:"get",path:"/master-data/provinces/import/status/<jobId>",summary:"Get Province Import Job Status",params:[{n:"jobId",t:"string",req:true,d:"jobId"}],req:null},
{cat:"Master Data / City",method:"get",path:"/master-data/cities/",summary:"Get All City",params:[{n:"id",t:"string",req:false,d:"id"},{n:"name",t:"string",req:false,d:"name"},{n:"province_id",t:"string",req:false,d:"province_id"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"},{n:"port",t:"string",req:false,d:"port"}],req:null},
{cat:"Master Data / City",method:"post",path:"/master-data/cities/",summary:"Create City",params:[],req:"CityCreateRequest"},
{cat:"Master Data / City",method:"post",path:"/master-data/cities/list",summary:"Get City List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Master Data / City",method:"get",path:"/master-data/cities/<id>",summary:"Get City by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / City",method:"put",path:"/master-data/cities/<id>",summary:"Update City",params:[{n:"id",t:"string",req:true,d:"id"}],req:"CityCreateRequest"},
{cat:"Master Data / City",method:"delete",path:"/master-data/cities/<id>",summary:"Delete City",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / City",method:"get",path:"/master-data/cities/template",summary:"Download City Import Template",params:[],req:null},
{cat:"Master Data / City",method:"post",path:"/master-data/cities/import",summary:"Import City Data",params:[],req:"_multipart_"},
{cat:"Master Data / City",method:"post",path:"/master-data/cities/import/stop",summary:"Stop City Import",params:[],req:"StopImportRequest"},
{cat:"Master Data / City",method:"get",path:"/master-data/cities/import/status/<jobId>",summary:"Get City Import Job Status",params:[{n:"jobId",t:"string",req:true,d:"jobId"}],req:null},
{cat:"Master Data / District",method:"get",path:"/master-data/districts/",summary:"Get All District",params:[{n:"id",t:"string",req:false,d:"id"},{n:"name",t:"string",req:false,d:"name"},{n:"province_id",t:"string",req:false,d:"province_id"},{n:"city_id",t:"string",req:false,d:"city_id"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"}],req:null},
{cat:"Master Data / District",method:"post",path:"/master-data/districts/",summary:"Create District",params:[],req:"DistrictCreateRequest"},
{cat:"Master Data / District",method:"post",path:"/master-data/districts/list",summary:"Get District List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Master Data / District",method:"get",path:"/master-data/districts/<id>",summary:"Get District by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / District",method:"put",path:"/master-data/districts/<id>",summary:"Update District",params:[{n:"id",t:"string",req:true,d:"id"}],req:"DistrictCreateRequest"},
{cat:"Master Data / District",method:"delete",path:"/master-data/districts/<id>",summary:"Delete District",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / District",method:"get",path:"/master-data/districts/template",summary:"Download District Import Template",params:[],req:null},
{cat:"Master Data / District",method:"post",path:"/master-data/districts/import",summary:"Import District Data",params:[],req:"_multipart_"},
{cat:"Master Data / District",method:"post",path:"/master-data/districts/import/stop",summary:"Stop District Import",params:[],req:"StopImportRequest"},
{cat:"Master Data / District",method:"get",path:"/master-data/districts/import/status/<jobId>",summary:"Get District Import Job Status",params:[{n:"jobId",t:"string",req:true,d:"jobId"}],req:null},
{cat:"Master Data / Subdistrict",method:"get",path:"/master-data/subdistricts/",summary:"Get All Subdistrict",params:[{n:"id",t:"string",req:false,d:"id"},{n:"name",t:"string",req:false,d:"name"},{n:"province_id",t:"string",req:false,d:"province_id"},{n:"city_id",t:"string",req:false,d:"city_id"},{n:"district_id",t:"string",req:false,d:"district_id"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"}],req:null},
{cat:"Master Data / Subdistrict",method:"post",path:"/master-data/subdistricts/",summary:"Create Subdistrict",params:[],req:"SubdistrictCreateRequest"},
{cat:"Master Data / Subdistrict",method:"post",path:"/master-data/subdistricts/list",summary:"Get Subdistrict List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Master Data / Subdistrict",method:"get",path:"/master-data/subdistricts/<id>",summary:"Get Subdistrict by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Subdistrict",method:"put",path:"/master-data/subdistricts/<id>",summary:"Update Subdistrict",params:[{n:"id",t:"string",req:true,d:"id"}],req:"SubdistrictCreateRequest"},
{cat:"Master Data / Subdistrict",method:"delete",path:"/master-data/subdistricts/<id>",summary:"Delete Subdistrict",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Subdistrict",method:"get",path:"/master-data/subdistricts/template",summary:"Download Subdistrict Import Template",params:[],req:null},
{cat:"Master Data / Subdistrict",method:"post",path:"/master-data/subdistricts/import",summary:"Import Subdistrict Data",params:[],req:"_multipart_"},
{cat:"Master Data / Subdistrict",method:"post",path:"/master-data/subdistricts/import/stop",summary:"Stop Subdistrict Import",params:[],req:"StopImportRequest"},
{cat:"Master Data / Subdistrict",method:"get",path:"/master-data/subdistricts/import/status/<jobId>",summary:"Get Subdistrict Import Job Status",params:[{n:"jobId",t:"string",req:true,d:"jobId"}],req:null},
{cat:"Master Data / Postal Code",method:"get",path:"/master-data/postal-codes/",summary:"Get All Postal Code",params:[{n:"id",t:"string",req:false,d:"id"},{n:"postal_code",t:"string",req:false,d:"postal_code"},{n:"province_id",t:"string",req:false,d:"province_id"},{n:"city_id",t:"string",req:false,d:"city_id"},{n:"district_id",t:"string",req:false,d:"district_id"},{n:"subdistrict_id",t:"string",req:false,d:"subdistrict_id"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"}],req:null},
{cat:"Master Data / Postal Code",method:"post",path:"/master-data/postal-codes/",summary:"Create Postal Code",params:[],req:"PostalCodeCreateRequest"},
{cat:"Master Data / Postal Code",method:"post",path:"/master-data/postal-codes/list",summary:"Get Postal Code List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Master Data / Postal Code",method:"get",path:"/master-data/postal-codes/<id>",summary:"Get Postal Code by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Postal Code",method:"put",path:"/master-data/postal-codes/<id>",summary:"Update Postal Code",params:[{n:"id",t:"string",req:true,d:"id"}],req:"PostalCodeCreateRequest"},
{cat:"Master Data / Postal Code",method:"delete",path:"/master-data/postal-codes/<id>",summary:"Delete Postal Code",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Postal Code",method:"get",path:"/master-data/postal-codes/template",summary:"Download Postal Code Import Template",params:[],req:null},
{cat:"Master Data / Postal Code",method:"post",path:"/master-data/postal-codes/import",summary:"Import Postal Code Data",params:[],req:"_multipart_"},
{cat:"Master Data / Postal Code",method:"post",path:"/master-data/postal-codes/import/stop",summary:"Stop Postal Code Import",params:[],req:"StopImportRequest"},
{cat:"Master Data / Postal Code",method:"get",path:"/master-data/postal-codes/import/status/<jobId>",summary:"Get Postal Code Import Job Status",params:[{n:"jobId",t:"string",req:true,d:"jobId"}],req:null},
{cat:"Master Data / Cost Component",method:"get",path:"/master-data/cost-components/",summary:"Get All Cost Component",params:[{n:"id",t:"string",req:false,d:"id"},{n:"name",t:"string",req:false,d:"name"},{n:"code",t:"string",req:false,d:"code"},{n:"component_type",t:"string",req:false,d:"component_type"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"}],req:null},
{cat:"Master Data / Cost Component",method:"post",path:"/master-data/cost-components/",summary:"Create Cost Component",params:[],req:"CostComponentCreateRequest"},
{cat:"Master Data / Cost Component",method:"post",path:"/master-data/cost-components/list",summary:"Get Cost Component List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Master Data / Cost Component",method:"get",path:"/master-data/cost-components/<id>",summary:"Get Cost Component by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Cost Component",method:"put",path:"/master-data/cost-components/<id>",summary:"Update Cost Component",params:[{n:"id",t:"string",req:true,d:"id"}],req:"CostComponentCreateRequest"},
{cat:"Master Data / Cost Component",method:"delete",path:"/master-data/cost-components/<id>",summary:"Delete Cost Component",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Master Data / Cost Component",method:"post",path:"/master-data/cost-components/sortup",summary:"Sort Up Cost Component",params:[],req:"SortRequest"},
{cat:"Master Data / Cost Component",method:"post",path:"/master-data/cost-components/sortdown",summary:"Sort Down Cost Component",params:[],req:"SortRequest"},
{cat:"Basic Pricing",method:"get",path:"/basic-pricings/",summary:"Get All Basic Pricing",params:[{n:"id",t:"string",req:false,d:"id"},{n:"name",t:"string",req:false,d:"name"},{n:"province_source_id",t:"string",req:false,d:"province_source_id"},{n:"city_source_id",t:"string",req:false,d:"city_source_id"},{n:"district_source_id",t:"string",req:false,d:"district_source_id"},{n:"subdistrict_source_id",t:"string",req:false,d:"subdistrict_source_id"},{n:"postal_code_source_id",t:"string",req:false,d:"postal_code_source_id"},{n:"province_destination_id",t:"string",req:false,d:"province_destination_id"},{n:"city_destination_id",t:"string",req:false,d:"city_destination_id"},{n:"district_destination_id",t:"string",req:false,d:"district_destination_id"},{n:"subdistrict_destination_id",t:"string",req:false,d:"subdistrict_destination_id"},{n:"postal_code_destination_id",t:"string",req:false,d:"postal_code_destination_id"},{n:"package_type_id",t:"string",req:false,d:"package_type_id"},{n:"moda_id",t:"string",req:false,d:"moda_id"},{n:"merchant_id",t:"string",req:false,d:"merchant_id"}],req:null},
{cat:"Basic Pricing",method:"post",path:"/basic-pricings/",summary:"Create Basic Pricing",params:[],req:"BasicPricingCreateRequest"},
{cat:"Basic Pricing",method:"post",path:"/basic-pricings/list",summary:"Get Basic Pricing List (DataTable)",params:[],req:"DataTableRequest"},
{cat:"Basic Pricing",method:"get",path:"/basic-pricings/<id>",summary:"Get Basic Pricing by ID",params:[{n:"id",t:"string",req:true,d:"id"}],req:null},
{cat:"Basic Pricing",method:"put",path:"/basic-pricings/<id>",summary:"Update Basic Pricing",params:[{n:"id",t:"string",req:true,d:"id"}],req:"BasicPricingCreateRequest"},
{cat:"Basic Pricing",method:"delete",path:"/basic-pricings/<id>",summary:"Delete Basic Pricing",params:[{n:"id",t:"string",req:true,d:"id"}],req:null}];
const schemas={"AuthRequest": ["email", "password"], "AuthResponse": ["token"], "ProvinceCreateRequest": ["name"], "ProvinceResponse": ["id", "name", "merchant_id"], "CityCreateRequest": ["name", "province_id", "port"], "CityResponse": ["id", "name", "province_id", "merchant_id", "port"], "DistrictCreateRequest": ["name", "province_id", "city_id"], "DistrictResponse": ["id", "name", "province_id", "city_id", "merchant_id"], "SubdistrictCreateRequest": ["name", "province_id", "city_id", "district_id"], "SubdistrictResponse": ["id", "name", "province_id", "city_id", "district_id", "merchant_id"], "PostalCodeCreateRequest": ["postal_code", "province_id", "city_id", "district_id", "subdistrict_id"], "PostalCodeResponse": ["id", "postal_code", "province_id", "city_id", "district_id", "subdistrict_id", "merchant_id"], "CostComponentCreateRequest": ["name", "code", "value", "component_type"], "CostComponentResponse": ["id", "name", "code", "inc", "value", "component_type", "merchant_id"], "BasicPricingComponentRequest": ["cost_component_id", "value"], "BasicPricingComponentResponse": ["id", "cost_component_id", "value"], "BasicPricingCreateRequest": ["name", "province_source_id", "city_source_id", "district_source_id", "subdistrict_source_id", "postal_code_source_id", "province_destination_id", "city_destination_id", "district_destination_id", "subdistrict_destination_id", "postal_code_destination_id", "package_type_id", "moda_id", "components"], "BasicPricingResponse": ["id", "name", "province_source_id", "city_source_id", "district_source_id", "subdistrict_source_id", "postal_code_source_id", "province_destination_id", "city_destination_id", "district_destination_id", "subdistrict_destination_id", "postal_code_destination_id", "package_type_id", "moda_id", "merchant_id", "components"]};
function render() {
const eps=document.getElementById('eps');
const q=document.getElementById('search').value.toLowerCase();
let html='';
let lastCat='';
E.forEach((e,i)=>{
if(q && !e.path.toLowerCase().includes(q) && !e.summary.toLowerCase().includes(q) && !e.cat.toLowerCase().includes(q)) return;
if(e.cat!==lastCat){lastCat=e.cat;html+='<div class="cat-section"><div class="cat-title">'+e.cat+'</div></div>';}
let body='';
if(e.params&&e.params.length){
body+='<div class="section-label">Parameters</div><div class="params"><table><tr><th>Name</th><th>Type</th><th>Required</th><th>Description</th></tr>';
e.params.forEach(p=>{body+='<tr><td>'+p.n+'</td><td>'+p.t+'</td><td>'+(p.req?'<span style="color:#fca5a5">Yes</span>':'No')+'</td><td>'+p.d+'</td></tr>'});
body+='</table></div>';
}
if(e.req){
body+='<div class="section-label">Request Body</div>';
if(e.req==='_multipart_'){
body+='<pre><code>multipart/form-data\nfield: file (CSV)</code></pre>';
} else if(schemas[e.req]){
body+='<pre><code>{\n';
schemas[e.req].forEach(k=>{body+=' \"'+k+'\": ...\n'});
body+='}</code></pre>';
}
}
body+='<div class="section-label">Response (200)</div><pre><code>{\n \"success\": true,\n \"data\": {...}\n}</code></pre>';
html+='<div class="ep" id="ep-'+i+'"><div class="ep-head" onclick="document.getElementById('ep-'+i+'').classList.toggle('open')"><span class="method '+e.method+'">'+e.method+'</span><span class="ep-path">'+e.path+'</span><span class="ep-summary">'+e.summary+'</span></div><div class="ep-body">'+body+'</div></div>';
});
eps.innerHTML=html;
}
document.getElementById('search').addEventListener('input',render);
render();
</script>
</body>
</html>