#!/usr/bin/env python3
"""Perbaikan harian tslaw.id 2026-10-05 - post 2940
/6-jenis-surat-kuasa-hukum-dan-fungsinya-yang-wajib-anda-pahami/

Prioritas 1 (ada tayangan, klik NOL, posisi 69,5): judul SEO + meta desc + fokus kw
diselaraskan ke kueri nyata GSC -> "surat kuasa", "fungsi surat kuasa".
Prioritas 2: 864 -> 1.000+ kata dengan isi berguna (6 jenis surat kuasa + dasar hukum).
Prioritas 5: tambah 1 tautan kontekstual ke pilar /law-firm-surabaya/.

Bonus integritas: 6 paragraf rusak (<p><p>) dirapikan; judul lama menjanjikan "6 jenis"
padahal isi hanya memuat 3 jenis -> 6 jenis nyata ditulis ulang dengan rujukan
KUHPerdata dan PP 24/1997 Pasal 39 ayat (1) huruf d (terverifikasi).
Nama kantor "Tito Supriyanto Law Firm (TSLaw)" -> "TS Law" (sebutan di beranda situs).

Jalankan tanpa argumen = dry run. Dengan --apply = tulis via REST (JSON) + verifikasi.
"""
import base64, html as htmlmod, json, os, re, sys
import urllib.request, urllib.error

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
sys.path.insert(0, WS)
from cfg_tslaw import CFG

AUTH = base64.b64encode(f"{CFG['user']}:{CFG['pass']}".encode()).decode()
BASE = "https://tslaw.id/wp-json/wp/v2"
HDR = {"Authorization": f"Basic {AUTH}", "User-Agent": "Mozilla/5.0"}

PID = 2940
OUT = f"{WS}/tslaw_pemulihan/perbaikan_20261005"
os.makedirs(OUT, exist_ok=True)


def rest_get(path, timeout=90):
    req = urllib.request.Request(BASE + path, headers=HDR)
    with urllib.request.urlopen(req, timeout=timeout) as r:
        return json.load(r)


def rest_post(path, payload, timeout=180):
    req = urllib.request.Request(
        BASE + path, data=json.dumps(payload).encode(),
        headers={**HDR, "Content-Type": "application/json"}, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=timeout) as r:
            return r.status, json.load(r)
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode()[:800]


def wc(html):
    t = htmlmod.unescape(re.sub(r"<(script|style).*?</\1>", " ", html, flags=re.S))
    t = re.sub(r"<[^>]+>", " ", t)
    return len(t.split())


p = rest_get(f"/posts/{PID}?context=edit")
raw = p["content"]["raw"]
open(f"{OUT}/post_{PID}_SEBELUM.html", "w").write(raw)
json.dump(p, open(f"{OUT}/post_{PID}_SEBELUM.json", "w"), ensure_ascii=False, indent=1)
KATA_SEBELUM = wc(raw)
print(f"[sebelum] kata={KATA_SEBELUM} judul={p['title']['raw']!r}")
print(f"[sebelum] seo={p['meta'].get('_yoast_wpseo_title')!r} fokus={p['meta'].get('_yoast_wpseo_focuskw')!r}")

# ---------- komponen yang dipakai ulang apa adanya (jangan ubah desain) ----------
m_btn = re.search(r'<div class="wp-block-buttons[\s\S]*?</div>\s*</div>', raw)
assert m_btn, "blok tombol WA tidak ditemukan"
WA_BTN = m_btn.group(0)
assert WA_BTN.count("wa.me/6281909222026") == 1, "nomor WA tidak seperti seharusnya"

BACA_LINKS = [
    ("https://www.tslaw.id/7-alasan-mengapa-jasa-pengacara-terbaik-surabaya-wajib-untuk-kasus-bisnis-anda-3/",
     "7 Alasan Mengapa Jasa Pengacara Terbaik Surabaya Wajib untuk Kasus Bisnis Anda"),
    ("https://www.tslaw.id/hak-konsumen-di-indonesia-perlindungan-hukum/",
     "Hak Konsumen di Indonesia: Perlindungan Hukum yang Wajib Anda Tahu"),
    ("https://www.tslaw.id/5-tips-memilih-pengacara-yang-tepat-untuk-bisnis-anda/",
     "5 Tips Memilih Pengacara yang Tepat untuk Bisnis Anda"),
]
for u, _ in BACA_LINKS:
    assert u in raw, f"tautan Baca juga hilang: {u}"

FAQ = [
    ["Apa beda surat kuasa umum dan khusus?",
     "Kuasa umum meliputi tindakan pengurusan secara luas, sedangkan kuasa khusus dibatasi pada satu perkara atau urusan tertentu. "
     "Untuk tindakan yang menyangkut pemindahan atau pembebanan harta, wewenangnya harus disebut tegas."],
    ["Apakah surat kuasa harus dibuat di notaris?",
     "Tidak selalu. Kuasa lisan pun diakui, dan untuk beracara di pengadilan pendaftaran di kepaniteraan umumnya sudah cukup. "
     "Notaris dibutuhkan bila pihak ketiga mensyaratkan kepastian tanggal atau legalisasi tanda tangan."],
    ["Bisakah surat kuasa dicabut?",
     "Bisa, kapan saja. Pemberi kuasa cukup membuat pemberitahuan tertulis kepada penerima kuasa dan pihak terkait agar pencabutan "
     "itu bisa dibuktikan terhadap pihak ketiga."],
    ["Apakah surat kuasa ada masa berlakunya?",
     "Bisa ditentukan di dalam surat, misalnya sampai urusan selesai atau sampai tanggal tertentu. Kalau tidak ditentukan, kuasa "
     "berlaku sampai urusan tuntas atau dicabut."],
    ["Apa risiko memberikan surat kuasa?",
     "Penyalahgunaan wewenang. Karena itu batas kewenangan perlu ditulis spesifik, objeknya disebut jelas, dan pemberi kuasa "
     "sebaiknya menyimpan salinan serta mencatat setiap tindakan penerima kuasa."],
    ["Apa itu surat kuasa istimewa?",
     "Kuasa istimewa diberikan untuk tindakan yang menurut undang-undang wajib dinyatakan secara tegas, seperti menjual atau "
     "membebani aset, mengadakan perdamaian, atau mewakili perkara di pengadilan. Tindakan yang tidak disebut dianggap di luar wewenang."],
    ["Apakah surat kuasa mutlak sah?",
     "Untuk pemindahan hak atas tanah, kuasa mutlak tidak bisa dipakai. PPAT wajib menolak membuat akta bila salah satu pihak "
     "bertindak atas dasar surat kuasa mutlak yang pada hakikatnya berisikan perbuatan hukum pemindahan hak, sebagaimana diatur "
     "dalam Pasal 39 ayat (1) huruf d PP No. 24 Tahun 1997 tentang Pendaftaran Tanah."],
]


def blok_h2(t):
    return f'<h2 class="wp-block-heading">{t}</h2>'


bagian = []
bagian.append(
    "<p>Surat kuasa dipakai di hampir semua urusan hukum: mengurus sertifikat tanah, mewakili perusahaan menandatangani kontrak, "
    "sampai beracara di pengadilan. Karena fungsinya berbeda-beda, salah memilih jenis surat kuasa bisa membuat tindakan yang Anda "
    "percayakan kepada orang lain jadi tidak sah. Ulasan berikut membahas fungsi surat kuasa, enam jenis yang paling sering dipakai, "
    "dasar hukumnya, dan syarat yang harus dipenuhi agar dokumen ini kuat saat diuji.</p>")

bagian.append(blok_h2("Pengertian Surat Kuasa dan Dasar Hukumnya"))
bagian.append(
    "<p>Menurut Pasal 1792 KUHPerdata, pemberian kuasa adalah perjanjian dengan mana seseorang memberikan kekuasaan kepada orang lain, "
    "yang menerimanya, untuk dan atas namanya menyelenggarakan suatu urusan. Kata kuncinya \"untuk dan atas nama\": penerima kuasa "
    "bertindak sebagai wakil, sementara akibat hukumnya tetap melekat pada pemberi kuasa.</p>")
bagian.append(
    "<p>Bentuknya tidak wajib akta notaris. Pasal 1793 KUHPerdata membuka ruang bagi kuasa yang dibuat dengan akta umum, akta di bawah "
    "tangan, surat, bahkan lisan, dan penerimaan kuasa bisa terjadi secara diam-diam. Kebebasan bentuk itu aman untuk urusan ringan. "
    "Begitu menyangkut pengadilan, aset, atau nilai besar, surat kuasa tertulis dengan batas yang jelas menjadi keharusan praktis karena "
    "Anda perlu bisa membuktikannya saat timbul sengketa.</p>")

bagian.append(blok_h2("Fungsi Surat Kuasa"))
bagian.append(
    "<p>Ada empat fungsi yang membuat surat kuasa penting. Pertama, mewakili tindakan hukum ketika pemberi kuasa tidak bisa hadir sendiri, "
    "misalnya karena sakit, berada di luar kota, atau sedang menjalankan usaha. Kedua, memberi dasar hukum bagi pihak ketiga: notaris, bank, "
    "atau instansi pemerintah tidak akan menerima tindakan seorang wakil tanpa dokumen kuasa. Ketiga, membatasi wewenang supaya penerima "
    "kuasa tidak bertindak di luar yang Anda izinkan. Keempat, menjadi alat bukti bila nantinya ada pihak yang mempersoalkan tindakan tersebut.</p>")
bagian.append(
    "<p>Dengan memahami fungsi ini, Anda bisa menilai sendiri seberapa luas wewenang yang layak diberikan. Semakin besar nilainya, semakin "
    "sempit kuasa sebaiknya dibuat.</p>")

bagian.append(blok_h2("1. Surat Kuasa Umum"))
bagian.append(
    "<p>Surat kuasa umum meliputi tindakan pengurusan, misalnya mengurus administrasi pajak, memperbarui dokumen perusahaan, atau mengambil "
    "berkas di instansi. Luasnya wewenang membuat jenis ini sering disalahpahami sebagai kuasa untuk segala hal. Pasal 1795 dan 1796 "
    "KUHPerdata memberi batas: kuasa umum tidak dengan sendirinya meliputi perbuatan memindahtangankan atau membebani harta. Untuk tindakan "
    "semacam itu, wewenangnya harus disebut tegas.</p>")
bagian.append(
    "<p>Hindari rumusan longgar seperti \"mengurus segala kepentingan pemberi kuasa\". Sebutkan urusan yang dimaksud satu per satu.</p>")

bagian.append(blok_h2("2. Surat Kuasa Khusus"))
bagian.append(
    "<p>Surat kuasa khusus hanya mencakup satu urusan atau beberapa urusan yang dirinci. Contohnya mewakili klien dalam sengketa wanprestasi "
    "di Pengadilan Negeri Surabaya, atau menandatangani perjanjian kerja sama tertentu. Pasal 1795 KUHPerdata membolehkan pemberian kuasa "
    "dibatasi pada satu kepentingan tertentu atau lebih.</p>")
bagian.append(
    "<p>Dalam praktik peradilan, surat kuasa khusus untuk beracara harus menyebut pengadilan yang berwenang, pokok perkara, dan identitas "
    "para pihak. Tanpa itu, hakim dapat menilai kuasa tidak sah dan sidang terpaksa ditunda.</p>")

bagian.append(blok_h2("3. Surat Kuasa Istimewa"))
bagian.append(
    "<p>Surat kuasa istimewa jarang disebut dalam percakapan sehari-hari, padahal perannya penting. Jenis ini dipakai untuk tindakan yang "
    "menurut undang-undang wajib dinyatakan secara tegas: menjual atau membebani aset, mengadakan perdamaian, mengajukan gugatan, dan "
    "tindakan lain yang menyangkut pemindahan hak. Apa pun yang tidak disebut dianggap di luar wewenang penerima kuasa.</p>")
bagian.append(
    "<p>Karena sifatnya, salah mencantumkan objek bisa berakibat fatal. Menyebut \"tanah milik bersama\" tanpa nomor sertifikat dan lokasi "
    "yang pasti sering membuat akta bermasalah di kemudian hari. Rinci alamat, nomor sertifikat, dan luas bidangnya.</p>")

bagian.append(blok_h2("4. Surat Kuasa Substitusi"))
bagian.append(
    "<p>Surat kuasa substitusi adalah kuasa yang diberikan oleh penerima kuasa kepada pihak lain untuk menggantikannya. Pasal 1800 KUHPerdata "
    "mengatur hal ini: penggantian hanya sah bila pemberi kuasa memang memberi wewenang untuk itu. Tanpa wewenang tersebut, penerima kuasa "
    "tetap bertanggung jawab atas tindakan penggantinya.</p>")
bagian.append(
    "<p>Dalam praktik, advokat memakai kuasa substitusi ketika berhalangan hadir dan menunjuk rekan sejawat. Pastikan surat kuasa awal memuat "
    "klausul penggantian supaya pelimpahan tidak dipersoalkan.</p>")

bagian.append(blok_h2("5. Surat Kuasa Mutlak"))
bagian.append(
    "<p>Surat kuasa mutlak dirancang agar tidak dapat dicabut dan sering dipakai untuk mengikat pihak lain dalam sebuah transaksi. Untuk "
    "pemindahan hak atas tanah, pemakaiannya dilarang. Pasal 39 ayat (1) huruf d PP No. 24 Tahun 1997 tentang Pendaftaran Tanah mewajibkan "
    "PPAT menolak membuat akta jika salah satu pihak bertindak atas dasar surat kuasa mutlak yang pada hakikatnya berisikan perbuatan hukum "
    "pemindahan hak.</p>")
bagian.append(
    "<p>Artinya, jual beli tanah yang hanya bersandar pada kuasa mutlak tidak bisa didaftarkan. Praktik yang benar adalah akta pemindahan hak "
    "yang dibuat PPAT, dengan kehadiran pihak yang berhak.</p>")

bagian.append(blok_h2("6. Surat Kuasa Insidentil"))
bagian.append(
    "<p>Surat kuasa insidentil dipakai dalam praktik peradilan untuk memberi kesempatan kepada orang yang bukan advokat, biasanya keluarga atau "
    "kerabat dekat, mewakili pihak yang berperkara. Karena menyimpang dari aturan umum bahwa beracara memerlukan advokat, izinnya terbatas dan "
    "diberikan lewat ketua pengadilan.</p>")
bagian.append(
    "<p>Jenis ini bersifat kasuistis. Untuk perkara yang serius, memakai jasa advokat dengan surat kuasa khusus tetap lebih aman.</p>")

bagian.append(blok_h2("Syarat Sah Surat Kuasa dan Cara Membuatnya"))
bagian.append("<p>Agar kuat dipakai, surat kuasa perlu memuat lima hal berikut:</p>")
bagian.append(
    "<ul><li><strong>Identitas lengkap</strong> pemberi dan penerima kuasa sesuai KTP, termasuk alamat.</li>"
    "<li><strong>Objek kuasa yang spesifik</strong>, bukan rumusan \"segala urusan\".</li>"
    "<li><strong>Batas wewenang</strong>, yaitu apa yang boleh dan tidak boleh dilakukan penerima kuasa.</li>"
    "<li><strong>Masa berlaku</strong>, misalnya sampai perjanjian selesai atau sampai tanggal tertentu.</li>"
    "<li><strong>Tanda tangan kedua pihak</strong>, dan meterai Rp10.000 bila dokumen diperlukan sebagai alat bukti formal.</li></ul>")
bagian.append(
    "<p>Setelah dibuat, simpan satu salinan di tempat aman dan catat setiap tindakan penerima kuasa. Pencatatan sederhana sering "
    "menyelamatkan Anda ketika wewenang dipertanyakan.</p>")

bagian.append(blok_h2("Kapan Surat Kuasa Perlu Dibuat di Notaris atau PPAT?"))
bagian.append(
    "<p>Tidak semua surat kuasa harus dilewatkan notaris. Untuk mengambil dokumen atau menandatangani formulir administrasi, tanda tangan Anda "
    "sendiri sudah cukup. Notaris dibutuhkan ketika dokumen harus punya kepastian tanggal atau ketika pihak ketiga mensyaratkannya. Ada dua "
    "perlakuan yang biasa ditemui: legalisasi, yaitu notaris menyaksikan penandatanganan, dan waarmerking, yaitu notaris mendaftarkan surat yang "
    "sudah ditandatangani sebelumnya.</p>")
bagian.append(
    "<p>Untuk perbuatan hukum atas tanah, akta PPAT adalah syarat, bukan pilihan. Sebelum berkas diperiksa, ada baiknya Anda berdiskusi lebih "
    "dulu dengan <a href=\"https://www.tslaw.id/law-firm-surabaya/\">law firm Surabaya</a> agar bentuk dan isi dokumennya langsung sesuai ketentuan.</p>")

bagian.append(blok_h2("Risiko Penyalahgunaan Surat Kuasa dan Cara Mencegahnya"))
bagian.append(
    "<p>Kekhawatiran terbesar pemberi kuasa adalah wewenang dipakai melebihi maksud. Risiko ini nyata pada surat kuasa yang luas dengan masa "
    "berlaku tanpa batas. Beberapa langkah pencegahan yang bisa dilakukan:</p>")
bagian.append(
    "<ul><li>Tulis batas wewenang secara spesifik dan sebut objeknya.</li>"
    "<li>Cantumkan masa berlaku atau syarat berakhirnya kuasa.</li>"
    "<li>Simpan salinan resmi dan jangan pernah menyerahkan blanko bertanda tangan.</li>"
    "<li>Catat nomor akta atau tanggal surat kuasa supaya mudah ditelusuri.</li>"
    "<li>Cabut secara tertulis begitu urusan selesai, lalu beritahukan kepada pihak yang pernah menerima salinannya.</li></ul>")
bagian.append(
    "<p>Pencabutan kuasa tidak perlu menunggu masa berlaku habis. Pemberi kuasa berhak menariknya kapan saja, dan pemberitahuan tertulis "
    "membuat pencabutan itu bisa dibuktikan terhadap pihak ketiga.</p>")

bagian.append(blok_h2("Konsultasikan Pembuatan Surat Kuasa dengan Advokat TS Law"))
bagian.append(
    "<p>Pembuatan surat kuasa terlihat sederhana, tetapi kesalahan kecil pada rumusan wewenang bisa membatalkan tindakan yang sudah berjalan. "
    "TS Law membantu menyusun surat kuasa untuk kebutuhan perdata, pidana, maupun bisnis, mulai dari urusan administrasi sampai beracara di "
    "pengadilan. Layanannya mencakup pemeriksaan wewenang, penyusunan klausul, hingga pendampingan saat dokumen dipersoalkan. Konsultasi awal "
    "bisa dilakukan tanpa biaya lewat tombol di bawah.</p>")

bagian.append(blok_h2("Kesimpulan"))
bagian.append(
    "<p>Surat kuasa adalah dasar bagi setiap tindakan yang dilakukan seseorang atas nama pihak lain. Enam jenis yang dibahas di atas, yaitu "
    "umum, khusus, istimewa, substitusi, mutlak, dan insidentil, punya fungsi serta batas masing-masing. Memilih jenis yang tepat dan menulis "
    "wewenang secara spesifik jauh lebih murah daripada memperbaiki akta yang bermasalah. Bila nilai urusannya besar, libatkan advokat sejak "
    "tahap penyusunan.</p>")

bagian.append(WA_BTN)

bagian.append("<h2>Baca juga</h2>")
bagian.append("<p>Kalau topiknya berhubungan dengan kebutuhan Anda, artikel berikut membahasnya lebih dalam: " +
              ", ".join(f'<a href="{u}">{t}</a>' for u, t in BACA_LINKS) + ".</p>")

bagian.append("<h2>Pertanyaan yang Sering Diajukan</h2>")
for q, a in FAQ:
    bagian.append(f"<h3>{q}</h3>")
    bagian.append(f"<p>{a}</p>")

new = "\n".join(bagian) + "\n"


def plain(s):
    return htmlmod.unescape(re.sub(r"<[^>]+>", "", s)).strip()


schema = {"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [
    {"@type": "Question", "name": plain(q), "acceptedAnswer": {"@type": "Answer", "text": plain(a)}}
    for q, a in FAQ]}
new += '<script type="application/ld+json">' + json.dumps(schema, ensure_ascii=False) + "</script>\n"

# ---------- judul + meta selaras kueri nyata ----------
TITLE = "Surat Kuasa: Fungsi, 6 Jenis, dan Cara Membuatnya yang Sah"
SEO_TITLE = "Fungsi Surat Kuasa dan 6 Jenisnya yang Wajib Diketahui"
FOKUS = "surat kuasa"
META = ("Surat kuasa adalah dasar bagi setiap tindakan atas nama orang lain. Kenali 6 jenisnya, "
        "fungsi, syarat sah, dan cara membuatnya yang benar.")

# ---------- validasi ----------
assert 120 <= len(META) <= 158, f"meta {len(META)} char di luar 120-158"
assert META.lower().startswith(FOKUS), "meta tidak diawali fokus kw"
assert len(SEO_TITLE) <= 60, f"seo title {len(SEO_TITLE)} char"
assert FOKUS in (SEO_TITLE + " " + META + " " + TITLE).lower(), "fokus kw tidak ada di judul/meta"
assert "fungsi surat kuasa" in SEO_TITLE.lower(), "kueri 'fungsi surat kuasa' tidak ada di judul"
for tok in ["surat kuasa", "jenis", "fungsi"]:
    assert tok in (SEO_TITLE + " " + META).lower(), f"token '{tok}' tidak ada"
assert "Tito Supriyanto" not in new and "TSLaw" not in new, "nama kantor lama masih ada"
assert new.count("law-firm-surabaya") == 1, "tautan pilar bukan tepat 1"
assert new.count("wa.me/6281909222026") == 1, "tombol WA hilang/berubah"
assert new.count('"@type": "FAQPage"') == 1, "schema FAQPage tidak tepat 1"
assert len(re.findall(r'<h3>', new)) == len(FAQ) == len(schema["mainEntity"]), "FAQ tampil vs schema tidak sinkron"
assert not re.findall(r"\{[A-Za-z_\[\\\]0-9]+\}", new), "masih ada placeholder {..}"
assert not re.search(r"<p>[^<]*<p>", new), "masih ada <p> bersarang"
for tag in ["p", "h2", "h3", "ul", "li", "div", "script"]:
    b = len(re.findall(rf"<{tag}[ >]", new)) - len(re.findall(rf"</{tag}>", new))
    assert b == 0, f"tag <{tag}> tidak seimbang ({b})"

KATA_SESUDAH = wc(new)
print(f"[sesudah] kata={KATA_SESUDAH} ({KATA_SESUDAH - KATA_SEBELUM:+d})")
print(f"[sesudah] H1={TITLE!r}")
print(f"[sesudah] seo={SEO_TITLE!r} ({len(SEO_TITLE)} char)")
print(f"[sesudah] meta={META!r} ({len(META)} char) | fokus={FOKUS!r}")
print(f"[sesudah] FAQ={len(FAQ)} item | schema={len(schema['mainEntity'])} | pilar=1 | WA=1")

open(f"{OUT}/post_{PID}_SESUDAH.html", "w").write(new)

if "--apply" not in sys.argv:
    print("\n[DRY RUN] tidak ada perubahan dikirim.")
    sys.exit(0)

kode, resp = rest_post(f"/posts/{PID}", {
    "title": TITLE, "content": new,
    "meta": {"_yoast_wpseo_focuskw": FOKUS, "_yoast_wpseo_title": SEO_TITLE,
             "_yoast_wpseo_metadesc": META}})
print(f"\nPOST /posts/{PID} -> HTTP {kode}")
if kode != 200:
    print(resp)
    sys.exit(1)
json.dump(resp if isinstance(resp, dict) else {"raw": resp},
          open(f"{OUT}/post_{PID}_POSTRESP.json", "w"), ensure_ascii=False, indent=1)
print("modified :", resp.get("modified"))
