Blog

  • OpenCode & OpenRouter, Solusi Saat Token Claude Code & Codex Habis

    OpenCode & OpenRouter, Solusi Saat Token Claude Code & Codex Habis

    Saya seorang vibe coder. Tapi saya tetap memahami arsitektur aplikasi, database, alur bisnis, deployment, dan keputusan teknis yang sedang dibuat. Tetapi untuk pekerjaan coding sehari-hari, saya banyak bekerja bersama AI agent.

    Dalam workflow saya sekarang, ada dua AI agent yang paling sering saya gunakan.

    Claude Code biasanya menjadi programmer utama. Saya memakainya untuk implementasi fitur, refactor lintas file, debugging, perubahan arsitektur, dan pekerjaan lain yang membutuhkan pemahaman repository cukup dalam.

    Sementara Codex lebih sering saya posisikan sebagai pihak kedua yang independen. Setelah Claude selesai mengerjakan sesuatu, Codex saya gunakan untuk audit, code review, QA, security review, mengecek regression, menjalankan test, dan memastikan implementasi yang akan saya merge memang sudah aman.

    Jadi polanya kurang lebih seperti ini:

    Saya sebagai pemilik produk dan pengambil keputusan β†’ Claude Code sebagai implementer β†’ Codex sebagai independent reviewer β†’ Human QA β†’ merge β†’ production.

    Workflow seperti ini sangat membantu saya. Masalahnya, semakin sering menggunakan AI agent, saya semakin sadar bahwa ada satu resource yang juga harus dikelola: usage limit.

    Claude Code punya limit. Codex juga punya limit.

    Dan kalau salah satunya habis di tengah pekerjaan, saya tidak ingin seluruh proses development ikut berhenti.

    Dari situlah eksperimen ini dimulai.

    Awalnya cuma ingin punya AI agent cadangan

    Beberapa waktu terakhir saya mulai berpikir:

    β€œApakah ada AI coding agent lain yang bisa saya pasang di VS Code sebagai cadangan?”

    Saya tidak sedang mencari pengganti Claude Code atau Codex.

    Sampai sekarang keduanya tetap menjadi agent utama saya.

    Yang saya cari adalah jalur alternatif.

    Kalau quota Claude habis, pekerjaan sederhana masih bisa jalan.

    Kalau Codex sedang limit, setidaknya saya punya reviewer kedua.

    Kalau ada pekerjaan ringan, saya juga tidak harus selalu menghabiskan resource model premium.

    Sebagai vibe coder, saya merasa ini penting. Ketergantungan hanya pada satu atau dua AI provider rasanya mirip developer yang hanya punya satu tool di toolbox-nya.

    Semakin banyak saya memahami berbagai agent, model, provider, permission system, dan karakter masing-masing LLM, semakin fleksibel juga cara saya bekerja.

    Akhirnya saya mencoba OpenCode.

    OpenCode sendiri bukan sebuah model AI. Ia adalah coding agent open-source yang bisa dijalankan dari terminal, desktop, maupun IDE, dan kita bisa menghubungkannya ke berbagai provider LLM.

    Ini salah satu hal pertama yang menurut saya penting untuk dipahami:

    OpenCode adalah agent harness. Model AI yang bekerja di belakangnya bisa kita ganti.

    Dengan kata lain, OpenCode bisa menjadi semacam cockpit, sedangkan β€œmesinnya” bisa berasal dari provider yang berbeda.

    Untuk eksperimen saya, providernya adalah OpenRouter.

    Kenapa OpenRouter menarik?

    OpenRouter pada dasarnya memberi satu pintu untuk mengakses banyak model dari berbagai provider.

    Di OpenCode, setelah OpenRouter dihubungkan, saya bisa membuka /models dan memilih model mana yang ingin digunakan. OpenCode sendiri memang mendukung pemilihan model per session seperti ini.

    Yang membuat saya tertarik adalah OpenRouter mempunyai cukup banyak model yang tersedia melalui endpoint gratis dengan suffix :free.

    Jadi saya mulai bereksperimen.

    Model pertama yang saya coba adalah North Mini Code.

    Setelah itu saya mencoba model lain yang lebih kuat untuk agentic coding, yaitu Nex-N2.5-Pro, lalu menjalankannya pada reasoning level High.

    Saya tidak mengujinya dengan tugas dummy.

    Saya sengaja menggunakan kasus development sungguhan.

    Kasus nyata yang saya jadikan benchmark

    Saat eksperimen ini berlangsung, saya sedang menyelesaikan sebuah fitur pada salah satu aplikasi internal berbasis Next.js.

    Nama project dan domainnya sengaja tidak saya tulis di sini. Anggap saja aplikasinya mempunyai sebuah modul finansial.

    Di salah satu halaman overview, kami baru saja menyelesaikan beberapa perubahan cukup besar:

    ada integrasi data finansial asli, agregasi omzet, biaya, profit, dan margin, visualisasi chart batang dan area, donut chart, tooltip interaktif, penyimpanan preference chart, keyboard accessibility, touch interaction, serta beberapa perubahan shared component dan design system.

    Total perubahan yang akan direview menyentuh 22 file.

    Implementasinya sudah selesai.

    Human QA sudah saya lakukan.

    Test suite juga sudah lolos.

    Pull Request sudah dibuat.

    Tahap berikutnya adalah independent review sebelum merge.

    Biasanya pekerjaan semacam ini saya serahkan ke Codex.

    Kebetulan saat itu quota Codex saya sedang habis.

    Nah, ini situasi yang sempurna untuk pertanyaan saya sebelumnya:

    β€œBisakah OpenCode + model gratis menjadi reviewer cadangan saat agent utama sedang limit?”

    Akhirnya eksperimen benar-benar dimulai.

    Eksperimen pertama: North Mini Code

    Saya membuat prompt audit yang cukup ketat.

    Agent tidak saya izinkan mengedit repository.

    Ia hanya boleh membaca source code, memahami data flow, memeriksa Git diff, mengecek business logic, lalu menjalankan validation secara bertahap.

    Saya bahkan membagi review menjadi beberapa fase.

    Phase A hanya untuk memastikan repository, branch, commit SHA, dan diff benar.

    Phase B untuk static code review.

    Phase C untuk deterministic validation seperti tests, typecheck, lint, verifier, dan build.

    Phase D baru boleh menghasilkan verdict akhir.

    Tujuannya bukan hanya menguji apakah model bisa menemukan bug.

    Saya juga ingin melihat apakah model disiplin mengikuti workflow engineering.

    North Mini ternyata cukup menarik.

    Ia berhasil membaca repository dan mengikuti sebagian besar instruksi. Bahkan ketika ia sempat membuat dua kesimpulan keliru tentang perhitungan finansial, saya meminta model tersebut membuka kembali implementasinya dan membuktikan klaimnya dengan source code.

    Ia akhirnya mengakui bahwa dua finding tersebut adalah:

    RETRACTED_FALSE_POSITIVE

    Buat saya ini justru menarik.

    Modelnya bisa salah, tetapi ketika dipaksa kembali ke evidence, ia mampu memperbaiki reasoning-nya.

    Sayangnya, ada beberapa masalah lain.

    Pada bagian berikutnya ia mulai mencampur hasil targeted test dengan full test suite. Ia juga melewati phase gate dan menghasilkan final verdict sebelum saya memberikan izin untuk melanjutkan ke fase tersebut.

    Artinya, untuk pekerjaan kritis, North Mini pada konfigurasi yang saya gunakan saat itu belum cukup bisa dipercaya sebagai pengganti Codex.

    Tetapi bukan berarti tidak berguna.

    Saya justru mulai melihat tempatnya.

    Model ringan seperti itu mungkin sangat berguna untuk Git inspection, pencarian file, inventory, preliminary review, atau pekerjaan mekanis lainnya.

    Kemudian saya mencoba model yang lebih kuat

    Saya lalu berpikir bahwa eksperimen model gratis seharusnya dilakukan dengan cara berbeda.

    Kalau tujuan saya mencari batas kemampuan maksimal sebuah model gratis, kenapa justru memulainya dari reasoning Medium?

    Sejak saat itu saya memutuskan:

    Untuk eksperimen model gratis pada pekerjaan substantif, gunakan reasoning tertinggi yang tersedia terlebih dahulu.

    Barulah setelah mengetahui ceiling-nya, kita menentukan pekerjaan mana yang aman diturunkan ke Medium atau Low.

    Saya kemudian memilih Nex-N2.5-Pro Free dan reasoning High.

    Session baru dibuat dari nol agar tidak membawa bias atau reasoning dari model sebelumnya.

    Hasil awalnya cukup menjanjikan.

    Nex berhasil menjalankan Phase A dengan sangat disiplin.

    Ia memverifikasi worktree, branch, commit SHA, origin/main, merge-base, status repository, package manifest, lockfile, dan tepat menemukan bahwa PR tersebut terdiri dari 22 file.

    Ia berhenti persis ketika Phase A selesai.

    Saya lalu mengirim:

    CONTINUE_PHASE_B

    Model mulai membaca governance repository, dokumentasi, design system, arsitektur Finance, lalu mulai menjalankan beberapa subtask untuk memahami data flow dan Core component.

    Saya cukup antusias melihatnya.

    Lalu tiba-tiba semuanya berhenti.

    Masalah pertama yang saya kira: apakah modelnya error?

    Pesan yang muncul di OpenCode adalah:

    Rate limit exceeded: free-models-per-day

    Di bawahnya bahkan ada pesan yang menyebut bahwa menambahkan credit dapat membuka 1.000 free model requests per day.

    Awalnya saya belum benar-benar memahami maksudnya.

    Apakah token model habis?

    Apakah context window penuh?

    Apakah saya terkena batas 20 request per menit?

    Atau memang jatah gratis hariannya habis?

    Ini membawa saya ke salah satu pelajaran paling penting dari eksperimen malam ini.

    Prompt, request, dan token ternyata bukan hal yang sama

    Sebelumnya saya terbiasa melihat AI dari sisi pengguna.

    Saya mengetik satu prompt.

    Agent bekerja.

    Agent mengembalikan laporan.

    Secara intuitif rasanya:

    satu prompt = satu request.

    Ternyata pada coding agent, tidak sesederhana itu.

    Bayangkan saya memberi OpenCode satu instruksi:

    β€œReview PR ini secara menyeluruh.”

    Di mata saya itu satu prompt.

    Tetapi di belakang layar bisa terjadi pola seperti:

    model berpikir β†’ agent membaca file β†’ model dipanggil lagi β†’ agent membaca file lain β†’ model dipanggil lagi β†’ menjalankan tool β†’ model membaca hasil tool β†’ berpikir lagi β†’ memanggil subagent β†’ dan seterusnya.

    Setiap kali OpenCode menghubungi LLM melalui OpenRouter, terjadilah sebuah request.

    Jadi:

    1 prompt manusia bisa menghasilkan banyak request ke model.

    Token berbeda lagi.

    Token adalah unit teks yang diproses oleh model.

    Satu request bisa hanya membawa beberapa ribu token.

    Request lain mungkin membawa puluhan atau bahkan ratusan ribu token karena berisi prompt, history session, source code, hasil tool, dan konteks lainnya.

    Analogi yang paling mudah bagi saya akhirnya seperti ini:

    Request adalah jumlah perjalanan truk. Token adalah banyaknya muatan yang dibawa truk.

    Satu truk bisa membawa sedikit barang.

    Satu truk lain bisa membawa muatan sangat besar.

    Tetapi dari sisi request, keduanya tetap dihitung sebagai satu perjalanan.

    Saya tidak mau hanya menebak, jadi saya membuka dashboard OpenRouter

    Karena ini eksperimen yang ingin saya pahami dengan benar, saya tidak mau berhenti pada asumsi.

    Saya membuka dashboard OpenRouter dan masuk ke menu Activity.

    Di sanalah semuanya menjadi jelas.

    Dashboard menunjukkan:

    52 requests

    dengan total sekitar:

    3,05 juta token

    Breakdown modelnya:

    North Mini Code: 29 requests

    Nex-N2.5-Pro: 23 requests

    Totalnya:

    52 requests.

    Dan seluruh aktivitas tersebut berasal dari OpenCode.

    Ini cocok dengan dokumentasi OpenRouter saat ini.

    Untuk model gratis, akun tanpa credit mempunyai limit 50 requests per hari dan 20 requests per menit.

    Setelah akun mempunyai minimal $10 credit, batas free-model meningkat menjadi 1.000 requests per hari, sedangkan limit per menit tetap 20 requests per minute.

    Yang lebih meyakinkan lagi, error yang menghentikan OpenCode bukan generic rate-limit error.

    Pesannya secara eksplisit:

    free-models-per-day

    Jadi yang saya tabrak adalah batas harian, bukan batas per menit.

    Ini penting, karena kalau yang habis 20 request/menit, top-up $10 tidak menyelesaikan masalah

    Ini bagian yang benar-benar ingin saya buktikan sebelum mempertimbangkan membayar.

    Kondisinya saat ini:

    Kondisi akunFree requests/dayRequests/minute
    Tanpa credit5020
    Credit β‰₯ $101.00020

    Perhatikan kolom terakhir.

    Keduanya tetap 20 request per menit.

    Jadi kalau eksperimen saya tadi terhenti karena limit 20 RPM, membeli $10 credit tidak akan mengubah bottleneck tersebut.

    Tetapi data akun saya sendiri menunjukkan penggunaan berada di sekitar batas 50 request, dan server mengembalikan free-models-per-day.

    Artinya bottleneck yang saya alami memang:

    50 requests/day β†’ habis.

    Sedangkan upgrade yang ditawarkan OpenRouter mengubah tepat limit tersebut menjadi:

    1.000 requests/day.

    Inilah titik ketika saya mulai berpikir:

    β€œOke, sekarang $10 ini mulai terlihat masuk akal.”

    Apakah 20 requests per menit cukup untuk coding agent?

    Saya sempat mempertanyakan ini juga.

    Kalau daily limit naik menjadi 1.000 tetapi tetap dibatasi 20 request per menit, apakah coding workflow saya akan tetap sering terhambat?

    Setelah memahami cara agent bekerja, saya justru tidak terlalu khawatir.

    20 request per menit berarti satu request setiap sekitar tiga detik jika digunakan penuh terus-menerus.

    Workflow development saya bukan workload massively parallel.

    Biasanya agent bekerja secara sequential.

    Ia membaca file.

    Berpikir.

    Membaca caller.

    Berpikir lagi.

    Menjalankan test.

    Menunggu test selesai.

    Menganalisis output.

    Kemudian menentukan langkah berikutnya.

    Reasoning High juga membuat satu model call sendiri bisa membutuhkan waktu beberapa detik atau lebih.

    Jadi untuk satu atau beberapa agent yang bekerja normal, 20 RPM menurut saya masih cukup masuk akal.

    Yang lebih cepat habis justru daily allowance-nya.

    Misalnya 1.000 request digunakan selama delapan jam kerja, rata-rata hanya sekitar dua request per menit.

    Masih sangat jauh dari ceiling 20 RPM.

    Tentu kondisi bisa berbeda jika kita menjalankan banyak subagent secara paralel, retry loop agresif, atau banyak instance OpenCode dengan API key yang sama sekaligus.

    Tetapi untuk pola kerja saya sekarang, 1.000 requests/day terasa jauh lebih relevan dibanding memperbesar RPM.

    Lalu sebenarnya apa yang kita dapat kalau memasukkan $10?

    Ini perlu diluruskan karena saya sendiri awalnya mengira seperti subscription.

    Berdasarkan kebijakan OpenRouter saat tulisan ini dibuat, menambahkan minimal $10 credit menaikkan free-model allowance menjadi 1.000 requests/day. Credit itu bukan biaya langganan bulanan untuk menggunakan free model. Credit tetap dapat digunakan untuk model berbayar jika suatu hari kita membutuhkannya. OpenRouter juga menyatakan deposit tersebut tidak kedaluwarsa pada kebijakan saat ini.

    Namun saya sengaja menulis β€œpada kebijakan saat ini.”

    Saya tidak menganggap 1.000 free requests/day sebagai janji seumur hidup.

    Daftar model gratis, capacity, maupun policy sebuah platform tentu dapat berubah.

    OpenRouter sendiri menyatakan free model availability terus berkembang dan tidak dapat menjamin kondisinya akan selalu sama di masa depan.

    Jadi cara saya melihatnya bukan:

    β€œBayar $10 dan dapat AI gratis selamanya.”

    Tetapi:

    β€œDengan kebijakan sekarang, $10 credit membuka kapasitas eksperimen free-model yang jauh lebih usable, dan credit-nya sendiri tetap tersedia.”

    Pada kurs saat saya menulis catatan ini, $10 kira-kira berada di kisaran Rp170 ribuan.

    Saya sendiri belum melakukan top-up saat eksperimen ini ditulis.

    Tetapi setelah melihat data usage nyata, saya merasa biaya tersebut cukup layak dipertimbangkan.

    Yang sebenarnya paling menarik bukan soal gratisnya

    Semakin lama saya bereksperimen, saya sadar bahwa bagian paling menarik dari OpenCode + OpenRouter bukan sekadar:

    β€œSaya bisa pakai AI gratis.”

    Yang jauh lebih penting adalah saya mempunyai pilihan.

    Sebelumnya pola pikir saya kurang lebih:

    Claude Code adalah coding agent.

    Codex adalah reviewer.

    Sekarang cara saya melihat ekosistemnya mulai berubah.

    OpenCode adalah harness.

    OpenRouter adalah router/marketplace model.

    Di dalamnya saya bisa memilih model berbeda untuk karakter pekerjaan berbeda.

    Hari ini mungkin Nex.

    Besok bisa Nemotron.

    Lain waktu mungkin ada coding model baru yang bahkan belum tersedia saat artikel ini ditulis.

    Dan ini menurut saya salah satu skill baru yang akan semakin penting bagi developer yang bekerja bersama AI.

    Kita tidak harus mencari:

    β€œModel mana yang paling pintar?”

    Pertanyaan yang lebih berguna bisa menjadi:

    β€œModel mana yang cukup baik untuk pekerjaan ini, berapa resource yang dibutuhkan, seberapa disiplin ia mengikuti instruction, dan seberapa besar risikonya?”

    Saya juga belajar bahwa model gratis tidak otomatis pantas dipercaya untuk pekerjaan kritis

    Eksperimen ini juga memberi pelajaran sebaliknya.

    Gratis dan powerful bukan berarti otomatis aman.

    North Mini misalnya sempat menghasilkan false positive ketika membaca business logic finansial.

    Setelah dipaksa melihat source code lagi, model bisa memperbaiki dirinya.

    Tetapi pada fase berikutnya, ia sempat mencampur evidence dari command berbeda dan melewati phase gate yang sudah dibuat.

    Kalau saat itu saya hanya membaca kalimat:

    PASS

    lalu langsung merge ke production, eksperimen seperti ini justru berbahaya.

    Karena itu saya merasa workflow dengan AI agent tetap membutuhkan governance.

    Agent harus mempunyai scope.

    Harus ada permission.

    Harus ada evidence.

    Harus dibedakan antara static reasoning dan deterministic test.

    Harus ada Human QA.

    Dan khusus pekerjaan kritis, independent reviewer tetap sangat berharga.

    Jadi tujuan saya menggunakan OpenCode bukan membuat Claude Code atau Codex tidak diperlukan lagi.

    Justru saya ingin membuat workflow menjadi lebih resilien.

    Gambaran β€œarsenal” yang mulai terbentuk

    Setelah eksperimen ini, cara saya membayangkan workflow AI development pribadi mulai seperti ini:

    • Claude Code tetap menjadi implementer utama untuk coding berat, perubahan lintas file, architecture, auth, database, dan pekerjaan dengan risiko tinggi.
    • Codex tetap menjadi independent reviewer utama untuk QA, security review, final audit, dan release gate.
    • OpenCode + model gratis yang kuat menjadi jalur cadangan ketika quota agent utama habis, atau untuk pekerjaan yang memang tidak membutuhkan model premium.
    • Model gratis ringan bisa digunakan untuk Git inspection, repository inventory, pencarian, atau pekerjaan deterministic yang murah risikonya.
    • Model gratis dengan reasoning lebih kuat bisa diuji sebagai backup reviewer, investigator, debugging agent, atau implementer sekunder.

    Saya belum menganggap pembagian ini final.

    Justru tujuannya adalah terus melakukan benchmark dengan pekerjaan saya sehari-hari.

    Saya ingin mengukur bukan hanya apakah jawabannya bagus, tetapi juga request consumption, latency, false-positive rate, instruction discipline, kemampuan menggunakan tools, dan kualitas final report.

    Kenapa saya merasa eksperimen ini worth it?

    Karena sebagai vibe coder, pekerjaan saya semakin erat dengan model-model AI.

    Dulu toolbox developer berisi editor, Git, browser devtools, database client, server, framework, dan command line.

    Sekarang ada layer baru:

    AI coding agent.

    Model.

    Reasoning level.

    Provider.

    Context window.

    Permission system.

    Tool calling.

    Request limit.

    Token consumption.

    Agent orchestration.

    Menurut saya memahami semua ini pelan-pelan akan menjadi keunggulan tersendiri.

    Bukan berarti kita harus menggunakan 20 model sekaligus.

    Justru sebaliknya.

    Dengan memahami karakter masing-masing, kita bisa tahu kapan memakai tool yang tepat.

    Pelajaran utama saya untuk sesama vibe coder

    Kalau saya harus merangkum eksperimen ini menjadi beberapa hal yang ingin saya ingat sendiri dan mungkin berguna untuk vibe coder lain di Indonesia, ini poinnya:

    1. Jangan bergantung hanya pada satu AI coding agent. Bahkan model terbaik tetap mempunyai quota, outage, dan limit.
    2. OpenCode bukan model. Ia adalah agent harness yang memungkinkan kita menggunakan berbagai model/provider. OpenRouter adalah salah satu cara memberi OpenCode akses ke banyak model.
    3. Prompt, request, dan token adalah hal berbeda. Satu prompt manusia dapat memicu banyak request model. Satu request dapat membawa sedikit atau sangat banyak token.
    4. Agentic coding dapat mengonsumsi request jauh lebih cepat daripada chat biasa. Eksperimen saya hanya dalam satu malam menghasilkan 52 requests dan sekitar 3 juta token.
    5. Kalau OpenRouter menampilkan free-models-per-day, itu berbeda dengan limit 20 RPM. Dalam kasus saya, dashboard dan error sama-sama menunjukkan bahwa yang tercapai adalah daily free-request allowance.
    6. Pada kebijakan OpenRouter saat artikel ini ditulis, free account mendapat 50 requests/day dan 20 RPM. Dengan minimal $10 credit, free-model allowance menjadi 1.000 requests/day sementara RPM tetap 20.
    7. Jangan langsung percaya verdict AI. Minta evidence. Bedakan finding, observation, test result, dan asumsi. Model gratis maupun premium tetap dapat salah.
    8. Untuk pekerjaan berisiko tinggi, pakai model terkuat yang tersedia dan pertahankan independent review. Model gratis lebih cocok diposisikan sesuai kemampuan yang sudah kita buktikan sendiri, bukan berdasarkan hype.
    9. Lihat dashboard usage. Jangan menebak-nebak biaya atau limit. OpenRouter Activity memang menyediakan breakdown per request, model, app, token, dan penggunaan lainnya.
    10. Bangun pengalaman sendiri. Benchmark model menggunakan repository dan problem nyata jauh lebih berguna daripada sekadar melihat leaderboard.

    Jadi, apakah saya akan membeli $10 credit OpenRouter?

    Saat tulisan ini dibuat, belum.

    Tetapi eksperimen ini berhasil menjawab pertanyaan utama saya.

    Sebelumnya saya belum tahu apakah OpenCode dan OpenRouter benar-benar berguna dalam workflow saya.

    Sekarang saya tahu jawabannya:

    Ya, ada gunanya.

    Saya juga sekarang tahu bottleneck free tier yang saya alami bukan 20 request per menit, tetapi batas 50 request per hari.

    Dan karena $10 credit saat ini meningkatkan limit yang memang saya tabrak dari 50 menjadi 1.000 request per hari, menurut saya itu worth it untuk dipertimbangkan.

    Bukan karena saya berharap mengganti Claude Code atau Codex dengan model gratis.

    Tetapi karena dengan biaya yang relatif kecil, saya bisa mempunyai jalur cadangan yang jauh lebih fleksibel, sekaligus laboratorium untuk mencoba berbagai model AI coding.

    Kalau suatu hari Claude Code sedang habis quota, saya tidak harus berhenti.

    Kalau Codex sedang limit, saya masih punya opsi lain untuk melakukan preliminary review.

    Kalau muncul model open/free baru yang menarik, saya sudah punya infrastrukturnya untuk langsung mencoba.

    Bagi saya, value terbesar ada di sana.

    Bukan mencari satu AI yang bisa melakukan semuanya, tetapi mempunyai cukup banyak β€œjurus” untuk tetap bisa bergerak ketika kondisi berubah.

    Dan mungkin itulah salah satu kemampuan baru yang perlu dimiliki vibe coder sekarang.

  • Merancang Context Loading yang Efisien untuk AI Coding Assistant

    Merancang Context Loading yang Efisien untuk AI Coding Assistant

    Merancang Context Loading yang Efisien untuk AI Coding Assistant

    Bagaimana Mengurangi Pemborosan Token Tanpa Mengorbankan Pemahaman Proyek

    AI coding assistant seperti Claude Code, Codex, Cursor, dan berbagai agent berbasis LLM dapat mempercepat proses pengembangan aplikasi secara signifikan.

    Namun, ketika proyek mulai membesar, muncul sebuah masalah yang sering tidak terlihat pada tahap awal:

    Semakin besar proyek, semakin banyak konteks yang harus dibaca oleh AI sebelum bisa mulai bekerja.

    Pada proyek kecil, kita mungkin cukup memberikan satu file instruksi, beberapa dokumentasi, lalu meminta AI mengerjakan sebuah fitur.

    Tetapi seiring waktu, proyek biasanya mulai memiliki:

    • dokumentasi arsitektur,
    • aturan coding,
    • business rules,
    • struktur database,
    • keputusan teknis,
    • dokumentasi setiap modul,
    • prosedur deployment,
    • panduan testing,
    • catatan keamanan,
    • dan berbagai informasi lainnya.

    Masalahnya, tidak semua informasi tersebut relevan untuk setiap pekerjaan.

    Ketika AI harus membaca semuanya setiap memulai sesi, kita menghadapi beberapa konsekuensi:

    1. Penggunaan token menjadi lebih besar.
    2. Waktu orientasi agent menjadi lebih lama.
    3. Informasi penting mudah tenggelam di antara informasi yang tidak relevan.
    4. Risiko instruksi saling bertentangan meningkat.
    5. AI bisa kehilangan fokus terhadap pekerjaan yang sedang dilakukan.

    Artikel ini membahas sebuah pendekatan untuk mengatur konteks proyek secara bertingkat, sehingga AI hanya membaca informasi yang benar-benar diperlukan.

    Konsep utamanya sederhana:

    Jangan memuat seluruh pengetahuan proyek sejak awal. Muat konteks secara bertahap berdasarkan kebutuhan.


    Masalah Context Loading pada Workflow AI Coding

    Bayangkan kita memiliki proyek aplikasi yang cukup besar.

    Di dalamnya terdapat beberapa dokumen seperti:

    CLAUDE.md
    architecture.md
    database-schema.md
    security-guidelines.md
    api-conventions.md
    deployment-guide.md
    testing-guide.md
    module-auth.md
    module-payment.md
    module-notification.md
    

    Cara paling sederhana adalah meminta AI membaca semua file tersebut sebelum mulai bekerja.

    Workflow-nya menjadi seperti ini:

    Agent memulai sesi
    ↓
    Membaca instruksi utama
    ↓
    Membaca seluruh dokumentasi
    ↓
    Mencari file yang berkaitan
    ↓
    Membaca source code
    ↓
    Memahami konteks
    ↓
    Mulai mengerjakan task
    

    Pendekatan ini memang memberikan konteks lengkap, tetapi tidak selalu efisien.

    Ketika task-nya hanya memperbaiki tombol pada halaman tertentu, apakah AI benar-benar perlu membaca dokumentasi deployment, sistem pembayaran, struktur notifikasi, dan seluruh keputusan arsitektur?

    Kemungkinan besar tidak.

    Yang sebenarnya kita butuhkan adalah mekanisme seperti ini:

    Agent memulai sesi
    ↓
    Membaca instruksi global yang ringkas
    ↓
    Mengidentifikasi konteks task
    ↓
    Mengambil aturan dan dokumentasi yang relevan
    ↓
    Membaca source code terkait
    ↓
    Mulai bekerja
    

    Perbedaannya terlihat kecil, tetapi pada proyek besar dampaknya bisa sangat signifikan.


    Kesalahpahaman tentang Memecah CLAUDE.md

    Salah satu ide yang cukup alami adalah memecah satu file CLAUDE.md besar menjadi banyak file Markdown kecil.

    Contohnya:

    CLAUDE.md
    docs/
    β”œβ”€β”€ architecture.md
    β”œβ”€β”€ security.md
    β”œβ”€β”€ database.md
    β”œβ”€β”€ testing.md
    └── deployment.md
    

    Kemudian CLAUDE.md dijadikan semacam index:

    @docs/architecture.md
    @docs/security.md
    @docs/database.md
    @docs/testing.md
    @docs/deployment.md
    

    Struktur tersebut memang jauh lebih rapi untuk manusia.

    Namun, berdasarkan dokumentasi Claude Code, file yang dimasukkan menggunakan mekanisme @import tetap dimuat ke dalam context window.

    Artinya:

    Satu CLAUDE.md besar
    

    dan:

    CLAUDE.md yang mengimpor banyak file
    

    dapat menghasilkan penggunaan context yang hampir sama.

    Memecah file menggunakan @import bermanfaat untuk:

    • organisasi dokumentasi,
    • kemudahan maintenance,
    • pembagian tanggung jawab file,
    • kenyamanan membaca.

    Tetapi bukan untuk mengurangi token.

    Kesimpulannya:

    @import adalah alat organisasi, bukan mekanisme lazy loading.

    Untuk menghemat context, kita membutuhkan mekanisme yang benar-benar hanya memuat informasi ketika diperlukan.


    Tiga Mekanisme Lazy Loading di Claude Code

    Claude Code menyediakan beberapa mekanisme yang lebih cocok untuk context loading bertahap.

    1. Path-Scoped Rules

    Claude Code mendukung file aturan di dalam folder:

    .claude/rules/
    

    Aturan tersebut dapat diberi frontmatter paths.

    Contoh:

    ---
    paths:
      - "app/api/**/*.ts"
    ---
    
    # API Route Conventions
    
    - Semua input harus divalidasi.
    - Response harus menggunakan format standar.
    - Error internal tidak boleh ditampilkan kepada user.
    - Setiap endpoint sensitif harus memiliki authorization check.
    

    Rule tersebut hanya relevan ketika Claude bekerja dengan file yang cocok dengan pattern:

    app/api/**/*.ts
    

    Jika Claude hanya mengedit komponen frontend, rule untuk API tidak perlu masuk ke context.

    Contoh struktur:

    .claude/
    └── rules/
        β”œβ”€β”€ api-routes.md
        β”œβ”€β”€ components.md
        β”œβ”€β”€ database.md
        β”œβ”€β”€ migrations.md
        └── testing.md
    

    Setiap rule memiliki cakupan path masing-masing.

    Path-scoped rules cocok untuk menjawab pertanyaan:

    Ketika mengedit jenis file ini, aturan apa yang harus dipatuhi?

    Contohnya:

    • aturan API route,
    • aturan React component,
    • aturan database query,
    • aturan migration,
    • aturan testing,
    • aturan server action,
    • aturan keamanan file tertentu.

    Hal penting yang perlu diperhatikan, rule tanpa paths dapat tetap dianggap sebagai instruksi global.

    Jadi, jika tujuan kita adalah lazy loading, pastikan aturan tersebut benar-benar memiliki cakupan path yang sesuai.


    2. Nested CLAUDE.md

    Selain CLAUDE.md utama di root proyek, kita juga dapat menempatkan CLAUDE.md di dalam subfolder tertentu.

    Contohnya:

    project/
    β”œβ”€β”€ CLAUDE.md
    └── src/
        └── modules/
            β”œβ”€β”€ authentication/
            β”‚   β”œβ”€β”€ CLAUDE.md
            β”‚   └── ...
            β”œβ”€β”€ payment/
            β”‚   β”œβ”€β”€ CLAUDE.md
            β”‚   └── ...
            └── notification/
                β”œβ”€β”€ CLAUDE.md
                └── ...
    

    CLAUDE.md utama berisi aturan yang berlaku untuk seluruh proyek.

    Sementara itu, CLAUDE.md di dalam modul payment hanya dibutuhkan ketika agent bekerja di dalam modul payment.

    Nested CLAUDE.md cocok untuk menjelaskan:

    • tanggung jawab modul,
    • batas modul,
    • invariant domain,
    • entry point utama,
    • hubungan dengan modul lain,
    • hal-hal yang tidak boleh dilakukan modul tersebut.

    Contohnya:

    # Payment Module
    
    ## Responsibility
    
    Modul ini menangani pembuatan transaksi, komunikasi dengan payment provider,
    callback, reconciliation, dan perubahan status pembayaran.
    
    ## Boundaries
    
    - Tidak menangani entitlement user.
    - Tidak mengirim email secara langsung.
    - Tidak mengakses komponen UI.
    - Semua komunikasi provider harus melalui adapter.
    
    ## Main Entry Points
    
    - createPayment()
    - handlePaymentCallback()
    - reconcilePayment()
    

    Nested CLAUDE.md menjawab pertanyaan:

    Apa fungsi modul ini dan bagaimana batas tanggung jawabnya?

    Ini berbeda dengan path-scoped rule.

    Path-scoped rule menjelaskan aturan saat mengedit jenis file tertentu, sedangkan nested CLAUDE.md menjelaskan mental model dari sebuah area atau modul.


    3. Skills

    Tidak semua instruksi perlu aktif setiap saat.

    Beberapa instruksi hanya dibutuhkan ketika kita menjalankan workflow tertentu, misalnya:

    • membuat migration,
    • menambahkan payment provider,
    • melakukan deployment,
    • menjalankan security review,
    • membuat release,
    • memperbaiki CI,
    • memperbarui dokumentasi,
    • melakukan audit repository.

    Instruksi seperti ini lebih cocok dijadikan skill.

    Contoh struktur:

    .claude/
    └── skills/
        β”œβ”€β”€ deploy-production/
        β”‚   └── SKILL.md
        β”œβ”€β”€ create-migration/
        β”‚   └── SKILL.md
        β”œβ”€β”€ security-review/
        β”‚   └── SKILL.md
        └── update-documentation/
            └── SKILL.md
    

    Skill cocok untuk prosedur yang memiliki:

    1. kondisi awal,
    2. urutan proses,
    3. checkpoint,
    4. validasi,
    5. output akhir.

    Sebagai contoh, prosedur deployment mungkin mencakup:

    Periksa status Git
    ↓
    Jalankan test
    ↓
    Build aplikasi
    ↓
    Buat backup
    ↓
    Deploy
    ↓
    Verifikasi production
    ↓
    Buat laporan
    

    Prosedur ini tidak perlu berada di context setiap kali agent hanya memperbaiki tampilan tombol.

    Skill dapat dimuat ketika:

    • dipanggil secara eksplisit,
    • atau dianggap relevan dengan task yang sedang dikerjakan.

    Dengan demikian, skills menggunakan konsep progressive disclosure, yaitu informasi lengkap baru diberikan ketika benar-benar diperlukan.


    Auto Memory sebagai Catatan Pembelajaran Agent

    Claude Code juga memiliki mekanisme auto memory.

    Secara konseptual, strukturnya menyerupai:

    memory/
    β”œβ”€β”€ MEMORY.md
    β”œβ”€β”€ debugging.md
    β”œβ”€β”€ api-conventions.md
    β”œβ”€β”€ environment-notes.md
    └── testing-notes.md
    

    MEMORY.md berfungsi sebagai index ringkas yang dibaca saat sesi dimulai.

    Sementara file topik lain dapat dibaca ketika dibutuhkan.

    Pola ini menunjukkan bahwa konsep berikut memang valid:

    Index kecil selalu tersedia, detail dibaca on-demand.

    Namun, auto memory sebaiknya tidak dianggap sebagai dokumentasi resmi proyek.

    Auto memory lebih cocok untuk menyimpan pembelajaran seperti:

    • command tertentu bermasalah pada sistem operasi tertentu,
    • test tertentu membutuhkan environment khusus,
    • kebiasaan lokal dalam repository,
    • koreksi yang berulang kali diberikan kepada agent,
    • shortcut atau teknik debugging tertentu.

    Auto memory sebaiknya diperlakukan sebagai inbox pembelajaran.

    Jika sebuah informasi sudah:

    • terbukti benar,
    • berlaku untuk semua anggota tim,
    • penting untuk konsistensi proyek,
    • dan perlu menjadi aturan resmi,

    maka informasi tersebut sebaiknya dipindahkan ke salah satu tempat berikut:

    CLAUDE.md
    Path-scoped rule
    Nested CLAUDE.md
    Skill
    Canonical documentation
    

    Memisahkan Instruksi dan Pengetahuan

    Salah satu kesalahan yang sering terjadi adalah mencampurkan semua jenis informasi ke dalam CLAUDE.md.

    Padahal, tidak semua informasi memiliki fungsi yang sama.

    Ada perbedaan antara:

    • instruksi,
    • fakta sistem,
    • prosedur,
    • hubungan source code,
    • dan konteks task.

    Sebagai contoh:

    Semua perubahan status pembayaran harus melalui PaymentService.
    

    Ini adalah invariant atau aturan sistem.

    Informasi tersebut cocok ditempatkan dalam rule atau dokumentasi modul.

    Namun informasi seperti:

    PaymentService berada di file tertentu dan dipanggil oleh empat file lain.
    

    adalah hubungan source code yang dapat berubah sewaktu-waktu.

    Jika hubungan tersebut ditulis manual dalam dokumentasi, informasinya mudah menjadi basi.

    Untuk jenis pengetahuan seperti ini, knowledge graph dapat membantu.


    Memanfaatkan Knowledge Graph dengan Graphify

    Graphify adalah tool yang dapat memetakan source code, dokumentasi, PDF, gambar, dan berbagai jenis file menjadi sebuah knowledge graph.

    Untuk source code, Graphify menggunakan parsing berbasis AST atau Abstract Syntax Tree.

    Dari source code, Graphify dapat menemukan hubungan seperti:

    • file mengimpor file lain,
    • fungsi memanggil fungsi lain,
    • class menggunakan interface,
    • class mewarisi class lain,
    • route terhubung ke service,
    • service terhubung ke database,
    • test berhubungan dengan modul tertentu.

    Hasilnya disimpan dalam beberapa file:

    graphify-out/
    β”œβ”€β”€ graph.json
    β”œβ”€β”€ GRAPH_REPORT.md
    └── graph.html
    

    graph.json menjadi indeks hubungan proyek yang bisa ditanya kembali.

    Contoh query:

    graphify query "Bagaimana alur authentication bekerja?"
    
    graphify query "Apa yang terpengaruh jika struktur user diubah?"
    
    graphify path "CheckoutPage" "PaymentProvider"
    
    graphify explain "PaymentService"
    

    Alih-alih membaca seluruh repository, agent dapat menggunakan graph untuk menemukan bagian yang kemungkinan besar relevan.

    Workflow-nya menjadi:

    Task diberikan
    ↓
    Agent menanyakan task kepada graph
    ↓
    Graph mengembalikan konsep dan file terkait
    ↓
    Agent membaca file yang relevan
    ↓
    Agent melakukan perubahan
    

    Graphify tidak menggantikan dokumentasi.

    Graphify menjawab pertanyaan:

    Apa yang berhubungan dengan bagian ini?

    Sementara dokumentasi menjawab:

    Mengapa sistem ini dirancang seperti ini dan aturan bisnis apa yang berlaku?

    Keduanya memiliki fungsi berbeda.


    Perbedaan Path Rules dan Knowledge Graph

    Path-scoped rules dan knowledge graph sering terlihat mirip, tetapi sebenarnya menyelesaikan masalah yang berbeda.

    Path-scoped rule

    Menjawab:

    Ketika mengedit file ini, aturan apa yang harus dipatuhi?

    Contoh:

    ---
    paths:
      - "src/modules/payment/providers/**/*.ts"
    ---
    
    # Payment Provider Rules
    
    - Semua request wajib memiliki timeout.
    - Jangan mencatat credential ke log.
    - Response provider harus divalidasi.
    - Callback harus idempotent.
    

    Knowledge graph

    Menjawab:

    File dan konsep apa yang terhubung dengan perubahan ini?

    Contoh query:

    graphify query "Apa yang terdampak jika callback payment diubah?"
    

    Graph dapat menemukan hubungan:

    Callback Handler
    β†’ Payment Service
    β†’ Transaction Table
    β†’ Billing UI
    β†’ Notification
    β†’ Integration Tests
    

    Jadi:

    Rules
    = bagaimana agent harus bekerja
    
    Knowledge graph
    = di mana agent harus melihat
    

    Canonical Documentation Tetap Menjadi Source of Truth

    Meskipun knowledge graph sangat membantu, dokumentasi sistem tetap diperlukan.

    Ada banyak informasi yang tidak bisa diketahui hanya dengan membaca source code.

    Contohnya:

    • alasan sebuah keputusan dibuat,
    • business rules,
    • batasan produk,
    • kebijakan keamanan,
    • permission model,
    • lifecycle sebuah entitas,
    • risiko yang telah dipertimbangkan,
    • trade-off arsitektur,
    • keputusan yang sengaja tidak diimplementasikan.

    Informasi tersebut sebaiknya disimpan di dalam canonical documentation.

    Contoh struktur:

    docs/
    └── canonical/
        β”œβ”€β”€ system-overview.md
        β”œβ”€β”€ architecture.md
        β”œβ”€β”€ business-rules.md
        β”œβ”€β”€ database-schema.md
        β”œβ”€β”€ security-model.md
        β”œβ”€β”€ modules/
        └── decisions/
    

    Canonical documentation menjadi sumber resmi yang dapat dibaca oleh manusia dan AI.

    Knowledge graph kemudian dibuat dari:

    Source code
    +
    Canonical documentation
    

    Dengan demikian, graph dapat menghubungkan implementasi teknis dengan alasan dan keputusan di baliknya.

    Prinsip pentingnya:

    Dokumentasi kanonik diedit secara langsung. Graph dan index lainnya dihasilkan secara otomatis.


    Enam Lapisan Context Architecture

    Setelah memisahkan fungsi masing-masing mekanisme, kita dapat merancang arsitektur konteks dalam enam lapisan.

    1. Core Session Context

    Media:

    CLAUDE.md
    

    Berisi informasi yang harus diketahui dalam hampir setiap sesi:

    • identitas singkat proyek,
    • stack utama,
    • command penting,
    • source of truth,
    • larangan global,
    • aturan Git,
    • prinsip keamanan,
    • cara mencari konteks,
    • format laporan akhir.

    CLAUDE.md sebaiknya berfungsi sebagai bootstrap atau bootloader agent, bukan ensiklopedia proyek.


    2. Path Context

    Media:

    .claude/rules/
    Nested CLAUDE.md
    

    Berisi konteks yang hanya relevan ketika agent menyentuh bagian tertentu.

    Contohnya:

    • aturan API,
    • aturan component,
    • aturan migration,
    • mental model modul,
    • batas tanggung jawab domain.

    3. Procedural Context

    Media:

    Skills
    

    Berisi workflow multi-langkah yang hanya digunakan pada situasi tertentu.

    Contohnya:

    • deployment,
    • release,
    • security review,
    • migration,
    • integrasi baru,
    • audit repository.

    4. Canonical Knowledge

    Media:

    docs/canonical/
    

    Berisi pengetahuan resmi proyek:

    • arsitektur,
    • business rules,
    • database schema,
    • API contract,
    • keputusan teknis,
    • security model,
    • dokumentasi modul.

    5. Repository Knowledge

    Media:

    Graphify
    

    Berisi hubungan yang ditemukan atau dihitung dari source code dan dokumentasi:

    • dependency,
    • call flow,
    • import,
    • hubungan lintas file,
    • hubungan kode dengan dokumentasi,
    • kemungkinan area terdampak.

    6. Task Context

    Media:

    Task Context Package
    

    Task Context Package adalah kumpulan konteks yang dipilih secara khusus untuk satu pekerjaan.

    Contohnya:

    Task:
    Tambahkan logout pada menu profil.
    
    Relevant context:
    - authentication architecture,
    - session lifecycle,
    - UI component terkait,
    - fungsi sign out,
    - security rule,
    - test yang relevan,
    - acceptance criteria.
    

    Task Context Package dapat dihasilkan dari:

    Task
    +
    Canonical documentation
    +
    Knowledge graph
    +
    Relevant rules
    

    Hasil akhirnya adalah context kecil yang sangat spesifik.


    Alur Context Loading yang Ideal

    Dengan seluruh lapisan tersebut, context loading dapat berlangsung secara bertahap.

    CLAUDE.md utama
    ↓
    Identifikasi task
    ↓
    Query knowledge graph
    ↓
    Temukan source code dan dokumentasi terkait
    ↓
    Buka file yang relevan
    ↓
    Path-scoped rules aktif
    ↓
    Nested CLAUDE.md modul aktif
    ↓
    Skill dimuat jika diperlukan
    ↓
    Task Context Package terbentuk
    ↓
    Agent mulai bekerja
    

    Pendekatan ini jauh lebih efisien dibandingkan memuat semua dokumentasi sejak awal.


    Kerangka Keputusan: Informasi Ini Harus Diletakkan di Mana?

    Berikut checklist yang dapat digunakan setiap kali ada instruksi atau pengetahuan baru.

    Masukkan ke CLAUDE.md jika:

    • informasi wajib diketahui dalam hampir semua sesi,
    • ketidaktahuan terhadap informasi tersebut dapat menyebabkan kesalahan besar,
    • isinya singkat dan relatif stabil,
    • berlaku untuk seluruh repository.

    Contoh:

    • jangan menambah dependency tanpa persetujuan,
    • dokumentasi resmi berada di docs/canonical,
    • semua perubahan database harus memakai migration,
    • jangan pernah mencatat secret,
    • jalankan test utama sebelum menyelesaikan task.

    Masukkan ke path-scoped rule jika:

    • instruksi hanya berlaku pada pola file tertentu,
    • aturan dapat dipetakan ke glob path yang stabil,
    • tidak relevan untuk sebagian besar task lain.

    Contoh:

    • konvensi API route,
    • aturan React component,
    • standar migration,
    • validasi database query,
    • aturan test.

    Gunakan nested CLAUDE.md jika:

    • informasi menjelaskan satu modul atau domain besar,
    • seluruh file dalam folder tersebut memerlukan mental model yang sama,
    • informasi membahas responsibility dan boundary.

    Contoh:

    • tanggung jawab modul authentication,
    • batas modul payment,
    • invariant domain order,
    • entry point utama modul media.

    Jadikan skill jika:

    • informasinya merupakan prosedur multi-langkah,
    • hanya digunakan pada situasi tertentu,
    • memiliki checkpoint dan validasi,
    • dapat dipanggil sebagai workflow.

    Contoh:

    • deploy,
    • release,
    • audit keamanan,
    • membuat migration,
    • menambahkan provider baru.

    Masukkan ke canonical documentation jika:

    • merupakan fakta resmi sistem,
    • perlu dibaca manusia dan AI,
    • menjelaskan alasan, keputusan, atau aturan bisnis,
    • harus menjadi rujukan jangka panjang.

    Contoh:

    • arsitektur,
    • business rules,
    • schema database,
    • permission model,
    • keputusan teknis.

    Serahkan kepada knowledge graph jika:

    • informasi dapat dihitung dari repository,
    • hubungan tersebut sering berubah mengikuti kode,
    • menulisnya secara manual akan mudah basi.

    Contoh:

    • fungsi mana memanggil fungsi tertentu,
    • file mana menggunakan sebuah service,
    • test apa yang berkaitan dengan suatu modul,
    • route mana terhubung ke database tertentu.

    Masukkan ke auto memory jika:

    • merupakan pembelajaran lokal atau sementara,
    • belum layak menjadi aturan resmi,
    • berasal dari pengalaman agent selama bekerja.

    Contoh:

    • command tertentu gagal pada environment tertentu,
    • fixture tertentu sering terlupakan,
    • teknik debugging lokal.

    Gunakan hook, lint, test, atau CI jika:

    • aturan harus benar-benar dijalankan,
    • kegagalannya tidak boleh hanya bergantung pada ingatan AI.

    Contoh:

    Instruksi:
    Jalankan type check sebelum commit.
    
    Enforcement:
    Pre-commit hook atau CI menjalankan type check.
    

    Instruksi menjelaskan perilaku yang diharapkan.

    Hook dan CI memastikan perilaku tersebut benar-benar terjadi.


    Struktur Folder yang Dapat Digunakan

    Berikut salah satu contoh struktur yang dapat direplikasi pada berbagai proyek:

    project/
    β”œβ”€β”€ CLAUDE.md
    β”œβ”€β”€ AGENTS.md
    β”‚
    β”œβ”€β”€ .claude/
    β”‚   β”œβ”€β”€ rules/
    β”‚   β”‚   β”œβ”€β”€ frontend/
    β”‚   β”‚   β”œβ”€β”€ backend/
    β”‚   β”‚   β”œβ”€β”€ security/
    β”‚   β”‚   β”œβ”€β”€ testing/
    β”‚   β”‚   └── documentation/
    β”‚   β”‚
    β”‚   β”œβ”€β”€ skills/
    β”‚   β”‚   β”œβ”€β”€ deploy/
    β”‚   β”‚   β”œβ”€β”€ release/
    β”‚   β”‚   β”œβ”€β”€ create-migration/
    β”‚   β”‚   β”œβ”€β”€ security-review/
    β”‚   β”‚   └── update-documentation/
    β”‚   β”‚
    β”‚   └── settings.json
    β”‚
    β”œβ”€β”€ docs/
    β”‚   β”œβ”€β”€ canonical/
    β”‚   β”‚   β”œβ”€β”€ system-overview.md
    β”‚   β”‚   β”œβ”€β”€ architecture.md
    β”‚   β”‚   β”œβ”€β”€ business-rules.md
    β”‚   β”‚   β”œβ”€β”€ database-schema.md
    β”‚   β”‚   β”œβ”€β”€ security-model.md
    β”‚   β”‚   β”œβ”€β”€ modules/
    β”‚   β”‚   └── decisions/
    β”‚   β”‚
    β”‚   └── generated/
    β”‚       β”œβ”€β”€ task-context/
    β”‚       β”œβ”€β”€ summaries/
    β”‚       └── indexes/
    β”‚
    β”œβ”€β”€ graphify-out/
    β”‚   β”œβ”€β”€ graph.json
    β”‚   β”œβ”€β”€ GRAPH_REPORT.md
    β”‚   └── graph.html
    β”‚
    └── src/
        └── modules/
            β”œβ”€β”€ authentication/
            β”‚   └── CLAUDE.md
            β”œβ”€β”€ payment/
            β”‚   └── CLAUDE.md
            └── notification/
                └── CLAUDE.md
    

    Struktur ini tidak harus diterapkan secara lengkap sejak hari pertama.

    Pada proyek kecil, kita mungkin hanya membutuhkan:

    CLAUDE.md
    docs/
    src/
    

    Ketika proyek berkembang, kita dapat menambahkan:

    Path-scoped rules
    Nested CLAUDE.md
    Skills
    Graphify
    Task Context Package
    

    Arsitektur konteks sebaiknya tumbuh mengikuti kompleksitas proyek.


    Contoh CLAUDE.md sebagai Bootstrap Agent

    Berikut contoh sederhana:

    # Project Agent Bootstrap
    
    ## Project
    
    Aplikasi ini adalah platform manajemen workflow berbasis web.
    
    ## Source of Truth
    
    - Source code berada di repository ini.
    - Dokumentasi resmi berada di `docs/canonical/`.
    - Keputusan arsitektur berada di `docs/canonical/decisions/`.
    - File generated tidak boleh diedit secara langsung.
    
    ## Core Commands
    
    - Development: `npm run dev`
    - Test: `npm test`
    - Type check: `npm run typecheck`
    - Build: `npm run build`
    
    ## Mandatory Rules
    
    - Jangan menambah package tanpa persetujuan.
    - Jangan mengubah database tanpa migration.
    - Jangan membaca atau menampilkan secret.
    - Jangan push sebelum pengujian utama lulus.
    - Jaga backward compatibility kecuali task menyatakan sebaliknya.
    
    ## Context Loading
    
    Sebelum membaca repository secara luas:
    
    1. Gunakan knowledge graph untuk memetakan konteks task.
    2. Baca hanya dokumentasi kanonik yang relevan.
    3. Baca source code yang berkaitan dengan task.
    4. Muat skill jika task membutuhkan prosedur khusus.
    5. Verifikasi keputusan penting terhadap source code atau dokumentasi resmi.
    
    ## Task Completion
    
    Laporan akhir harus mencakup:
    
    - perubahan yang dilakukan,
    - file yang berubah,
    - pengujian,
    - risiko,
    - status Git.
    

    File ini tidak mencoba menjelaskan seluruh proyek.

    Fungsinya adalah memberi tahu agent:

    • di mana sumber kebenaran berada,
    • bagaimana cara mencari konteks,
    • aturan global apa yang wajib dipatuhi,
    • seperti apa definisi task selesai.

    Mengurangi Beban Maintenance

    Arsitektur modular memang dapat menghemat context, tetapi juga bisa menciptakan maintenance baru.

    Untuk menghindarinya, ada beberapa prinsip yang dapat digunakan.

    1. Pisahkan Berdasarkan Tingkat Kestabilan

    Sangat stabil
    β†’ CLAUDE.md utama
    
    Stabil per modul
    β†’ Nested CLAUDE.md
    
    Stabil per jenis file
    β†’ Path-scoped rules
    
    Berubah mengikuti source code
    β†’ Knowledge graph
    
    Prosedural
    β†’ Skills
    
    Pengetahuan resmi
    β†’ Canonical documentation
    

    Jangan menaruh hubungan source code yang cepat berubah ke dalam instruksi global.


    2. Gunakan Glob Berdasarkan Boundary

    Lebih baik:

    paths:
      - "src/modules/payment/**/*.ts"
    

    Daripada:

    paths:
      - "src/modules/payment/services/payment-service.ts"
    

    Rule berbasis boundary modul lebih tahan terhadap perubahan struktur internal.


    3. Hindari Duplikasi

    Satu aturan idealnya memiliki satu lokasi utama.

    Contohnya:

    Aturan global keamanan
    β†’ CLAUDE.md
    
    Aturan keamanan API
    β†’ api-security rule
    
    Security architecture
    β†’ canonical documentation
    
    Security review workflow
    β†’ skill
    

    Jangan menyalin seluruh isi security documentation ke semua tempat.

    Cukup letakkan prinsip dan referensi sesuai fungsinya.


    4. Audit Secara Berkala

    Tidak perlu mengaudit context setiap hari.

    Audit dapat dilakukan pada:

    • akhir sprint,
    • akhir milestone,
    • setelah refactor besar,
    • setelah perubahan struktur folder,
    • sebelum onboarding agent baru.

    Hal yang dapat diperiksa:

    • apakah CLAUDE.md terlalu panjang,
    • apakah ada rule yang tidak pernah digunakan,
    • apakah ada skill yang tumpang tindih,
    • apakah auto memory perlu dipromosikan menjadi aturan resmi,
    • apakah graph masih sesuai dengan commit terbaru,
    • apakah terdapat instruksi yang bertentangan.

    Apakah Pendekatan Ini Benar-Benar Menghemat Token?

    Jawabannya, ya, terutama pada proyek yang:

    • berumur panjang,
    • memiliki banyak modul,
    • dikerjakan dalam banyak sesi,
    • menggunakan beberapa AI agent,
    • memiliki dokumentasi cukup besar,
    • sering mengalami perpindahan konteks.

    Namun penghematannya tidak selalu langsung terlihat pada hari pertama.

    Knowledge graph, rules, skills, dan dokumentasi modular membutuhkan investasi awal.

    Secara sederhana:

    Tanpa arsitektur context:
    
    20 sesi
    Γ—
    membaca banyak dokumentasi dan source code
    

    Dengan arsitektur context:

    1 kali membangun struktur context
    +
    20 sesi
    Γ—
    membaca context terpilih
    

    Semakin panjang umur proyek, semakin besar manfaatnya.


    Hal yang Perlu Diwaspadai

    Knowledge Graph Bukan Sumber Kebenaran

    Graph dapat memiliki hubungan hasil inferensi.

    Karena itu:

    Graph membantu menemukan sumber.
    Source code dan dokumentasi resmi tetap menjadi bukti.
    

    Keputusan penting tetap harus diverifikasi.


    Graph Dapat Menjadi Basi

    Jika source code berubah tetapi graph tidak diperbarui, agent dapat menerima informasi lama.

    Solusinya dapat berupa:

    • incremental update,
    • Git hook,
    • CI check,
    • pencatatan commit SHA,
    • pencatatan versi graph,
    • validasi graph terhadap repository HEAD.

    Terlalu Banyak Rules Juga Menjadi Masalah

    Memecah satu file besar menjadi puluhan aturan kecil tidak otomatis menghasilkan sistem yang lebih baik.

    Terlalu banyak rule dapat menyebabkan:

    • duplikasi,
    • konflik,
    • kesulitan menemukan sumber aturan,
    • maintenance yang berat.

    Setiap rule sebaiknya memiliki boundary yang jelas.


    Instruksi Tidak Sama dengan Enforcement

    Menulis:

    Selalu jalankan test.
    

    tidak menjamin test benar-benar dijalankan.

    Aturan kritis sebaiknya didukung oleh:

    • hooks,
    • CI,
    • lint,
    • type checking,
    • permission,
    • automated tests.

    Kesimpulan

    Efisiensi context loading bukan hanya soal memperpendek satu file instruksi.

    Masalah sebenarnya adalah menentukan:

    • informasi apa yang harus selalu tersedia,
    • informasi apa yang hanya relevan untuk path tertentu,
    • prosedur apa yang hanya perlu dimuat ketika digunakan,
    • pengetahuan apa yang menjadi sumber resmi,
    • hubungan apa yang sebaiknya dihitung otomatis,
    • dan konteks apa yang dibutuhkan untuk satu task tertentu.

    Arsitektur yang saya anggap cukup ideal adalah:

    CLAUDE.md
    = konteks inti setiap sesi
    
    Path-scoped rules
    = aturan berdasarkan file yang sedang dikerjakan
    
    Nested CLAUDE.md
    = mental model modul
    
    Skills
    = prosedur multi-langkah
    
    Canonical documentation
    = sumber kebenaran proyek
    
    Knowledge graph
    = peta hubungan source code dan dokumentasi
    
    Auto memory
    = inbox pembelajaran lokal
    
    Hooks dan CI
    = enforcement
    
    Task Context Package
    = konteks terpilih untuk satu pekerjaan
    

    Dengan pendekatan tersebut, AI coding assistant tidak harus mengetahui seluruh proyek sejak awal.

    Ia hanya perlu mengetahui:

    1. di mana mencari informasi,
    2. bagaimana memilih informasi yang relevan,
    3. aturan apa yang berlaku,
    4. dan sumber mana yang harus dipercaya.

    Tujuan akhirnya bukan sekadar mengurangi token.

    Tujuan yang lebih penting adalah membuat AI bekerja dengan konteks yang:

    • lebih fokus,
    • lebih akurat,
    • lebih mudah diverifikasi,
    • lebih mudah dirawat,
    • dan lebih konsisten di berbagai sesi.

    Saya masih terus mengeksplorasi pendekatan ini dan kemungkinan akan memperbarui artikel ini seiring bertambahnya pengalaman penggunaan di proyek nyata.

    Apabila Anda menggunakan Claude Code, Codex, Cursor, atau AI coding assistant lainnya, saya tertarik mengetahui bagaimana Anda mengatur context proyek.

    Apakah Anda menggunakan satu file instruksi besar, dokumentasi modular, skills, knowledge graph, atau pendekatan lain?

    Silakan bagikan pengalaman, kendala, dan struktur yang Anda gunakan di kolom komentar. Diskusi dari berbagai pengalaman mungkin dapat membantu kita menemukan pola kerja AI-assisted development yang lebih efektif dan efisien.


    Referensi

    Catatan: Fitur dan perilaku tool AI dapat berubah dengan cepat. Penjelasan teknis dalam artikel ini mengacu pada dokumentasi yang tersedia pada Juli 2026. Periksa dokumentasi resmi terbaru sebelum menerapkan konfigurasi pada proyek produksi.

  • Mengatasi 403 Forbidden Saat Deploy Next.js ke Hostinger dengan output: “standalone”

    Mengatasi 403 Forbidden Saat Deploy Next.js ke Hostinger dengan output: “standalone”

    Saya baru saja mengalami masalah yang cukup membingungkan ketika mencoba melakukan deployment aplikasi Next.js ke Hostinger Web App Hosting.

    Proses build berhasil. Tidak ada vulnerability. Dashboard Hostinger menunjukkan deployment telah selesai dan aplikasi berstatus Running.

    Namun, ketika domain dibuka, halaman yang tampil justru:

    403 Forbidden
    Access to this resource on the server is denied!

    Hal yang membuat masalah ini semakin membingungkan adalah aplikasi berjalan normal di localhost. Halaman utama bisa dibuka, endpoint API bekerja, dan production build selesai tanpa error.

    Setelah melakukan pemeriksaan satu per satu, ternyata masalahnya bukan pada domain, SSL, kode halaman, atau environment variables.

    Masalahnya ada pada cara Next.js menghasilkan paket deployment.

    Solusi yang akhirnya berhasil adalah menambahkan:

    output: "standalone"

    ke dalam konfigurasi Next.js.

    Artikel ini menjelaskan proses diagnosisnya, alasan solusi tersebut bekerja, dan langkah-langkah yang bisa dicoba ketika mengalami masalah serupa.


    Gejala yang Terjadi

    Berikut kondisi deployment pada saat masalah muncul:

    • repository GitHub berhasil terhubung ke Hostinger,
    • framework terdeteksi sebagai Next.js,
    • proses npm install berhasil,
    • proses next build berhasil,
    • tidak ada vulnerability dari npm audit,
    • deployment berstatus Completed,
    • aplikasi berstatus Running,
    • domain dan SSL sudah aktif,
    • tetapi halaman utama tetap menampilkan 403 Forbidden.

    Build log terlihat normal:

    Creating an optimized production build ...
    Compiled successfully
    Generating static pages ...
    Finalizing page optimization ...
    
    Route (app)
    β”Œ β—‹ /
    β”œ β—‹ /_not-found
    β”” Ζ’ /api/health

    Secara sekilas, tidak ada tanda bahwa deployment mengalami kegagalan.


    Memastikan Aplikasi Berjalan di Localhost

    Sebelum mengubah konfigurasi hosting, langkah pertama yang sebaiknya dilakukan adalah memastikan aplikasi memang dapat berjalan dalam mode production di komputer lokal.

    Jalankan:

    npm run build
    npm run start

    Kemudian buka:

    http://127.0.0.1:3000

    Pada kasus saya, halaman utama berhasil ditampilkan.

    Endpoint API juga bekerja:

    http://127.0.0.1:3000/api/health

    Respons yang diterima:

    {
      "status": "ok",
      "runtime": "nextjs",
      "timestamp": "2026-07-30T05:16:50.459Z"
    }

    Hasil ini membuktikan bahwa:

    • source code dapat dikompilasi,
    • Next.js dapat dijalankan dalam mode production,
    • halaman utama bekerja,
    • route dinamis bekerja,
    • masalah kemungkinan berada pada proses packaging atau runtime hosting.

    Build Berhasil Belum Tentu Runtime Berhasil

    Salah satu pelajaran penting dari masalah ini adalah:

    Build yang berhasil tidak selalu berarti aplikasi server-side sudah memiliki runtime yang dapat menerima request.

    Perintah berikut:

    next build

    memang menghasilkan folder .next.

    Namun, folder .next pada konfigurasi default belum tentu menjadi paket deployment mandiri yang dapat langsung dijalankan oleh setiap platform hosting.

    Pada banyak server, aplikasi Next.js default dijalankan menggunakan:

    next start

    Perintah tersebut masih mengandalkan struktur repository, package Next.js, dan dependency yang tersedia dalam environment server.

    Hostinger menyediakan managed Web App Hosting yang menangani build, runtime Node.js, process management, routing, dan integrasi GitHub. Aplikasi Next.js yang menggunakan SSR, API route, atau fitur server-side memerlukan proses Node.js yang terus berjalan.


    Memeriksa Struktur File Deployment

    Langkah diagnosis berikutnya adalah membuka File Manager Hostinger.

    Pada deployment yang bermasalah, struktur root hanya berisi:

    .builds/
    public_html/
    DO_NOT_UPLOAD_HERE

    Tidak ada folder:

    nodejs/

    Di dalam public_html, justru terdapat isi build .next, seperti:

    public_html/
    β”œβ”€β”€ server/
    β”œβ”€β”€ static/
    β”œβ”€β”€ cache/
    β”œβ”€β”€ build-manifest.json
    β”œβ”€β”€ routes-manifest.json
    └── file build Next.js lainnya

    File .htaccess yang tersedia juga tidak meneruskan request ke runtime Node.js.

    Isinya hanya berupa perlindungan terhadap folder build:

    RewriteRule ^\.builds - [F,L]

    Artinya, Apache menerima request dari browser, tetapi tidak memiliki aplikasi Node.js yang menjadi tujuan request tersebut.

    Hasilnya adalah 403 Forbidden.


    Membandingkan dengan Deployment Next.js yang Berhasil

    Untuk mencari perbedaannya, saya membandingkan struktur tersebut dengan aplikasi Next.js lain yang berhasil berjalan di akun Hostinger yang sama.

    Deployment yang berhasil memiliki struktur:

    .builds/
    nodejs/
    public_html/

    Di dalam folder nodejs, terdapat:

    nodejs/
    β”œβ”€β”€ .next/
    β”œβ”€β”€ node_modules/
    β”œβ”€β”€ public/
    β”œβ”€β”€ tmp/
    β”œβ”€β”€ package.json
    β”œβ”€β”€ server.js
    β”œβ”€β”€ console.log
    └── stderr.log

    Sementara itu, public_html hanya berisi .htaccess.

    Isi .htaccess mengarahkan request ke aplikasi Node.js melalui Passenger:

    PassengerAppRoot /home/username/domains/example.com/nodejs
    PassengerAppType node
    PassengerNodejs /path/to/node
    PassengerStartupFile server.js
    PassengerBaseURI /
    PassengerRestartDir /home/username/domains/example.com/nodejs/tmp

    Alur request pada deployment yang benar menjadi:

    Browser
       ↓
    Apache
       ↓
    .htaccess
       ↓
    Passenger
       ↓
    nodejs/server.js
       ↓
    Next.js

    Hostinger juga menjelaskan bahwa build aplikasi backend seperti Next.js ditempatkan di folder nodejs, sedangkan .htaccess di public_html digunakan untuk routing menuju runtime tersebut.


    Akar Masalahnya: Tidak Ada Paket Standalone

    Setelah membuka server.js dari deployment yang berhasil, ditemukan konfigurasi berikut:

    "output": "standalone"

    Di sinilah penyebab utama ditemukan.

    Repository yang mengalami 403 belum menggunakan:

    output: "standalone"

    Akibatnya, Next.js hanya menghasilkan output build default dan Hostinger tidak memperoleh paket runtime mandiri yang berisi server.js.

    Tanpa server.js, Hostinger tidak membentuk struktur runtime yang seharusnya digunakan Passenger untuk menjalankan aplikasi.


    Solusi: Aktifkan Next.js Standalone Output

    Buat atau edit file next.config.mjs di root repository:

    /** @type {import("next").NextConfig} */
    const nextConfig = {
      output: "standalone",
    };
    
    export default nextConfig;

    Struktur sederhananya:

    project/
    β”œβ”€β”€ app/
    β”œβ”€β”€ package.json
    β”œβ”€β”€ package-lock.json
    └── next.config.mjs

    Apabila menggunakan format CommonJS pada next.config.js, bentuknya dapat ditulis sebagai:

    /** @type {import("next").NextConfig} */
    const nextConfig = {
      output: "standalone",
    };
    
    module.exports = nextConfig;

    Gunakan salah satu format yang sesuai dengan repository. Tidak perlu membuat keduanya.


    Apa yang Dilakukan output: "standalone"?

    Ketika konfigurasi standalone aktif, Next.js melakukan output file tracing.

    Next.js menganalisis file, import, dependency, dan package yang benar-benar dibutuhkan aplikasi saat production. Kemudian Next.js menghasilkan paket runtime minimal di:

    .next/standalone/

    Strukturnya kurang lebih:

    .next/
    └── standalone/
        β”œβ”€β”€ server.js
        β”œβ”€β”€ package.json
        β”œβ”€β”€ node_modules/
        └── .next/

    File server.js tersebut dibuat otomatis oleh Next.js. Kita tidak perlu menulis custom server sendiri.

    Next.js menjelaskan bahwa standalone output membuat folder deployment berisi file yang diperlukan, dependency terpilih, serta server minimal yang dapat dijalankan tanpa menggunakan next start.


    Menguji Standalone Output di Localhost

    Setelah menambahkan konfigurasi, hapus hasil build lama dan jalankan build ulang:

    rm -rf .next
    npm run build

    Periksa apakah file berikut sudah terbentuk:

    test -f .next/standalone/server.js
    test -f .next/standalone/package.json
    test -d .next/standalone/node_modules

    Jalankan standalone server:

    PORT=3001 \
    HOSTNAME=127.0.0.1 \
    node .next/standalone/server.js

    Kemudian buka:

    http://127.0.0.1:3001

    Pada kasus saya, halaman utama berhasil mengembalikan HTTP 200 dan endpoint API bekerja normal.

    Catatan tentang file statis

    Dokumentasi Next.js menyebutkan bahwa folder public dan .next/static tidak otomatis disalin ke folder standalone. Platform deployment dapat menangani proses tersebut sendiri. Untuk deployment manual, keduanya dapat disalin ke:

    .next/standalone/public
    .next/standalone/.next/static

    Push ke GitHub dan Biarkan Hostinger Melakukan Deployment Ulang

    Setelah standalone berhasil diuji secara lokal:

    git add next.config.mjs
    git commit -m "fix(deploy): enable Next.js standalone output"
    git push origin main

    Apabila auto-deployment Hostinger aktif, push ke branch yang terhubung akan memicu deployment baru secara otomatis.

    Pastikan build log kembali berhasil:

    Compiled successfully
    Generating static pages
    Finalizing page optimization

    Setelah deployment selesai, buka domain.

    Pada kasus saya, halaman yang sebelumnya menampilkan:

    403 Forbidden

    akhirnya berubah menjadi halaman Next.js yang benar.

    Endpoint dinamis juga berhasil diakses:

    https://example.com/api/health

    Responsnya:

    {
      "status": "ok",
      "runtime": "nextjs"
    }

    Struktur Deployment Setelah Berhasil

    Setelah standalone output diterapkan, Hostinger membentuk struktur yang lebih tepat:

    .builds/
    nodejs/
    public_html/

    Folder nodejs berisi:

    nodejs/
    β”œβ”€β”€ .next/
    β”œβ”€β”€ node_modules/
    β”œβ”€β”€ package.json
    β”œβ”€β”€ server.js
    └── file runtime lainnya

    Sementara itu, public_html/.htaccess meneruskan request ke nodejs/server.js melalui Passenger.

    Dengan demikian, request tidak lagi berhenti di Apache dan dapat diproses oleh Next.js.


    Mengapa Redeploy Saja Tidak Menyelesaikan Masalah?

    Sebelum menemukan akar masalah, saya sempat melakukan redeploy tanpa mengubah kode.

    Build kembali berhasil, tetapi website tetap 403.

    Hal ini terjadi karena redeploy hanya membangun ulang konfigurasi repository yang sama.

    Selama repository belum menghasilkan standalone runtime, hasil deployment tetap tidak memiliki server.js yang dibutuhkan.

    Jadi, urutannya bukan hanya:

    Redeploy

    melainkan:

    Tambahkan output: "standalone"
    ↓
    Build dan uji lokal
    ↓
    Commit
    ↓
    Push
    ↓
    Deploy ulang

    Dokumentasi Hostinger menyatakan redeployment dapat membuat ulang .htaccess, tetapi apabila paket aplikasi yang dibutuhkan belum terbentuk, regenerasi routing saja belum tentu menyelesaikan penyebab dasarnya.


    Checklist Troubleshooting 403 Next.js di Hostinger

    Ketika mengalami masalah serupa, gunakan checklist berikut.

    1. Pastikan aplikasi berjalan lokal

    npm run build
    npm run start

    2. Pastikan route utama mengembalikan HTTP 200

    curl -I http://127.0.0.1:3000

    3. Periksa build log Hostinger

    Pastikan tidak ada:

    Build failed
    Module not found
    Environment variable missing
    Out of memory

    4. Periksa struktur file Hostinger

    Deployment server-side yang benar seharusnya memiliki:

    nodejs/
    public_html/.htaccess

    5. Periksa apakah server.js tersedia

    nodejs/server.js

    6. Tambahkan standalone output

    const nextConfig = {
      output: "standalone",
    };

    7. Pastikan artefak lokal terbentuk

    .next/standalone/server.js

    8. Push dan deploy ulang

    git push origin main

    9. Uji halaman dan endpoint dinamis

    https://example.com/
    https://example.com/api/health

    10. Jangan langsung mengedit .htaccess secara manual

    Pada managed Web App Hosting, .htaccess dan konfigurasi Passenger sebaiknya dihasilkan oleh platform deployment.

    Edit manual dapat hilang ketika deployment berikutnya dijalankan.


    Apakah Semua Proyek Next.js Harus Menggunakan Standalone?

    Tidak selalu.

    Output default Next.js tetap valid dan dapat dijalankan menggunakan:

    next build
    next start

    pada server atau platform yang memang dikonfigurasi untuk menjalankan struktur repository secara penuh.

    Standalone lebih relevan ketika aplikasi perlu dikemas menjadi paket runtime yang:

    • lebih portabel,
    • memiliki server.js,
    • hanya membawa dependency yang dibutuhkan,
    • dijalankan oleh container, Passenger, atau platform deployment tertentu,
    • tidak bergantung pada seluruh repository production.

    Jadi, output: "standalone" bukan pengganti semua metode deployment.

    Namun, untuk kasus Hostinger Web App dengan gejala build berhasil tetapi domain 403 dan folder nodejs tidak terbentuk, konfigurasi ini layak menjadi pemeriksaan utama.


    Standalone Bukan Static Export

    Perlu dibedakan antara:

    output: "standalone"

    dan:

    output: "export"

    standalone tetap menjalankan server Node.js.

    Fitur seperti berikut tetap dapat digunakan:

    • server-side rendering,
    • Route Handlers,
    • API endpoint,
    • Server Components,
    • autentikasi server-side,
    • koneksi database,
    • halaman dinamis.

    Sementara output: "export" menghasilkan website statis tanpa runtime Node.js.

    Apabila aplikasi menggunakan API route atau fitur backend Next.js, jangan mengganti standalone dengan static export hanya untuk menghindari masalah runtime.


    Kesimpulan

    Masalah 403 pada deployment Next.js di Hostinger dapat terlihat seperti masalah domain, permission, SSL, atau .htaccess.

    Namun, pada kasus yang saya alami, akar masalahnya adalah aplikasi belum menghasilkan paket runtime standalone.

    Build memang berhasil, tetapi Hostinger tidak memperoleh:

    server.js

    yang diperlukan untuk menjalankan Next.js melalui Passenger.

    Solusinya adalah menambahkan:

    const nextConfig = {
      output: "standalone",
    };

    Setelah build ulang, pengujian lokal, commit, dan deployment baru, Hostinger berhasil membentuk runtime Node.js dan website dapat diakses secara normal.

    Ringkasnya:

    Build sukses + website 403
    ↓
    Periksa folder nodejs dan server.js
    ↓
    Tambahkan output: "standalone"
    ↓
    Build dan uji lokal
    ↓
    Deploy ulang
    ↓
    Website berhasil diakses

    Semoga pengalaman ini membantu pengguna Hostinger lain yang mengalami kondisi serupa.

    Keywords : Next.js output standalone, deploy Next.js ke Hostinger, Hostinger Web App, Next.js server.js, Next.js Passenger, error 403 Hostinger

  • Gagal Bayar ChatGPT Plus, Uang Nyangkut Rp349ribu

    Gagal Bayar ChatGPT Plus, Uang Nyangkut Rp349ribu

    Kemarin, tanggal 4 Market 2026, saya melakukan perpanjangan langganan ChatGPT Plus. Sudah beberapa Tahun ini, tidak ada masalah, semua berjalan mulus, tapi kali ini pembayarannya gagal, dan uang saya nyangkut Rp349ribu entah nyangkutnya dimana sampai saat ini belum jelas. Apakah di pihak Apple, di pihak ShopeePay, ataukah di pihak OpenAi (ChatGPT).

    Karena untuk bayar-bayar langganan seperti ChatGPT, dan aplikasi lainnya, saya pakai metode pembayaran otomatis lewat iPhone.

    iPhone akan memberi triger saat ada aplikasi yang perlu di perpanjang, kebetulan dompet digitalnya saya pakai ShopeePay.

    Kemarin, kebetulan saldo shopeePay saya dibawah 300ribu, sehingga pembayarannya gagal. Karena melihat notifikasi gagal, akhirnya saya topup saldo. Dan setelah itu, sudah terlihat status pembayarannya sukses.

    Lah tapi kok setelah bayar, status akun ChatGPT saya tidak berubah ke Plus. dan setelah beberapa menit, muncul lagi notifikasi pembayaran gagal (terlihat di screenshot diatas).

    Wah menyadari ada yang tidak beres, saya hubungi pihak shopeePay. Dengan menghubungi customer supportnya, awalnya kita chat dengan Bot, tapi setelah beberapa lama kita di layani oleh customer servicenya (manusia). Disana saya diminta untuk mengisi form, sudah saya isi dan submit.

    Pihak ShopeePay bilang, masih sedang di proses, kemungkinan 1×24 jam.

    Dan tak lama akhirnya ada balasan yang point pentingnya adalah :

    “setelah kami lakukan pengecekan lebih lanjut, transaksi tersebut telah diproses sesuai dengan syarat dan ketentuan yang berlaku: https:/shopeepay.co.id/terms . Oleh karena itu pengembalian dana untuk transaksi tersebut tidak dapat dilakukan dari sisi ShopeePay. Namun, Kakak dapat melakukan pengajuan pengembalian dana ke pihak merchant secara langsung.”

    Terus saya coba jelaskan kronologinya lagi, agar CSnya paham. Disamping itu, saya juga butuh ChatGPT Plusnya segera untuk dipakai kerja.

    Akhirnya saya coba cerita ke CS, kondisinya, bahwa saya butuh segera ChatGPT Plusnya, dan akhirnya disarankan, coba aja bayar pakai metode lain, agar nanti urusan klaim uang dari ShopeePay ini tidak kecampur yang nantinya bisa bikin bingung.

    Akhirnya, biar cepet bisa pakek kerja, saya bayar langganannya via Gopay.

    Proses pembayaran lancar, dan akun ChatGPT Plus saya langsung aktif lagi.

    Nah disinilah masalahnya, saat break saya coba iseng menghubungi customer supprot ChatGPT, saya jelaskan kronologinya dalam 1 chat. Dan tiba-tiba setelah kurang dari 5 menit, ada notifikasi masuk, bahwa permintaan refund berhasil πŸ˜… dan itu dananya langsung masuk ke akun Gopay saya.

    Laaaaaah kok gampang dan cepet kali?

    Udah seneng tuh awalnya, dan setelah saya perhatikan lebih detil, ternyata uang yang di refund itu uang yang barusan saya bayar lewat Gopay, dan akun ChatGPT saya kembali downgrade dari Plus ke Free.

    Artinya, tetap aja sebenernya uang saya masih nyangkut disana Rp349ribu (bayar via shopeePay)

    Padahal di keterangannya sudah saya jelasin secara rinci kronologinya, bahwa saya melakukan 2x bayar. pertama lewat shopeepay gagal, dan kedua lewat gopay dan berhasil. yang bermasalah adalah pembayaran shopeepay, gitu lah kurang lebih.

    Dan akhirnya saya followup lagi ke CS ShopeePay, dan menurut mereka status gagal ini terjadi di pihak merchant yaitu Apple.

    Dikasih link untuk klaim, https://support.apple.com/id-id/118223 tapi disana history pembayaran ChatGPT plus per tanggal 4 Maret 2026 ini tidak terdeteksi, hanya muncul history pembayaran bulan bulan sebelumnya, termasuk pembayaran aplikasi lain. Sehingga saya tidak bisa mengklaim ke pihak Applenya.

    Saya followup lagi lewat ChatGPT customer support, sudah di respon dan diminta mengirimkan bukti transaksi di shopeePay, padahal sudah saya kirimkan di chat pertama, tapi tetap saya kirim ulang, dan sampai saat ini belum ada respon lagi.

    Di pihak shopee juga sama, tidak ada respon lagi sampai hari ini.

    Jadi bingung, sebenernya uang saya nyangkutnya dimana?

    [Bersambung….]

    Hari ini, tanggal 6 Maret 2026, saya mendapatkan email dari Apple.

    Dan setelah saya cek di https://reportaproblem.apple.com/status

    Dan setelah saya cek di akun ShopeePay saya. dana tersebut sudah masuk.

    Oke artinya, masalah ini sudah selesai.

    Apa yang bisa kita pelajari dari masalah ini?

    Pertama, mungkin ini tidak ada kaitannya dengan masalah diatas, tapi saya baru sadar kalau selama ini saya banyak membayar langganan aplikasi/layanan yang sebetulnya tidak benar-benar penting atau tidak benar-benar saya pakai rutin tiap hari. Tapi kalau dipakai harian dan perannya sangat penting seperti LLM (ChatGPT), Canva Pro, CapCutPro, Netflix πŸ˜…, ya itu wajib. Tapi kalau aplikasi-aplikasi yang nggak begitu penting, yang masih bisa diatasi dengan cara gratisan, misalnya langganan iCloud (bisa backup ke HDD), Spotify (bisa puter mp3 aja), dan aplikasi-aplikasi produktivitas yang sebenernya nggak produktif amat, ya walaupun cuman Rp30.000, Rp50.000, Rp70.000 sebulan misalnya, kalau di total totalin sekian aplikasi, itu lumayan juga sebenernya. Jadi coba kamu cek lagi deh, jangan – jangan kamu juga punya kebocoran uang disini.

    Kedua, kalau uangmu nyangkut seperti kasus diatas, jangan panik. Karena semua bisa dilacak kok. Cukup hubungi customer support pihak terkait. Kalau dalam kasus saya diatas, saya hubung ketiganya, pihak ShopeePay (mereka melayani dengan baik), pihak OpenAi/ChatGPT (botnya melayani dengan baik, bahkan sangat agresif uang langsung di refund walaupun sebenernya salah sih πŸ˜…), dan terakhir berdasarkan arahan dari pihak ShopeePay dan OpenAi dimana mereka menjelaskan uangnya itu nyangkutnya di pihak Apple, jadi akhirnya saya hubungi pihak Apple. Daaaaan hanya butuh waktu 1×24 jam, uang saya akhirnya berhasil kembali.

    Catatan :

    Semoga bermafaat.

  • Cara Mengatasi Masalah Login “Nextend Social Login” WordPress

    Cara Mengatasi Masalah Login “Nextend Social Login” WordPress

    Kronologi

    Saya punya website membership, dimana ada masalah penamaan pada domainnya, sehingga mengharuskan saya mengganti nama domain tersebut dengan nama lain. Singkat cerita, akhirnya nemu nama domain yang cocok, saya beli, dan tibalah ditahap migrasi website dari domain lama ke domain baru. Proses migrasi berjalan lancar, tanpa error sedikitpun. Namun ada satu masalah kecil, tapi fatal.

    Masalah

    Dimana, saat saya coba login dengan user lama di website lama, datanya tidak akurat. Misal saya login dengan email : emailsatu@gmail.com jika di cek lewat fungsi “wp_get_current_user();” maka yang muncul justru akun/email member lainnya misal : memberdua@gmail.com πŸ˜… Kan kacau ya!

    Dan kadang untuk akun-akun tertentu, login manual berhasil, tetapi login via Google kadang masuk ke akun yang salah, bahkan muncul pesan, β€œWe found a user with your Google email address, it belongs to a different account.”

    Solusi

    Setelah bolak balik cek konfigurasi, solusinya ternyata sederhana, yaitu hapus isi tabel wp_social_users yang menjadi sisa dari plugin social login lama, dan masalah selesai.

    Sorry agak singkat, lagi capek banget! tapi yang penting intinya hapus isi tabel wp_social_users

    Semoga berhasil!

  • Cara Menonaktifkan Cache Saat Ngoding Di Server Langsung

    Cara Menonaktifkan Cache Saat Ngoding Di Server Langsung

    Konteks

    Dulu waktu awal awal belajar ngoding di kampus, rata-rata pasti diajarinnya ngoding di localhost. Dengan cara bikin server virtual di laptop/PC. Tapi kalau di dunia kerja, sebagian project harus dikerjakan secara live di web servernya, dengan mengakses domain/alamat websitenya langsung.

    Makin kesini, teknologi di server juga makin canggih, salah satunya di sisi efisiensi penggunaan bandwidth. Salah satu yang berperan penting disini adalah sistem Cache

    Dengan sistem cache, website kita bisa akses dengan cepat (ringan) oleh user, karena saat user membuka pertama kali, seluruh elemen website kita (code, css, script, gambar, dll) akan disalin, dan disimpan sementara di server server terdekat dengan pengguna. Dan disimpan juga di browser kita. Dan saat user mengakses lagi, seluruh elemen tidak di load ulang lagi dari awal.

    Kalau yang mengakses user/pengguna website sih ini jadi sangat menguntungkan, karena performa website kita terkesan cepat. Tetapi ini jadi masalah untuk kita yang lagi mengembangkan websitenya.

    Kronologi

    Saat kita melakukan perubahan kode atau konten di website, maka perubahan tersebut tidak bisa langsung terlihat. Karena yang kita akses adalah Cache nya (kondisi halaman sebelumnya).

    Bagi kamu yang berlangganan di web hosting seperti Hostinger contohnya, selain menerapkan Cache browser, disini juga menerapkan Cache server. Sehingga sekeras apapun usahamu menghapus Cache di browser, tidak akan ada pengaruhnya. Tetap saja perubahan code atau konten, yang kamu lakukan di server tidak bisa terlihat di browser kamu.

    Cara Menonaktifkan Cache Secara Permanen Di Server.

    Jawabannya ada pada CDN (Content Delivery Network), adalah jaringan server yang tersebar secara global untuk mengirimkan konten web. CDN menyimpan konten yang di-cache di server edge yang dekat dengan pengguna

    Login ke akun webhosting kami (disini saya langganan di hostinger)

    Lalu pilih website yang ingin kamu manage, setelah sampai di halaman dibawah ini, lakukan pengaturan berikut :

    1. Pilih domain / nama website yang ingin kamu atur Cache nya.

    2. Ketik CDN di kolom pencarian

    Lalu klik tombol Nonaktifkan

    Dan setelah itu, kamu bisa mengubah code dan konten apapun di halaman website, dan perubahannya langsung bisa terlihat di browser.

  • Mobil Matic Anda Mogok Di Jalan? Lakukan Ini, Semua Beres!

    Mobil Matic Anda Mogok Di Jalan? Lakukan Ini, Semua Beres!

    Ini adalah pengalaman pribadi saya, yang pertama kalinya ngerasain mobil mogok dijalan. Bagi anda pemilik mobil daihatsu, dan kebetulan lagi mogok dijalan, JANGAN PANIK. Semua bakal teratasi. Silahkan disimak ya.

    Kronologi

    Hari ini sekitar jam 12 siang, saya dan keluarga melakukan perjalanan cukup jauh, sekitar 2,5 Jam dari rumah, dalam rangka melakukan persembahyangan ke Pura Besakih. Dan kebetulan kali ini saya bawa mobil Daihatsu Sirion putih saya. Yang saya beli sekitar 4 Tahun yang lalu.

    Sekitar 1 jam perjalanan (sekitar jam 1 siang), kami melihat penjual es kelapa muda di pinggir Jln. By Pass Ida Bagus Mantra, dan kami sepakat berhenti istirahat sebentar, sambil minum es kelapa muda dan makan Tahu tek.

    Kebetulan banget, waktu kami berhenti, mesin mobil saya matikan, dan kaca saya buka semua (depan dan belakang) karena waktu itu di jalan suasananya sejuk dan berangin, nah pas lagi asik asiknya makan, ehhh tiba-tiba hujan gerimis. Jadi jendela saya tutup sedikit, tapi “pinternya” saya, wiper kaca depan saya hidupin. Biar apa cobak? πŸ˜…

    Karena PW banget, sama suasananya, sejuk, angin sepoi-sepoi, hujan gerimis. jadi istirahatnya di lama-lamain tuh. Tapi wiper tetep nyala nih. Inget, ini kondisi mesin lagi mati ya! 🀣

    Mungkin kalian sudah bisa tebak, apa yang terjadi berikutnya! Ya! AKI mobil saya soak!

    Pas saya tekan tombol Engine Start (starter). Ehhh lampu-lampu indikator di dashboard pada kedap kedip. Dan mesin nggak mau nyala!.

    Alamaaaaak! auto panik 🀣

    Dan ini pertama kali saya ngerasain, nyetir mobil sendiri dan mogok dijalan.

    Saya langsung hubungi salah satu karyawan di Bengkel Daihatstu, namanya Pak Cahyadi (081937001991), beliau ini yang selalu menghendel saya, kalau lagi service mobil di bengkel Astra Daihatsu Denpasar Cokroaminoto.

    Begitu saya hubungi, seperti biasa, beliau selalu sigap, langsung angkat telepon saya, dan saya langsung jelaskan apa yang sedang terjadi. Dan beliau menanyakan beberapa hal, untuk mencari tau, apa penyebab mesin mobil saya tidak mau nyala. Dan akhirnya beliau bilang, kalau ini masalahnya di AKI.

    Beliau menyuruh saya tenang, tetap disana, karena akan dikirimkan petugas ke lokasi, untuk mengecek mobil saya.

    Wah mendengar arahan beliau, saya merasa agak lega, karena penyebabnya udah jelas AKI, dan beliau janji kalau sekitar 30 menit, petugas akan datang ke lokasi saya. (Tentang petugas Daihatsu yang datang ke lokasi, saya ceritakan lebih detil di bawah, karena ada cara yang lebih mudah).

    Anjirrr selama ini saya sering denger cerita orang, yang mobilnya mengalami mogok dijalan, dan sekarang saya sendiri yang mengalaminya. Kalau lagi nyetir sendiri sih aman aman aja. Ini lagi bawa keluarga dan lagi mau acara persembahyangan. Dan sekarang posisi sudah jauh dari rumah. Dan waktu udah mulai sore.

    Sebelum kejadian ini, saya tuh sering ngidupin wiper loh padahal, atau ngidupin lampu, atau ngecas, atau ngidupin musik, dalam kondisi mesin mobil mati. Dan semua baik baik aja, Jadi saya ngerasa ngidupin wiper saat mesin mobil mati, adalah hal yang normal. Ternyata enggak! 😁

    Masalah & Penyebab

    Dalam kasus saya, penyebab utama mobil saya mogok, sudah pasti karena AKI nya soak. Karena saya menghidupkan wiper kaca depan, dalam kondisi mesin mobil mati, dan dalam waktu yang cukup lama (-+ 20 menit). Walaupun waktu itu saya pakai mode paling lambat.

    Penyebab lain adalah :

    • Umur AKI, kayaknya memang sudah waktunya diganti, karena dari pertama kali mobil ini saya beli, belum pernah ganti AKI sama sekali. Sudah 4 Tahun. Dan sebenarnya, hari-hari sebelumnya sudah ada tanda-tanda, AKI soak. Contoh : remote mobil saya main-main, dimana saat mobil saya parkir, pintunya nggak bisa dikunci otomatis dari remote (udah ganti batrai remote), head unit kadang-kadang nggak mati sendiri saat mesin dimatikan.
    • Mobil Jarang dipakai/dipanasin, Mobil Daihatsu Sirion saya ini juga jarang banget saya pakai, dihidupin/dipanasinnya pas lagi mau dipakai aja. Dipakai rata-rata 1 kali seminggu, kadang 1 Bulan ga pernah dipakai. Padahal dari dulu udah sering dikasih tau sama Sales mobilnya, kalau mobil harus sering-sering dipanasin, ternyata pengaruhnya bukan hanya ke kesehatan mesin aja, tapi ada hubungannya juga ke kesehatan AKI.

    Solusi

    Kalau mobil Daihatsu kamu mogok dijalan, apapun penyebabnya. Jangan panik. Ternyata daihatsu punya after sales yang luar biasa untuk pelanggannya. Yaitu layanan layanan emergency bernama ARAΒ 

    ARA (AstraWorld Roadside Assistance) adalah layanan emergency yang disediakan oleh Astra untuk membantu mobil – mobil merk Toyota/Daihatsu/Isuzu/BMW/ Peugeot yang mengalami kendala atau situasi darurat di jalan, seperti mogok, kunci tertinggal didalam mobil, ban kempes, dan sebagainya.

    Dan ini GRATIS loh! Karena ini memang bagian dari layanan after sales Daihatsu. Dulu pernah dikasih tau sama salesnya, waktu itu saya kiranya cuman gimmick aja. Ternyata beneran ada, dan berguna banget disaat-saat seperti ini.

    Selengkapnya tentang layanan emergency AstraWorld bisa cek di website resminya DISINI.

    Nah gimana cara menggunakan layanan ini?

    Cara ini justru saya dikasih tau sama sales yang dulu membantu saya saat membeli mobil ini. Namanya Maurine (082225284747), walaupun sekarang dia sudah tidak di Daihatsu lagi (sudah di Hyundai Indonesia), tapi dia banyak bantu saya kalau ada apa apa sama mobil saya. Kalau dihubungi selalu sigap, fokus ngasih solusi, padahal udah nggak di Daihatsu lagi 😁. Jadi kalau mau beli mobil Hyundai, belinya di dia aja. Asli semua urusanmu bakal beres. Bahkan sampai ke after salesnya juga.

    Cara #1 : Otomatis via Chatbot Whatsapp :

    • Chat ke whatsapp AstraWorld 0895381500898
    • Ketik “ARA” lalu enter
    • Nanti akan dijawab oleh chatbot AstraWorld, ikuti aja alur pertanyaannya. Nanti mereka akan otomatis membuatkan laporan untuk diajukan ke petugas lapangan.
    • Setelah menjawab semua pertanyaan, nanti kamu akan dihubungi oleh petugas lapangan layanan emergency AstraWorld via telepon atau whatsapp.
    • Berikan informasi selengkap-lengkapnya, agar petugas mudah menumkan lokasimu di lapangan.

    Pro tips :

    • Pastikan saat melakukan chat ke whatsapp AstraWorld, gunakan nomor whatsapp yang sudah terdaftar di Daihatsu. Yaitu nomor yang kamu gunakan, saat membeli mobil. Agar prosesnya tidak ribet, tidak perlu menyita waktu untuk mengisi formulir.

    Cara #2 : Mintalah bantuan ke sales Daihatsu :

    Pastinya kamu masih menyimpan nomor sales daihatsu yang dulu membantu kamu, saat proses pembelian mobil. hubungi aja salesnya, pasti nanti dia akan membantu membuatkan laporan ke layanan emergency AstraWorld.

    Kamu akan diminta tetap tenang dilokasi, menunggu petugas datang.

    Lalu bagaimana setelah petugas datang?

    Setelah menunggu sekitar 30 menit, akhirnya petugas datang membawa sepeda motor dengan tool box disadel belakang. Petugasnya sangat ramah, menjelaskan dengan baik, kalau ditanya ia dengan sabar menjelaskan agar kita sebagai orang awam jad paham, apa masalahnya, dan solusinya harus bagaimana.

    Dikasus saya, pertama-tama petugas mengintrogasi saya dulu, dia ingin tau apa yang terjadi sebelum mobil mogok, singkat cerita petugas inilah yang menyadarkan saya, kalau tadi saya menghidupkan wiper, sebelumnya saya engga ngeh! sumpah πŸ˜‚

    Nah karena petugasnya yakin kalau AKI soak karena dayanya habis, bukan karena rusak. Maka langkah yang diambil adalah melakukan jumper, dari AKI yang ia bawa, langsung disambungkan ke mesin mobil saya. Akhirnya mesin mobil saya berhasil hidup, dan dibiarkan sekitar 15 menit, Agar daya di AKI terisi kembali.

    Setelah 15 menit di hidupkan, benar saja. AKI mobil saya kembali normal. Mesin bisa di starter kembali seperti biasa.

    Petugasnya menyarankan untuk siap siap ganti AKI, karena memang kondisi AKInya sudah tua. sudah perlu diganti. Biar kedepannya, lebih nyaman dijalan. Tidak ada resiko mogok karena AKI soak.

    Info dari bapaknya sih, estimasi harga AKI yang ideal untuk mobil saya kisaran harga Rp900ribuan. Ini sudah AKI original standar Astra Daihatsu katanya. Jadi jadwal service berikutnya saya udah harus siapin dana tambahan untuk ganti AKI.

    Akhirnya, petuasnyapun membereskan alat-alatnya, bersiap untuk pulang, dan waktu saya tanyakan

    Saya : “Pak berapa ini pak?”

    Beliau jawab sambil senyum

    Petugas : “Oh sebenarnya ini gratis Pak, tapi kalau bapak mau ngasih ya saya sih engga nolak”

    Saya : “Wah berapa ya pak biasanya?”

    Petugas : “Ya seiklasnya bapak aja…” sambil senyum bapaknya 😁

    Akhirnya, saya kasih Rp50ribu. Soalnya bingung mau kasih berapa.

    Terakhir, nanti kita akan diminta untuk menandatangani sebuah dokumen, seperti surat perintah kerja (SPK), yang menjadi bukti bahwa ia telah membantu pelanggan Daihatsu, yang mogok di jalan.

    Kesimpulan

    Saat mobil daihatsu kamu mogok dijalan, jangan panik, karena daihatsu menyediakan layanan emergency 24 jam, dan ini GRATIS! untuk mobil daihatsu yang umurnya maksimal 5 Tahun. Cara menggunakan layanan ini sangat mudah, cukup hubungi sales mobil daihatsu kamu, ceritakan kronologi mogoknya, nanti ia akan membantu membuatkan laporan ke layanan emergency. Atau kamu juga bisa mengaksesnya sendiri dengan cara chat ke whatsapp 0895381500898 (AstraWorld), lalu ketik “ARA”, nanti ikuti aja alur pertanyaan dari chatbot, maka sistem akan menugaskan petugas lapangan untuk datang ke lokasi anda. Mereka akan membantu menyelesaikan masalah mobil anda.

    FAQ (Pertanyaan Umum)

    Tanya : Apakah mobil masih bisa jalan jika aki soak?

    Mobil masih bisa jalan, selama mesin mobil hidup, daya listrik yang dibutuhkan mobil, akan disuplay dari mesin. Tapi begitu mesin mobil dimatikan, mobil tidak akan bisa distarter jika aki soak karena aki yang soak tidak dapat menyediakan listrik yang diperlukan untuk menyalakan mesin mobil.

    Tanya : Apakah mobil matic bisa didorong kalau aki nya soak?

    Mobil maticΒ tidak bisa didorong layaknya mobil manual saat kehabisan daya pada aki. Kalau hanya untuk memindahkan posisi mobil memang bisa dan ada caranya, tapi untuk menyalakan mesin saat aki soak. Tidak bisa dengan cara didorong.


    Tanya : Jika aki mobil soak apa yang harus dilakukan? / Bagaimana cara mengatasi aki mobil matic tekor di jalan?

    Hubungi layanan emergency AstraWorld, di nomor whatsapp 0895381500898, ketik “ARA”, lalu enter. Ikuti alur panduan yang diarahkan oleh chatbot. Maka nanti petugas akan datang membantu.

    Tanya : Apa ciri ciri aki mobil lemah?Aki mobil soak apakah masih bisa dipakai

    Ciri-ciri aki mobil lemah termasuk kesulitan dalam menyalakan mesin, lampu redup, dan bunyi klik-klik ketika kunci kontak diputar. Aki mobil matic yang soak mungkin masih bisa dipakai setelah diisi ulang dan dicas kembali, tetapi kemampuannya untuk menyimpan muatan listrik bisa berkurang, yang dapat memengaruhi kinerja sistem elektrikal mobil. Sebaiknya periksa kondisi aki secara menyeluruh untuk memastikan kesehatan AKI nya ke bengkel resmi Daihatsu.

    Tanya : Bagaimana cara dorong mobil matic aki tekor?

    Jangan di dorong! mobil matic tidak sama dengan mobil manual, yang jika mogok karena aki tegor, bisa di dorong. Jika mobil matic anda mogok karena Aki tekor, panggilah teknisi untuk jumper AKI mobil anda, atau ganti aki jika diperlukan.

    Tanya : Bagaimana cara jumper aki mobil matic? / Cara memancing aki mobil yang tekor? / Bagaimana cara menghidupkan mobil matic yang tidak bisa distarter? / Cara menghidupkan mobil mogok tanpa didorong?

    Untuk melakukan jumper aki mobil matic, pertama pastikan kedua mobil mati yang digunakan berada dalam keadaan parkir dan mesin dimatikan. Selanjutnya, sambungkan kabel positif (+) dari aki mobil penyumbang ke terminal positif (+) aki mobil mati, lalu hubungkan kabel negatif (-) dari aki mobil penyumbang ke titik tanah yang baik pada mobil mati, seperti rangka mobil. Nyalakan mesin mobil penyumbang dan biarkan berjalan beberapa menit untuk mengisi daya aki mobil mati, kemudian coba hidupkan mesin mobil mati. Pastikan untuk melepas kabel jumper dengan hati-hati setelah mobil mati berhasil dinyalakan.

    Tanya : Apa sih ciri-ciri aki mobil matic sudah soak? / Apa saja tanda aki soak pada mobil matic?

    Aki mobil matic yang sudah soak biasanya menunjukkan gejala-gejala seperti turunnya performa mesin, lampu yang redup tidak seperti biasanya saat menghidupkan mesin, lampu indikator baterai menyala terus-menerus, serta suara mesin yang tidak normal saat mobil dihidupkan (mesin berat saat di starter), terganggunya sistem elektronik seperti kadang mobil tidka bisa di kunci otomatis menggunakan remote.


    Tanya : Berapa harga aki mobil matic mobil daihatsu Sirion?

    Untuk yang standar astra daihatsu, harga AKI original untuk mobil sirion adalah kisaran harga Rp900ribuan.


    Tanya : Apa saja pengaruh aki pada mobil matic?

    Aki pada mobil matic berperan penting dalam menyediakan listrik untuk sistem starter dan sistem kelistrikan lainnya. Ketika mobil dihidupkan, aki menyediakan arus listrik yang diperlukan untuk mengaktifkan starter dan memulai mesin. Selain itu, aki juga menyimpan energi untuk memasok daya ke berbagai komponen kelistrikan mobil seperti lampu, AC, radio, dan lainnya. Jika aki rusak atau kehabisan daya, mobil matic tidak akan bisa dihidupkan atau bisa mengalami masalah dalam perpindahan gigi dan sistem elektronik lainnya.


    Tanya : Apa saja penyebab aki mobil matic tekor habis sendiri?

    Beberapa penyebab aki mobil matic bisa habis sendiri termasuk masalah pada sistem pengisian, seperti alternator yang rusak atau regulator tegangan yang bermasalah, juga bisa disebabkan oleh komponen elektrikal lain yang mengalami kebocoran arus, seperti kabel yang aus atau komponen yang terus-menerus aktif meskipun mesin mati, misalnya relay yang menempel terus. Masalah yang umum terjadi karena mobil jarang digunakan atau dipanaskan.


  • Kisah Nyata : “Usaha Tidak Menghianati Hasil” Modal Tekun & Sabar

    Kisah Nyata : “Usaha Tidak Menghianati Hasil” Modal Tekun & Sabar

    Ini adalah sharing pribadi saya, yang merupakan 100% kisah nyata, tidak saya buat-buat sama sekali. Menceritakan tentang perjalanan salah satu bisnis online saya, yang baru menghasilkan uang, setelah 2 Tahun berjalan. Padahal saya sudah hampir menyerah berkali-kali, mulai dari masalah teknis yang sangat sulit di pecahkan, masalah kehabisan modal, website kena takedown, sampai di momen mendapatkan hinaan dan sama sekali tidak mendapatkan dukungan dari orang terdekat. Tapi berkat keyakinan, ketekunan dan kesabaran, akhirnya setelah 2 Tahun, bisnis ini sukses mencetak omset yang cukup membahagiakan, dan makin hari makin bertambah, dan sampai sekarang masih sedang berlangsung. Hari ini, bisnis ini tuh rasanya seperti, pesawat yang sedang dalam proses “take off”. Terbang naik terus semakin tinggi, dan sesekali ada kejutannya. Dan disinilah saya mendapatkan makna sesungguhnya, tentang “Usaha tidak pernah menghianati hasil”. Dari yang tanpa omset selama 2 Tahun, berkat keyakinan, tekun dan sabar, per hari ini, bisnis ini bisa mendapatkan penghasilan bersih, setara UMR, hanya dalam 1 hari.

    Hari ini, tanggal 21 Februari 2024, sekitar beberapa menit yang lalu (sekitar pukul 22 lewat 15 menitan lah). Saya duduk di depan laptop, baru saja selesai membalas chat terakhir dari salah satu customer, yang happy banget dengan hasil yang ia terima, dari layanan yang ia beli lewat salah satu website saya ini.

    Sambil bengong, saya ngeliatin aplikasi whatsapp desktop yang lagi kebuka di layar laptop saya. Walaupun badan rasanya udah rada berat, performa otak udah mulai melambat, tanda udah mulai ngantuk.

    Cuman saya lagi nyaman banget duduk di kursi kerja saya, sambil mandangin laptop. Ngantuk sih, tapi belum bener-bener pengen tidur.

    Tiba-tiba saya kepikiran aja sama kata-kata customer tadi. “Makasih banyak ya kak, seneng banget!, nanti saya pasti order lagi…”, gitu katanya.

    Dan customer yang puas seperti ini, udah nggak kehitung lagi sih jumlahnya. Banyak banget. Hampir semua customer kami selalu menyampaikan kepuasannya.

    Cuman tadi pas sambil bengong, saya sambil mikir, Oh ternyata ini yang disebut “Usaha tak menghianati hasil”.

    Kalimat bijak tersebut, sering banget saya denger dari dulu, tapi tidak benar-benar paham maknanya. Nah tadi, tiba-tiba saya seperti mendapatkan pencerahan. Benar-benar memahami kalimat bijak : “Usaha tak akan pernah menghianati hasil”.

    Padahal, kalau dipikir-pikir, dari awal bisnis ini saya bangun, saya sudah hampir menyerah berkali-kali. Kendala-kendala yang saya hadapi dari awal, benar-benar kendala yang sulit banget di pecahkan. Itu juga kenapa, bisnis sejenis ini, sangat jarang yang bisa survive atau berkelanjutan. Karena memang benar-benar sulit.

    Tapi kalau berhasil menembus berbagai halangannya, saya akan berpeluang menjadi pemain utama. Karena sampai sekarang, sudah banyak pemain lama yang menyerah.

    Disclaimer

    Walaupun ini merupakan blog, tapi sejujurnya, sebagian besar artikel yang saya tulis di www.putuadi.id, bukan untuk orang lain, melainkan untuk diri saya sendiri. Terutama di artikel ini, banyak hal yang tidak bisa saya jelaskan dengan rinci. Karena memang tidak ingin saya buka ke semua orang. Jadi kalau nanti ada hal yang membingungkan saat kamu baca. Ya maklumi aja ya. 😁 Karena menulis, bagi saya, salah satu cara untuk merayakan sesuatu, kadang untuk healing, atau kadang hanya sekedar untuk membuat catatan aja.

    Ini Bisnis Apa Sih?

    Saya tidak akan jelaskan, ini bisnis apa. Karena bukan itu pointnya. Disamping itu, saya juga tidak ingin kata kunci ataupun nama website nya ter-Index disini. Tapi intinya, secara garis besar, ini adalah bisnis digital, yang bentuknya sebuah web aplikasi, yang produk utamanya adalah, layanan yang bisa menaikan kredibilitas seseorang, ataupun brand, di dunia digital marketing.

    Kapan Bisnis Ini Dimulai?

    Saya seorang web developer, awal mula ide bisnis ini adalah, karena terinspirasi dari seorang client, yang baru saja membeli website kepada saya. Waktu itu kejadiannya di Bulan Januari 2022. Beliau membicarakan tentang kebutuhannya akan sebuah layanan, yang bisa menaikan kredibilitas usahanya.

    Dari obrolan itu, saya sangat excited dan passioned banget bikin oret oretan konsepnya. Karena saya ngeliat ini punya peluang yang sangat besar. Kemudian beberapa hari setelahnya, saya coba buat rancangan konsep yang lebih matang, dan mulai membangun sistemnya sedikit demi sedikit.

    Di tahap ini, yang saya bangun adalah sistemnya dulu (mesinnya), bukan websitenya. Jadi tiap hari, saya ngoding start dari jam 7 malam, sampai larut malam, intinya sampai nggak bisa nahan ngantuk lah. Dan begitu terus setiap malam. Kenapa malam? karena siang sampai sore saya ngurusin bisnis saya yang lain yang udah jalan. Dan saya nggak mau terganggu dengan itu.

    Setelah 2 Bulan ngoding tiap malam, akhirnya saya menemukan ide nama, yang menurut saya sangat cocok untuk bisnis ini. Selain namanya bagus, ini juga sekaligus menjadi kata kunci utama, saat orang mencari layanan jenis ini di internet. dan kebetulan domainnya tersedia, akhirnya saya register dulu, biar engga keduluan orang lain.

    Dan akhirnya pada tanggal 16 Maret 2022, jam 20:58:12 PM (data saya ambil dari server) saya berhasil membeli/register nama domain tersebut.

    Waktu itu websitenya belum langsung online, masih dalam tahap pengujian di localhost (laptop). Setelah berhari-hari memastikan semuanya berjalan dengan sempurna, akhirnya aplikasi saya pindahkan dari local host (laptop), ke web hosting (internet). Artinya sekarang web aplikasinya sudah online.

    Tanpa perayaan apapun, tanpa satu orangpun yang tau. 😁

    Apa Kendalanya?

    1. Kemampuan Skill

    Dari awal saya bikin oret-oretan konsepnya dikertas, sebenarnya di momen itu pun, kendala sudah mulai bermunculan di kepala saya. Mulai dari gimana teknis eksekusinya nanti dari sisi coding, database, API (Application Programming Interface), dll. Karena project ini tuh, ada di level kerumitan dua tingkat diatas, dari seluruh project yang pernah saya kerjakan sebelumnya. Saya belum pernah mengerjakan project sekompleks ini. Sehingga kadang ngerasa mungkin (optimis), kadang ngerasa nggak mungkin (pesimis). Tapi kalau nggak di coba, nanti takut nyesel.

    Saya nggak mau nyerah disini, jadi saya paksakan diri untuk ngembangin skill pemrogramman saya. Saya palajari semua hal-hal yang saya butuhkan untuk ngebangun aplikasi ini. Dan ternyata makin dipelajari, saya merasa makin optimis, bahwa hal ini mungkin untuk dilakukan.

    2. Integrasi antar aplikasi yang tidak stabil

    Aplikasi yang saya bangun ini, nantinya akan di integrasikan dengan aplikasi lainnya. Nah sistem integrasi ini tidak di desain untuk melakukan hal yang akan kami lakukan. 😁 Sehingga sering kali proses berhenti di tengah jalan. Tentu ini masalah besar. Walaupun sistem sudah dibuat sedemikian rupa untuk menghindari terjadinya macet di tengah-tengah proses, tapi tetap saja sampai sekarang masih sering terjadi. Walaupun tidak sesering dulu. Intinya, saat kendala ini terjadi, client sudah pasti komplain.

    Dan waktu itu benar-benar hampir tidak ada solusi untuk mengatasi kemacetan proses ditengah jalan seperti ini. Karena di internet tidak ada tutorialnya sama sekali, atau setidaknya waktu itu saya belum nemu. Macet disini tuh bukan setelah di proses ulang, maka prosesnya kembali jalan, tidak!. Kalau udah macet, maka sering kali macetnya permanen.

    Itu yang bikin saya sering galau, dan pengen nyerah aja rasanya. Temen ngobrol juga nggak ada (orang yang ngerti ranah ini). Cari di internet juga nggak ada jawabannya. Pusiiiiiing!

    3. Banyak komplain

    Customer kami tentu tidak paham apa yang terjadi di belakang layar. Namanya juga customer, yang dia tau hanyalah, apa yang ia beli, harus sesuai dengan yang kami janjikan. Ia nggak? Jika sesuai, dia akan happy, jika tidak sesuai dia akan komplain. Padahal, saat pesananannya tidak sesuai, bukan berarti kami sengaja melakukannya. Padahal itu terjadi karena sebuah kesalahan yang tidak sengaja terjadi pada sistem kami. Tapi makin banyak komplain yang masuk, makin banyak perbaikan dilakukan, sehingga akhirnya sistem kami semakin hari semakin baik. Tapi bukan berarti sempurna, karena sesekali ada aja masalah baru yang muncul.

    Sebagai orang yang berzodiak libra (ciee percaya zodiak). Salah satu sifat saya adalah “enggak enakan”. Sehingga tiap ada customer komplain, salah satu hal utama yang selalu saya tawarkan adalah Refund atau pengembalian dana. Karena tiap saya bisnis, salah satu hal yang paling saya jaga adalah integritas. Saya nggak mau mengecewakan atau merugikan orang lain. Disamping itu, sebagai umat Hindu, saya sangat percaya akan karma pala. Jadi kalau hal yang berkaitan dengan “Amanah dan Kejujuran dalam bisnis”, skrup saya cukup kenceng.

    Tapi dari sifat ini pula, yang akhirnya bikin saya sering kepikiran, sering ngerasa bersalah banget saat customer komplain. Sehingga sering kali saya kepikiran untuk berhenti dan meninggalkan bisnis ini. Karena sulit banget melihat dan merasakan begitu banyak customer yang kecewa. Terutama di awal-awal.

    Bisnis ini pernah saya tidak urus sama sekali selama berminggu-minggu. Memilih fokus ke bisnis utama yang udah jelas hasilnya. Tapi karena ngelihat banyak juga customer yang repeat order, akhirnya saya ketarik-tarik lagi ke sini.

    4. Lebih besar pengeluaran dari pada pemasukan

    Sejak website ini online, 1 tahun setelah itu, yang menggunakan layanan kami kebanyakan datangnya dari orang-orang yang saya kenal. Itupun karena di tawarin. Karena waktu itu pengunjung web harian, angkanya masih sangat kecil. Rata-rata cuman 5 – 10, sesekali nyentuh 20 orang per hari. Omset per bulan kadang adaaaaaa, kadang nggak ada! πŸ˜‚. Ibarat kata nih, omset cuman cukup untuk bayar domain dan hosting doang. Biaya saya begadang, dan lain-lain itu, belum balik modal tuh di tahun pertama.

    Namanya juga bisnis, pasti tujuan utamanya adalah untuk mencari keuntungan. Lah ini 1 tahun berjalan tapi nggak untung-untung. Malah sering kali pakai uang pribadi untuk nalangin bayar server.

    Kalau sebulan dua bulan nggak untung sih nggak masalah, masih wajar. Lahhhh ini udah 2 Tahunan masih belum untung juga. Sehingga makin kesini saya makin pesimis, sering kepikiran untuk iklas aja untuk ninggalin bisnis ini.

    Tapi lagi-lagi ketarik-tarik sama pelanggan setia saya. Orderan masuk walaupun uang receh, saya tetap layani. Walaupun pikiran saya sudah bukan di bisnis ini lagi.

    5. Terbentur Regulasi

    Belum sampai disitu, waktu itu saya tidak sengaja ketemu situs hukumonline.com dan saya iseng cari aturan yang berkaitan dengan aktifitas bisnis yang saya lakukan di aplikasi saya ini. Dan saya tiba-tiba tertampar! gemeteran dan keringat dingin ngebaca bahwa ternyata di hukum UU ITE sudah ada regulasinya. Padahal saat awal saya ngebangun aplikasi ini, saya googling sana sini, belum ada hukum yang mengatur hal seperti ini.

    Karena saya cek tanggal postingannya, memang disana baru beberapa hari yang lalu artikel tersebut di posting. Nah intinya, disana ada 2 pasal yang relevan atau terkait.

    Duhhh! mana aplikasinya udah jadi, udah ada customer (walaupun masih uang recehan). Apakah ini waktunya berhenti?

    Waktu itu saya galau banget, stress banget. Dalam hati saya, “Wah fix, bisnis ini harus benar-benar saya tinggalin aja”.

    Beberapa hari setelah itu, saya lagi nyuci mobil di carwash deket rumah. Nah kebetulan ketemu sama pensiunan salah satu instansi BUMN. Yang berkaitan banget sama Hukum UU ITE. Ini bener-bener saya ngerasa sebuah kebetulan yang sangat kebetulan. Mungkin Tuhan ngirim saya kesana untuk dengerin pandangan beliau.

    Beliau ngakunya sih salah satu pejabat tinggi di instansi BUMN gitu, dan baru aja bulan ini beliau pensiun. Singkat cerita, saya konsultasi ke beliau, saya ceritakan tentang aplikasi saya ini, lalu ceritakan juga bahwa ada 2 pasal UU ITE yang relevan dengan itu. Dan penjelasan dari beliau ini cukup menenangkan hati saya.

    Beliau bilang, “Dik Putu, Negara ini masih banyak dibebani sama persoalan-persoalan yang jauh lebih besar dan jauh lebih penting dari ini…. Lagipula, hukum akan bertindak jika ada yang melaporkan, karena ada pihak yang dirugikan. Selama tidak ada pihak yang dirugikan dan melapor ke pihak berwajib, maka jangan kuatir”. Begitu kurang lebih pesan beliau kepada saya.

    Karena memang, walaupun bisnis saya ini di “gray area”, tapi tidak ada satu orang pun yang saya rugikan. Justru kehadiran aplikasi ini untuk membantu. Semua customer kami happy kok! (kecuali klo ada error aplikasi, ya itupun kan udah di refund 😁 jadi hitungannya tidak merugikan).

    Dari yang awalnya down banget, karena baca 2 pasal UU ITE itu, berkat pandangan dari beliau, akhirnya saya semangat lagi.

    6. Website di blacklist whatsapp

    Badai pasti berlalu? berlalu gigi lu gondrong! badai belum berlalu brooooo! 🀣 badai berikutnya adalah waktu saya mulai bikin rancangan kegiatan marketing. Karena dari awal jalan sampai titik ini, saya belum pernah melakukan kegiatan marketing yang proper. Selama ini hanya mengandalkan trafik dari website, sosmed standar, dan belum pernah menggunakan iklan berbayar atau sejenisnya. jadi selama ini 100% penjualan yang terjadi lewat cara-cara organik.

    Waktu itu rencana saya, adalah kirim whatsapp blast ke nomor-nomor para pemilik bisnis, karena target utama kami adalah para pemilik pebisnis yang aktif menggunakan sosial media. Kebetulan saya tergabung di banyak banget group whatsapp entrepreneurship gitu lah, yang isinya para pemilik usaha, kebanyakan sih levelnya masih UMKM.

    Tapi saya nggak mau spamming juga, ke group-group ini, apalagi nomor yang terdaftar di group-group tersebut kan nomor pribadi saya, jadi saya ngerasa nggak etis aja sih rasanya, kalau langsung posting penawaran di group.

    Jadi idenya gini, saya export semua nomor anggota, yang ada di tiap group. Setelah itu, saya kirim chat mereka satu persatu, yang isiinya chat penawaran.

    Beberapa hari sebelumnya, saya beli HP baru, memang sengaja saya siapkan khusus 1 HP dan 1 Nomor baru untuk semua kebutuhan bisnis ini nantinya.

    Singkat cerita, saya mulai kirim chat penawaran, ke satu persatu nomor tadi. Dari 10 nomor pertama, lanjut ke 15 noomr, 20 nomor dan kebablasan sampai 100an nomor. Nahhhh! inilah awal mula masalah besar terjadi.

    Tiba-tiba aplikasi whatsapp saya logout dan ternyata nggak bisa login lagi, setelah beberapa menit, saya baru nyadar, kalau nomor saya ini terblokir. Dugaan saya sih, mungkin karena terlalu banyak kirim chat ke banyak nomor baru (saya tidak save nomor mereka, mereka juga tidak save nomor saya) apalagi isi chatnya template gitu, isinya sama semua, dan di dalamnya juga ada link/url website gitu. Ya saya yakin pasti kamu tau chat-chat template penawaran / chat jualan yang saya maksud.

    Semua ceritanya ada disini :

    Ahhhh nomor di blokir kan tinggal beli nomor baru brooo!. Nahhhhhh! ini dia yang juga saya pikirin waktu itu, jadi setelah kejadian itu, yaaa saya tenang-tenang aja πŸ˜‚, sampai akhirnya saya beli nomor baru, lalu lakuin hal yang sama, tapi begitu sekali kirim chat penawaran, Whatsapp saya langsung terblokir lagi. Padahal itu nomor baru loh! Wah di tahap ini, saya mulai rada-rada kuatir.

    Saya beli nomor lagi… tapi tetap aja langsung terblokir. Makin panik kan? Udah coba tukar pakai HP lain juga, tapi hasilnya sama aja, terblokir2 juga.

    Sampai akhirnya saya menyadari bahwa yang di blokir ini, bukan karena nomornya atau bukan karena HPnya. Tapi karena link URL website saya. Jadi yang bikin terblokir itu sebenarnya adalah link URL website aplikasi saya πŸ€£πŸ˜‚πŸ€£πŸ˜‚

    Sepertinya algoritma whatsapp, pertama-tama medeteksi adanya chat spamming ke ratusan nomor. Jadi di tahap itu, yang di blokir cuman nomor doang.

    Begitu ganti nomor baru, template chat yang sama, saya copy paste dan kirim chat blast lagi ke banyak nomor. Dugaan saya di tahap ini, algoritmanya whatsapp menandai URL website saya sebagai URL redflag. Sehingga jika ada nomor baru, yang mengirim chat yang mengandung link URL tersebut, maka diasumsikan itu spamming dari pelaku yang sama.

    Untuk kesekian kalinya beli nomor baru, sampai-sampai saya udah tidak peduli lagi apakah itu nomor cantik atau bukan, saya beli acak aja, ngambilnya random gitu.

    Setelah beli nomor baru untuk yang kesekian kalinya, saya lakukan uji coba pelan-pelan. Jadi begitu nomor baru terpasang, saya coba kirim chat yang isinya cuman teks biasa. Dan ternyata itu normal-normal aja, tapi begitu saya coba kirim chat yang mengandung alamat website saya, whatsapp langsung terblokir. 🀣

    Jadi fix, yang bikin terblokir itu adalah link atau alamat website aplikasi saya.

    Artinya apa? artinya, saya tidak bisa pakai whatsapp untuk alat komunikasi dengan customer saya.

    Apa jadinya, sebuah bisnis tanpa punya nomor whatsapp? Pasti dicurigai macem-macem kan?. Ada fasenya, di website saya pasangin tools untuk livechat gitu. Jadi tiap ada chat masuk, kelamaan nggak di bales, calon pelanggan kabur, dan tidak bisa di followup lagi. Saya pernah juga coba pakai telegram, dan beragam aplikasi chat opsional. Tapi tetap saja orang Indonesia, alat komunikasi utamanya itu tetap pakai Whatsapp. jadi kalau kita berbisnis, tidak punya nomor whatsapp, itu sangat-sangat aneh sih.

    Semua ceritanya ada disini :

    Segala upaya solusi dan dinamikanya, saya ceritain lengkap di artikel diatas. Tapi intinya, waktu itu saya benar-benar patah arang. Rasanya sudah tidak ada harapan lagi untuk bisnis ini πŸ˜‚

    Mood saya berantakan banget, pokoknya senggol bacok, banyak orang sekitar saya kena pelampiasan saya lah intinya. Orang ga salah jadi salah.

    Waktu itu saya sudah di fase untuk belajar merelakan dan menyudahi bisnis ini.

    Tapi saya memang pada dasarnya, si kepala batu banget. Jadi kalau ada orang, yang ngata-ngatain apalagi menghina karya saya. Waduhhhh…. hati-hati banget! Maka itu akan memberikan saya energi yang maha dasyat! hanya untuk nunjukin bahwa anggapan mereka itu salah! Itu mirip kayak reaksi fusi nuklir yang terjadi pada bom atom, yang menghasilkan ledakan super dasyat!.

    Waktu itu saya di bully sama pacar saya sendiri. Niatnya mau curhat, mau meringankan beban pikiran, ehhh malah kena bully. πŸ˜‚

    Ya namanya juga mood lagi berantakan, settingannya udah senggol bacok aja. lagi super sensitif nih boss! senggoh dong!

    Dan dari bullyan inilah justru, saya bangkit berkali-kali lipat. Nunjukin bahwa apa yang ia katakan itu salah besar!. Saya berantem besar dan hampir putus karena cuman persoalan itu πŸ˜πŸ˜‚πŸ€£

    7. Diragukan dan dihina pacar sendiri

    Waktu itu, saya coba sharing masalah saya ke pacar tercinta. Harapannya dia cukup bisa ngasih semangat atau ngasih support sistem. Nggak ada harapan untuk minta bantuan apa-apa sih sebenernya, cuman sekedar ingin di dengerin aja.

    Baru aja ngobrol beberapa kalimat, ehhh doi langsung nyerocos ngomong kalimat-kalimat yang menyakitkan hati saya. Yang awalnya saya cuman patah arang, sekarang arangnya jadi hancur berkeping-keping πŸ€£πŸ˜‚ … (maaf saya nggak bisa tulis kata-katanya doi disini, tapi sangat-sangat menyakitkan hati saya).

    Intinya, responnya bisa salah seperti itu, karena “ketidak tahuan”. Doi nggak ngerti apa-apa tentang aplikasi yang saya bangun ini. Sehingga pandangannya keliru aja sih. Soalnya dari dulu, tiap kali saya coba sharing, dia nggak pernah ngerti.

    Waktu itu saya hancur, marah, dan benci banget sama dia. Di benak saya udah pengen putus aja. Karena menurut saya harusnya disaat kondisi pasangan terpuruk seperti ini, peran pasangan adalah sebagai support sistem. Seperti hal yang selama ini saya lakukan untuk dia.

    Tapi tidak lama setelah kejadian itu, dia minta maaf dan membujuk saya, ngejelasin kalau dia tidak bermaksud seperti itu. Ya intinya saya terima permintaan maafnya, dan hubungan kami jalan lagi, walaupun sampai sekarang saya tidak pernah mau sharing apa-apa lagi tentang bisnis ini ke dia.

    Di tengah keterpurukan saya, dimana aplikasi prosesnya yang sering macet, komplain dari customer, penjualan tidak pernah mencapai target, modal sering ditalangin dari duit pribadi, website terblokir di whatsapp (nggak bisa pakai whatsapp lagi). Besar banget alasan untuk berhenti sebenarnya.

    Tapi justru karena karya saya dihina, dicampakkan, dan diragukan oleh pacar sendiri. Ini yang membuat saya akhirnya berubah jadi Hulk 😎. Dikepala saya cuman ada kejengahan, rasa ingin membuktikan, bahwa “Kamu salah!, lihat aja nanti, bisnis ini akan berhasil… akan aku buktikan!”.

    Dan di hari valentine kemarin (14 Februari 2024). Saya belikan doi kado spesial, yang uangnya dari hasil keuntungan bisnis ini. Doi happy banget nerima kadonya, karena isinya adalah hal yang ia butuhkan selama ini. Tapi satu hal yang dia tidak tau adalah, kado itu dibeli menggunakan uang dari bisnis ini. 😎 Sampai hari inipun doi belum tau itu. Saya memang sengaja mengunggu momennya, kapan-kapan saat doi nanyain kabar bisnis ini, saya akan ceritakan dan sekaligus tunjukin history penjualan dari bisnis ini.

    Tapi jangan salah ya, saya sangat-sangat mencintai pacar saya. Ini saya lakukan, bukan lagi karena dorongan rasa marah, tapi lebih kepada upaya untuk mengubah pandangan dia terkait bisnis yang sudah lama saya perjuangkan ini.

    Mungkin ini terdengar seperti drama di film-film, tapi ini true story.

    Apa Yang Membuat Saya Bertahan?

    Selain alasan-alasan diatas, ada satu hal yang paling mendasari, kenapa saya tetap bertahan sampai hari ini, di bisnis ini. Adalah karena satu kata, yaitu “POTENSI”.

    POTENSI yang saya maksud begini, kalau di pandang dari rumus ekonomi, yang paling basic sekalipun, itu adalah tentang “supply and demand” (persediaan dan permintaan), Bisnis ini tuh, pasarnya akan selalu ada, permintaannya akan semakin besar, tapi saat ini suplaynya sangat terbatas.

    Dikala ada permintaan dalam jumlah besar, tapi persediaannya terbatas. Itu adalah indikasi peluang bisnis yang sangat-sangat gurih. Apalagi jika kita bisa menjadi salah satu pihak yang men-supply demand tersebut, Maka auto cuan.

    Jadi bayangan saya terhadap potensi bisnis ini, di kepala saya, itu diibaratkan seperti “setitik cahaya kecil”, yang selalu menyala, segelap apapun masalah yang datang. Walaupun setitik cahaya kecil, dikala gelap, ia akan menjadi sumber penerangan utama.

    Jadi, POTENSI, adalah sumber motivasi utama saya, untuk mencoba sekali lagi… sekali lagi… dan lagi.

    Coba deh dipikir baik baik, lah kita, segala sumber dayanya sudah punya (aplikasinya sudah jadi, websitenya sudah jadi), sudah siap untuk mensupply nih, nah PR berikutnya adalah tinggal mendekatkan diri ke market. Karena marketnya sudah ada, permintaannya besar, tapi yang bisa mensuplai masih sangat sedikit.

    Nah itulah alasan kenapa saya tetap bertahan sampai sekarang. Yaitu karena melihat potensi bisnis ini. Itu adalah mindset yang selalu menyala di dalam hati dan pikiran saya.

    Bagaimana Keadaan Bisnis Ini Sekarang?

    Seperti yang saya jelasin di awal-awal tadi, sekarang bisnis kami ini sedang dalam kondisi yang sangat membanggakan. Keyakinan yang saya pegang selama 2 Tahun belakangan, tentang potensi bisnis ini, akhirnya mulai terbukti sekarang. Benar saja, sekarang bisnis ini sedang ketemu momentumnya. Kalau di ibaratkan pesawat, Nah si pesawatnya sekarang lagi Take Off. Manuver ini terjadi tepat pada awal Januari 2024. Berikut ini adalah screen capture dari dashboard “Google Search Console” website saya.

    Grafik pengunjung bisnis baru saya

    Kalau ibaratkan pesawat, sebelum take off, tentu pesawat harus melaju datar dulu kan?, disaat kecepatannya sudah memadai, maka barulah pesawat layak untuk take off. Apa gitu kali ya filosofinya? πŸ˜‚


    Catatan : kenaikan ini bukan karena iklan berbayar, endorsment, ataupun hal semacamnya. Ini benar-benar terjadi secara organik.


    Bisa dilihat grafik diatas, dari ujung kiri ke kanan, perhatikan periode tanggalnya. Disana terlihat betapa mirisnya pengunjung website saya dari Tahun 2022 sampai akhir Tahun 2023.

    Grafik diatas adalah gambaran “Usaha tidak menghianati hasil”, kuncinya adalah tekun dan sabar.

    2 Tahun broooo! πŸ€£πŸ˜‚

    Yang awalnya, tiap minggu kadang ada omset, kadang kagak. Bayar domain dan hosting ditalangin mulu. Tapi sekarang sangat bersyukur, dikit-dikit ada aja notifikasi orderan masuk.

    Perasaan tiap hari rasanya happy, penuh rasa syukur aja sih. Ternyata hal yang saya perjuangkan selama 2 Tahun ini, berbuah manis. Nggak sia-sia, dan sudah bisa dikatakan jadi salah satu sumber penghasilan yang oke lah sekarang. Bisa di bangga-banggain lah intinya. 😁

    Apa Yang Mau Di Capai Kedepannya?

    Sebetulnya kalau di lihat dari grafik pengunjung website diatas, tentu masih sangat-sangat jauh, kalau dibandingkan dengan jumlah pengunjung website, bisnis utama saya, yang 1 harinya bisa nyentuh rata-rata 6.000 – 8.000an pengunjung. Dan itupun kalau dibandingkan dengan bisnis temen-temen yang lain, ini mah nggak ada apa apanya. ehehehe. Tapi untuk kapasitas saya, seorang Putu Adi. Ini cukup oke.

    Grafik pengunjung bisnis utama saya

    Tapi sekali lagi, ini tentang “potensi”. Cerita baru saja dimulai brooo.

    Bisnis utama saya, produknya adalah produk fisik, yang sebelum jualan, kita harus mikirin produksinya dulu, setelah ada orderan masuk, kita harus packing dulu, baru kirim barangnya ke kurir, pengiriman berhari-hari, barulah sampai ke tangan customer. Rata-rata sih pengiriman sekitar 1 – 2 hari, bahkan kalau kota yang jauh seperti aceh (sumatra) dan sorong (papua) itu bisa hitungan mingguan. Belum lagi ada resiko barang rusak saat pengiriman.

    Nah sedangkan, bisnis baru saya ini, adalah bisnis digital. Yang dijual adalah layanan. Sehingga saat ada orderan masuk, seketika langsung di proses oleh sistem. Tidak perlu produksi, tidak perlu packing, tidak perlu kirim ke kurir. Jadi dari segi pekerjaan jauh lebih gampang, dan dari segi biaya jauh lebih murah. Sedangkan harga layanan yang saya jual disini (produk digital), harganya jauh lebih mahal dan lebih menguntungkan dibandingkan dengan bisnis utama saya (yang produknya fisik).

    Jadi potensinya sangat-sangat besar.

    Kedepannya, saya lagi merencanakan untuk rekrut tim. Utamanya untuk CS (balesin chat customer), operator sistem (yang memproses dan memantau kinerja sistem), dan editor (untuk rutin memproduksi konten).

    Ini 3 posisi yang sementara ini paling saya butuhkan, untuk menggantikan posisi saya. Agar saya bisa lebih fokus pada kegiatan atau strategi marketing, sehingga dengan adanya tim, harapannya target-target bisa dengan mudah dicapai.

    Penutup

    Dari sini saya benar-benar paham makna dari “Usaha tidak pernah menghianati hasil”. Berkat ketekunan dan kesabaran selama 2 Tahun, akhirnya sekarang seluruh kerja keras saya berbuah manis. Saya tidak sedang ingin berupaya memotivasi siapa-siapa, ini murni artikel yang saya tulis untuk merayakan kemenangan saya aja sih. jadi tanpa banyak basa basi lagi. artikel ini saya tutup.

    Terima Kasih sudah membaca.

  • Membuat HTML Select Tag Element Agar Ada Search Box nya

    Membuat HTML Select Tag Element Agar Ada Search Box nya

    Kronologi

    Ini agar receh sebenernya, tapi bagi programmer pemula pasti sangat bermanfaat. Seperti yang kita tau, salah satu tugas programmer bukan hanya sekedar jago bikin program, tapi juga bagaimana membuat user mudah menggunakan aplikasi, yang sedang kita kembangkan.

    Salah satu cara mempermudah user dalam menggunakan aplikasi kita adalah, membuat select tag element agar bisa di search, tidak sekedar muncul drop down saat di klik, tapi juga bisa di search atau di ketik untuk mencari data yang muncul pada select element tersebut.

    Contoh select tag yang simpel

    <select class="form-select">
      <option selected>Pilih...</option>
      <option value="1">Pilihan Satu</option>
      <option value="2">Pilihan Dua</option>
      <option value="3">Pilihan Tiga</option>
    </select>

    Masalah

    Kalau pilihannya cuman 3 sih nggak masalah pakai cara ini, tapi kalau pilihannya dinamis, isinya puluhan, ratusan atau bahkan ribuan gimana?

    Bisa-bisa user mabok, memilih salah satu data, dari sekian banyak pilihan yang tampil.

    Solusi

    Sebetulnya ada banyak cara, tapi ini salah satu cara yang belakangan ini sering saya pakai, untuk membuat search pada select element. Yaitu dengan Selectize berbasis jQuery.

    1. Load semua komponen Selectize

    <!-- Load CSS nya -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/css/selectize.bootstrap3.min.css" integrity="sha256-ze/OEYGcFbPRmvCnrSeKbRTtjG4vGLHXgOqsyLFTRjg=" crossorigin="anonymous" />
    
    <!-- Load jquery nya -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    
    <!-- Load Javascript Selectize -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/standalone/selectize.min.js" integrity="sha256-+C0A5Ilqmu4QcSPxrlGpaZxJ04VjsRjKu+G82kl5UJk=" crossorigin="anonymous"></script>

    2. Siapkan select elementnya

    Pertama siapkan file koneksi.php

    <?php
    $dbhost = "localhost"; 
    $dbuser = "xxx";     // isi user name database kamu
    $dbpass = "xxx";     // ini password database kamu
    $dbname = "xxx";     // ini nama database kamu
    
    // melakukan koneksi ke database
    $connect = new mysqli($dbhost,$dbuser,$dbpass,$dbname);
    
    mysqli_set_charset($connect,"utf8");
    
    // cek koneksi yang kita lakukan berhasil atau tidak
    if ($connect->connect_error) {
       // jika terjadi error, matikan proses dengan die() atau exit();
       die('Maaf koneksi gagal: '. $connect->connect_error);
    }

    Lalu, siapkan element selectnya. Saya asumsikan kalian sudah punya database dan tabel yang ingin di olah ya.

    <label class="form-label">Nama Produk</label>							  				
    <select placeholder="Ketik nama produk..." name="id_produk" id="id_produk">
    	<option value="" selected>Ketik nama produk...</option>
    	<?php
    	include "koneksi.php";    
    	$query = "SELECT * FROM tb_produk";
    	$hasil = mysqli_query($connect, $query) or die("Gagal terhubung ke database " . mysqli_error($connect));
    	while($data=mysqli_fetch_array($hasil)){
    		echo "<option value=$data[id_produk]>$data[nama_produk]</option>";
    	}
    	?>
    </select>

    Kita juga perlu mendefinisikan, bahwa si Selectize ini akan hanya berefek pada select tag yang memiliki ID atau Nama tertentu, dalam contoh ini adalah “id_produk”. Ini penting agar tidak berpengaruh ke select tag lainnya, yang tidak memerlukan tritmen seperti ini.

    <script type="text/javascript">
    	$(document).ready(function () {
    		$('#id_produk').selectize({
    			sortField: 'text'
    		});
    	});
    </script>

    Semoga bermanfaat ya. Kalau ada yang ingin ditanyakan, bisa DM saya di sosmed.

    Lihat contoh hasilnya

  • Cara Ambil Nilai Element HTML Select, Bukan Value, Tapi Textnya

    Cara Ambil Nilai Element HTML Select, Bukan Value, Tapi Textnya

    Kronologi

    Saya sedang ngerjain project ERP (Enterprise Resource Planning), dan menemukan kasus unik, dimana pada fitur yang sedang saya buat kali ini, mengharuskan saya mengambil nilai dari element select. Bukan isi valuenya, tetapi isi text yang dipilih. Contohnya begini.

    Dibawah ini, ada sebuah elemen select, dengan 3 pilihan. Nah perhatikan di bagian valuenya. Contoh untuk Pcs, disana valuenya 4000. Pcs mewakili satuannya, sedangkan 4000 mewakili harganya.

    Jadi untuk produk ini, per pcsnya, harganya 4000. dan untuk satuan Bal, harga per bal nya 12000, terakhir, 1 Box harganya 40000.

    <label for="satuanProduk">Satuan Produk:</label>
    <select id="satuanProduk">
      <option value="4000">Pcs</option>
      <option value="12000">Bal</option>
      <option value="40000">Box</option>
    </select>

    Masalah

    Nah kalau dengan sistem penyeimpanan normal, menggunakan metode $_POST di php. Jika dari 3 opsi, kita pilih satuannya.

      <option value="4000">Pcs</option>

    Misalnya adalah Pcs, maka saat kita simpan, nilai yang kita dapatkan adalah sesuai isi dari valuenya, yaitu 4000, bukan Pcs.

    Nah sampai saat ini saya belum tau cara mendapatkan nilai textnya yaitu “Pcs”. Dengan perintah php standar.

    Solusi

    Dari pada makin botak, saya akali dengan Javascript aja dengan membuat satu input baru bernama “mirror”, yang fungsinya memirroring atau menangkap nilai dari text si <select> satuanProduk secara realtime, saat ada perubahan di select satuanProduk, akan langsung di kirim isi textnya ke input mirror.

    Nanti hasil mirroring dari input “mirror” inilah yang saya simpan. Bukan nilai dari si <select> satuanProduk ini. Tapi si input “mirror” ini saya hide (dengan type=”hidden”), agar tidak mengganggu estetika.

    Jadi contoh penerapannya seperti ini.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Real-time Mirror</title>
    </head>
    <body>
        <label for="satuanProduk">Satuan Produk:</label>
        <select id="satuanProduk" onchange="updateMirror()">
            <option value="4000">Pcs</option>
            <option value="12000">Bal</option>
            <option value="40000">Box</option>
            <!-- Tambahkan opsi lain jika diperlukan -->
        </select>
        <br>
        <label for="mirror">Mirror:</label>
        <input type="text" id="mirror" readonly>
        <script>
            function updateMirror() {
                // Mengambil elemen select berdasarkan id
                var selectSatuanProduk = document.getElementById("satuanProduk");
    
                // Mengambil nilai teks yang dipilih pada select
                var nilaiTeksPilihan = selectSatuanProduk.options[selectSatuanProduk.selectedIndex].text;
    
                // Mengambil elemen input mirror berdasarkan id
                var inputMirror = document.getElementById("mirror");
    
                // Menetapkan nilai input mirror dengan nilai teks yang dipilih pada select
                inputMirror.value = nilaiTeksPilihan;
            }
        </script>
    </body>
    </html>

    Lihat demonya disini