Skip to content
AFM Studio
  • Pages

    AFM Studio
  • Work
  • Lab
  • About
  • CV
  • Contact
  • Projects

    AksaraA searchable library for Otorita IKN's knowledge, where the server checks every reader's access across three levels
  • Daily TaqwaTamper-resistant prayer attendance system for ~2,000 OIKN government employees at Masjid Negara IKN
  • Lantara v2A permit engine for Otorita IKN where administrators add new permit types from a screen, without a developer
  • eKiosk IKNTwo control rooms for Nusantara: kiosk content management and live bus tracking with arrival times that grade themselves
  • E-Monev IKNA monitoring platform for Nusantara's 23-year build, tracking every unit's quarterly progress against 24 national KPIs
  • JDIH OIKNOIKN's public legal document portal, with a controlled publishing workflow and AI summaries that never leave the server
  • Jejak PenanamanA check-in app for IKN tree-planting events that proves each participant was on site with a geofenced selfie
  • Dashboard SAKTIA nightly pipeline and dashboard that replaces OIKN's manual budget downloads for all six of its budget units
  • DoseRxA bedside dose calculator for 127 drugs that rounds each dose to tablets and syrups Indonesian pharmacies sell
  • CubiqA speedcubing trainer with competition-grade timing and a solver I wrote for each of the 8 major puzzles
  • ScimotionAn interactive science library of 86 articles, each explained next to animations the reader can control
  • WA Daily Scrum BotA WhatsApp bot that chases missing standup reports for a 14-person team and flags tasks stuck for days

↑ ↓ to move · Enter to open · Esc to close

JDIH OIKN

OIKN's public legal document portal, with a controlled publishing workflow and AI summaries that never leave the server

Screenshots
documents sent to outside AI services
0
access tiers, checked at every download
3
roles matching the legal directorate's sign-off
5
public and admin pages
36
On this page

The problem

Otorita IKN is a new government body, and it issues its own legal instruments: regulations, decrees, cooperation agreements and more. Before this system, those documents sat in email threads and on local drives. The public had no way to find an official OIKN regulation. There was no controlled review, so anyone with server access could publish anything. Access to sensitive documents was handled informally, with no record of who saw what. The yearly activity report required by OIKN Head Regulation No. 14 of 2025 was assembled by hand.

JDIH is Indonesia's national legal information network, and every agency must run a compliant portal. OIKN needed one with a public side for citizens and a controlled workflow for its Directorate of Law.

What I built

The plan had four roles. In practice it needed five, to match how the directorate works. Legal directorate admins and data stewards can approve documents, and data stewards also handle access requests. Other admins can create and edit documents, but can never approve them. This split came with single sign-on, when it became clear who signs off in the real organisation. Every admin action declares which roles may use it, and the review page is closed to anyone who can't approve.

Access tiers checked at the download

Every document is open, restricted or closed. Restricted documents still appear in search, with a button to request access. A data steward approves the request, with an optional expiry date. Before showing a button, the page asks the server what this person may do: download, request access, or log in. The file link is never sent to someone who can't open it, and every access and download is logged.

AI summaries that never leave the server

I first shipped document summaries through an outside AI service, to prove the feature was worth building. A day later I rebuilt the pipeline to run fully on OIKN's own server, because sending government legal documents to a third-party service is a compliance risk. It pulls the text from each PDF, picks the key sentences into a plain-language summary, and tags the legal field. Over the following month I added a way to check its quality. Staff can write a corrected summary for any document, and a weekly job compares the output against those corrections to catch drift.

A map of which rules change which

A background job reads new document titles for legal citation phrases, such as "revoking Regulation No. 14 of 2022". It finds the document being cited and proposes a link for an admin to confirm. Confirmed links form a public tree showing which regulations revoke, amend or implement each other.

Statistics computed overnight

The admin dashboard and the public statistics page never count documents live. A nightly job fills summary tables, so both pages stay fast as the collection grows. The public page shows a year-long activity heatmap, trending document types and the most-read legal fields. If the nightly table is still empty, the dashboard reads the activity log so it never shows a false zero.

Result

JDIH OIKN is in production. The Directorate of Law uses it to draft, review and publish documents, and the public portal serves open documents to anyone. Staff sign in through OIKN's single sign-on, and outside users sign in with email and password. Past the mandate, I added bookmarks, notifications when an access request changes, moderated star ratings shown on the homepage, and shareable search filters with a CSV export of up to 2,000 rows. I built it between March and June 2026. The last logged release is v1.10.0 in May, and the quality checks for the summaries shipped in June.

Under the hoodTechnical detail for engineers
  • Roles: superadmin, admin_jdih, admin_anggota, walidata, registered. admin_jdih approves through a can_approve property. Permission classes such as IsAdminOrAbove, IsWalidata and IsSuperAdmin live in one permissions.py.
  • Access tiers terbuka / terbatas / tertutup are enforced at the download endpoint. /accesses/check/ returns the right call to action without exposing the file. A Celery task expires stale access grants.
  • Summaries started on Gemini Flash (v1.8.0) and moved offline in v1.9.0: pdfplumber extraction, extractive summaries with sumy and nltk, and a keyword-weighted legal-domain classifier.
  • Quality loop: a RingkasanEvalRun model, gold-summary fields and editor, a legalese-to-plain-language glossary pass, a weekly_ai_eval task, and an evaluate_ai_summaries benchmark command. Superadmins can regenerate stale summaries with a Redis-backed progress bar.
  • detect_relations matches citation patterns such as "mencabut Perka No. 14 Tahun 2022" and creates a RelationCandidate. Confirmed relations render at /pohon-peraturan.
  • refresh_statistik_harian fills StatistikHarian and StatistikDokumen nightly through Celery Beat, with an ActivityLog fallback.
  • Keycloak OIDC via mozilla-django-oidc maps department, NIP and name claims. The OIDC session stays server-side and mints a JWT for the frontend; public users use SimpleJWT with email and password.
  • Cooperation agreements (PKS and MoU) have two party names and no document number, so they use a conditional serializer and a separate slug path.
  • Search uses a PostgreSQL SearchVectorField with a GIN index. sync_berita_ikn imports news from the IKN portal, deduplicated by external ID.
  • 7 Django apps, 25 models, 90 URL patterns, 9 named Celery tasks, 36 frontend routes, 76 frontend source files, about 15,800 lines of frontend code, 100 backend and 91 frontend commits from 7 March to 24 June 2026.

Screenshots

Beranda
Beranda Jenis Dokumen Hukum
Beranda Dokumen Terbaru
Beranda User Feedback
Dokumen Hukum List
Dokumen Detail

Hiring, or building something similar?

I'm open to full-time roles and select freelance work.