PostgreSQL
Spesifikasi komprehensif skema database relasional OLTP PostgreSQL, definisi tabel master, relasi entitas, struktur artikel AI, data sektoral, serta strategi indeks performa di Nexa Intelligence Platform.
PostgreSQL Relational Database (OLTP)
PostgreSQL bertindak sebagai Single Source of Truth (SSOT) dan mesin transaksional (OLTP) utama untuk seluruh ekosistem Nexa Intelligence Platform. Database ini mengelola integritas data master taksonomi 5 level, metadata artikel berita dari ratusan portal media, pemanenan media sosial phone farm, repositori pengadaan barang/jasa pemerintah (LPSE/SIRUP), ekstraksi fakta terstruktur (SPOK), evaluasi kecerdasan buatan (AI reasoning), hierarki 38 provinsi, hingga observabilitas antrean broker Kafka.
Arsitektur & Klaster Tabel Database
Database PostgreSQL diorkestrasi menggunakan Drizzle ORM (TypeScript) pada sisi Backend API (f1-api-backend) serta diakses langsung oleh worker Python (nexa-aggregation, nexa-knowledge-graph, B3 Phone Farm) untuk operasi baca-tulis berkinerja tinggi.
PostgreSQL Schema (Nexa OLTP)
├── 1. Master Taksonomi & Entitas Wilayah
│ ├── taxonomy_nodes # Pohon taksonomi 5-level (L1 - L5) & 5 pilar
│ ├── master_sectors # Data induk 4 peran pemangku kepentingan
│ ├── master_regions # Hierarki wilayah 38 provinsi, kab/kota, kecamatan
│ └── organization_nodes # Entitas K/L, Pemda, TNI, POLRI beserta alias pencarian
│
├── 2. Konfigurasi Ingestion & Target Scraper
│ ├── sources # Direktori portal media, RSS, adaptor, cron, & rate limit
│ ├── scraping_targets # Konfigurasi target scraping domain & link ke organisasi
│ ├── taxonomy_keywords # Frasa kata kunci spesifik simpul taksonomi
│ ├── scraping_target_keywords # Tabel relasi (junction) target scraping & kata kunci
│ ├── keywords # Master kata kunci pencarian umum
│ └── social_keywords # Kata kunci pantauan percakapan media sosial
│
├── 3. Artikel Berita, Ekstraksi AI, & Kurasi Manusia
│ ├── articles # Master metadata artikel berita teranalisis AI
│ ├── article_spoks # Fakta terstruktur SPOK (Subjek, Predikat, Objek, Keterangan)
│ ├── article_currations # Log status kurasi editorial manusia
│ ├── validation_decisions # Rekam jejak koreksi label & keputusan validasi
│ └── gold_dataset_state # Metrik akumulasi dataset acuan (gold dataset)
│
├── 4. Media Sosial & Phone Farm (Pipeline B3)
│ ├── social_trending_topics # Master topik tren media sosial X/Twitter termutakhir
│ ├── social_trending_snapshots # Time-series 15-menit peringkat & laju lonjakan tren
│ ├── postings # Arsip postingan multichannel (X, FB, IG, TikTok)
│ └── post_author # Profil pengunggah & metrik pengaruh akun medsos
│
├── 5. Pengadaan Barang & Jasa Pemerintah (LPSE / SIRUP)
│ ├── fact_procurement # Master paket lelang & pengadaan per RUP ID
│ ├── fact_procurement_regions # Relasi jangkauan wilayah multi-kabupaten paket pengadaan
│ └── fact_procurement_ai # Hasil evaluasi inferensi AI (anomali & pemborosan)
│
├── 6. Data Sektoral Pangan, Pendidikan, & Static Datasets (B2)
│ ├── master_commodities # Katalog komoditas pangan pokok nasional & nama alias
│ ├── fact_indicator # Deret waktu harga pangan harian & indikator ketahanan
│ ├── master_schools # Registri sekolah nasional Kemendikbudristek & koordinat GPS
│ ├── static_datasets # Registri berkas bulk ingest (CSV/Excel via MinIO)
│ └── static_dataset_records # Rekaman baris payload data statis terhashing
│
└── 7. Keamanan, Observabilitas, & Registry Sistem
├── users # Pengguna sistem & kontrol akses berbasis peran (RBAC)
├── audit_log # Log jejak audit aktivitas pengguna dan analis
├── module_registry # Konfigurasi dinamis modul dashboard & navigasi UI
└── kafka_topic_offset_samples # Time-series sampling offset Kafka per menitDiagram Relasi Entitas (ERD)
Diagram di bawah ini mengilustrasikan keterkaitan antar tabel utama dalam skema relasional PostgreSQL Nexa:
erDiagram
master_sectors ||--o{ organization_nodes : "dikelompokkan ke"
master_regions ||--o{ organization_nodes : "berlokasi di"
master_regions ||--o{ fact_procurement : "lokasi utama"
master_regions ||--o{ fact_procurement_regions : "wilayah cakupan"
master_regions ||--o{ master_schools : "wilayah sekolah"
master_regions ||--o{ fact_indicator : "wilayah data"
taxonomy_nodes ||--o{ taxonomy_nodes : "induk hierarki (L1-L5)"
taxonomy_nodes ||--o{ taxonomy_keywords : "memiliki kata kunci"
taxonomy_nodes ||--o{ social_keywords : "memetakan"
taxonomy_nodes ||--o{ articles : "klasifikasi taksonomi"
sources ||--o{ articles : "menerbitkan artikel"
organization_nodes ||--o{ scraping_targets : "memiliki target portal"
scraping_targets ||--o{ scraping_target_keywords : "relasi kata kunci"
taxonomy_keywords ||--o{ scraping_target_keywords : "diasosiasikan ke"
articles ||--o{ article_spoks : "menghasilkan fakta"
articles ||--o{ article_currations : "dikurasi pada"
articles ||--o{ validation_decisions : "divalidasi oleh"
fact_procurement ||--o{ fact_procurement_regions : "mencakup wilayah"
fact_procurement ||--|| fact_procurement_ai : "dianalisa oleh AI"
organization_nodes ||--o{ fact_procurement : "K/L/D pemilik paket"
social_trending_topics ||--o{ social_trending_snapshots : "riwayat 15 menit"
social_trending_topics ||--o{ postings : "dikaitkan ke tren"
post_author ||--o{ postings : "membuat konten"1. Modul Master Taksonomi & Entitas Wilayah
Modul ini adalah jangkar acuan nasional untuk standardisasi klasifikasi isu, organisasi negara, dan batas wilayah administratif Indonesia.
taxonomy_nodes (Pohon Taksonomi 5-Level)
Menyimpan struktur taksonomi pohon dengan kedalaman hingga 5 level yang mengorganisir puluhan ribu isu nasional ke dalam 5 pilar strategis:
- Ekonomi: Stabilitas harga pangan, inflasi, industri, ketenagakerjaan, investasi.
- Sosial: Kemiskinan, pendidikan, kesehatan, konflik sosial, bencana.
- Politik: Pilkada serentak, dinamika parlemen, kebijakan publik, pemilu.
- Budaya: Pariwisata, moderasi beragama, kearifan lokal, cagar budaya.
- Geo Politik: Hubungan diplomatik, pertahanan perbatasan, kedaulatan laut, siber internasional.
| Kolom | Tipe Data | Keterangan |
|---|---|---|
id | UUID (PK) | Identifikator unik simpul (defaultRandom). |
parent_id | UUID (FK) | Relasi rekursif ke simpul induk (bernilai NULL untuk simpul akar Pilar). |
label | TEXT | Nama label isu (misal: Keamanan Siber, Korupsi APBD, Ketahanan Pangan). |
pillar | TEXT | Pilar utama (EKONOMI, SOSIAL, POLITIK, BUDAYA, GEO_POLITIK). |
level | TEXT | Tingkat hierarki simpul (L1, L2, L3, L4, L5). |
color | TEXT | Kode warna HEX acuan untuk visualisasi grafik & peta taksonomi. |
description | TEXT | Definisi ruang lingkup isu yang digunakan sebagai acuan prompt LLM. |
sort_order | INTEGER | Urutan tampilan pada antarmuka admin/navigasi. |
created_at | TIMESTAMPTZ | Waktu simpul dibuat. |
updated_at | TIMESTAMPTZ | Waktu modifikasi terakhir. |
master_sectors (Klasifikasi 4 Peran Pengguna)
Mendukung kapabilitas antarmuka Role-based Decision Intelligence ("Lihat sebagai"):
id | sector_name | public_id | Deskripsi Peran Antarmuka |
|---|---|---|---|
1 | government | UUID | Pemerintahan: Pemangku kebijakan, K/L, TNI, POLRI, dan Pemda. |
2 | swasta | UUID | Pelaku Bisnis: Investor, korporasi swasta, BUMN, pasar modal. |
3 | lsm | UUID | LSM & Organisasi: Organisasi masyarakat, yayasan, advokasi sipil. |
4 | sosmed / personal | UUID | Personal: Analis independen, akademisi, dan publik luas. |
master_regions (Hierarki Wilayah 38 Provinsi)
- Menyimpan kodifikasi wilayah administratif resmi di seluruh Indonesia:
PROVINSI: 38 provinsi di Indonesia (termasuk Papua Barat Daya, Papua Tengah, Papua Pegunungan, Papua Selatan).KABUPATEN/KOTA: Seluruh 514 kabupaten dan kota nasional.KECAMATAN: Wilayah kecamatan untuk pemetaan geospasial mikro.
- Kolom:
id(INT PK),parent_id(INT FK rekursif),region_name(TEXT),region_level(TEXT),public_id(UUID UNIQUE).
organization_nodes (Direktori Instansi & Normalisasi Alias)
- Menyimpan pohon organisasi kepolisian (Mabes Polri, Polda, Polres, Polsek), kementerian, lembaga pemerintah non-kementerian (LPNK), dinas daerah, dan BUMN.
- Kolom penting:
aliases TEXT[]: Menyimpan ragam variasi penulisan nama instansi dalam bahasa berita (misal:['polda metro jaya', 'ditreskrimum polda metro', 'kepolisian daerah metro jaya']). Digunakan oleh worker saat ekstraksi entitas untuk pencocokan instan tanpa LLM.is_procurement_master BOOLEAN: Flag penanda apakah instansi ini berwenang menjadi pemilik paket lelang pengadaan (KLPD).sector_id®ion_id: Relasi langsung ke data induk sektor dan wilayah.
2. Modul Konfigurasi Ingestion & Target Scraper
Mengatur armada perayap (crawler) berita dan pemantau sumber data siber.
| Nama Tabel | Peran & Kolom Utama | Fungsionalitas Operasional |
|---|---|---|
sources | id, name, type, mode, adapter, base_url, template JSONB, cron, rate_limit_per_min, status_scrappe, success_rate_7d, active | Master portal penerbit berita online (Detik, Kompas, Antara, dll.), konfigurasi adaptor DOM scraper, jadwal perayapan otomatis, dan metrik kesehatan crawler 7 hari. |
scraping_targets | id, organization_node_id, domain_name, base_url, scraping_config JSONB, is_active | Menghubungkan portal web resmi instansi dengan simpul organization_nodes untuk pemantauan rilis pers pemerintah daerah dan instansi penegak hukum. |
taxonomy_keywords | id, taxonomy_node_id, keyword_phrase, is_active | Frasa kata kunci spesifik untuk menyaring artikel berita ke node taksonomi tertentu saat tahap preprocessing crawler. |
scraping_target_keywords | scraping_target_id, taxonomy_keyword_id (PK Komposit) | Tabel relasi many-to-many untuk mengikat target scraping instansi dengan daftar kata kunci fokus investigasi. |
social_keywords | id, keyword, article_id, taxonomy, level, taxonomy_node_id, is_active | Daftar kata kunci pantauan media sosial (X/Twitter, TikTok) yang terikat pada hierarki taksonomi nasional. |
3. Modul Artikel Berita, Ekstraksi AI, & Kurasi Manusia
articles (Master Metadata Artikel)
Tabel pusat penampung artikel berita yang telah dibersihkan oleh worker D1 dan diperkaya dengan metadata inferensi AI:
| Kolom | Tipe Data | Keterangan & Karakteristik |
|---|---|---|
id | UUID (PK) | ID artikel unik. |
code | TEXT (Unique) | Kode hash dokumen (SHA-256 dari URL/konten) untuk mencegah duplikasi ingest (deduplication). |
title | TEXT | Judul artikel berita yang telah dinormalisasi. |
url | TEXT | Tautan absolut artikel berita asli. |
data_type | TEXT | Tipe media (news_article, press_release, dll.). |
channel | TEXT | Kanal pemberitaan (Nasional, Hukum, Bisnis, Metro). |
source_name | TEXT | Nama portal penerbit berita (misal: Kompas.com, DetikNews). |
summary | TEXT | Ringkasan eksekutif 2–3 kalimat hasil ekstraksi AI. |
pillar | TEXT | Pilar strategis utama hasil klasifikasi tertinggi (EKONOMI, POLITIK, dll.). |
primary_label | JSONB | Simpul taksonomi primer: {"id": "...", "label": "Inflasi Pangan", "confidence": 0.94}. |
labels | JSONB | Array seluruh label taksonomi pendukung beserta skor probabilitas relevansi. |
sentiment | TEXT | Valensi sentimen pemberitaan (positive, neutral, negative). |
confidence | REAL | Skor kepastian model inferensi AI (skala 0.00 – 1.00). |
severity | INTEGER | Derajat keparahan dampak isu (skala 1 = Rendah s.d. 5 = Kritis/Darurat). |
flagged | BOOLEAN | Penanda khusus jika artikel mengandung anomali atau ancaman keamanan mendesak. |
entities | JSONB | Daftar entitas named-entity recognition: Tokoh, Organisasi, Lokasi, Objek Vital. |
location_province | TEXT | Nama provinsi hasil resolusi geospasial teks berita. |
location_city | TEXT | Nama kabupaten/kota hasil resolusi entitas lokasi. |
location_lat / lng | DOUBLE PRECISION | Koordinat titik lintang dan bujur lokasi peristiwa berita. |
human_validation_status | ENUM | Status validasi kurasi manusia: 'pending', 'approved', 'rejected'. |
published_at | TIMESTAMPTZ | Waktu artikel diterbitkan oleh portal sumber asli. |
scraped_at | TIMESTAMPTZ | Waktu crawler memanen artikel mentah. |
processed_at | TIMESTAMPTZ | Waktu artikel selesai diproses AI dan diindeks ke sistem. |
article_spoks (Fakta Terstruktur Subjek-Predikat-Objek-Keterangan)
Disimpan untuk memungkinkan analisis jaringan peristiwa (Event Knowledge Graph) dan dihitung oleh nexa-aggregation untuk metrik structured_facts:
CREATE TABLE article_spoks (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
article_id TEXT NOT NULL REFERENCES articles(id::text) ON DELETE CASCADE,
subjek JSONB NOT NULL DEFAULT '[]', -- Contoh: ["KPK", "Penyidik"]
predikat JSONB NOT NULL DEFAULT '[]', -- Contoh: ["Menyita", "Menggeledah"]
objek JSONB NOT NULL DEFAULT '[]', -- Contoh: ["Aset Rumah Mewah", "Uang Tunai"]
keterangan TEXT, -- Contoh: "di kawasan Menteng, Jakarta Pusat"
confidence REAL DEFAULT 0.85,
extracted_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_article_spoks_article ON article_spoks (article_id);article_currations & validation_decisions (Human-in-the-Loop)
article_currations: Mencatat aksi persetujuan (approved) atau penolakan (rejected) artikel oleh kurator beserta catatan koreksi editorial (validation_note).validation_decisions: Menyimpan keputusan audit mendalam jika kurator mengubah klasifikasi AI (misal membetulkancorrected_labeldari kategori Politik ke Ekonomi).gold_dataset_state: Melacak jumlah korpus artikel terverifikasi manusia yang siap dialokasikan untuk siklus fine-tuning model AI selanjutnya.
4. Modul Media Sosial & Phone Farm (Pipeline B3)
Pipeline B3 Phone Farm memanen tren dan postingan sosial media secara kontinu menggunakan armada ponsel fisik Android, mengontrol scraping 4 platform (X, Facebook, Instagram, TikTok).
-- Master topik tren percakapan X/Twitter yang dinormalisasi setiap 15 menit
CREATE TABLE social_trending_topics (
id SERIAL PRIMARY KEY,
topic_name VARCHAR(255) NOT NULL UNIQUE,
normalized_name VARCHAR(255) NOT NULL,
first_detected_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
last_detected_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
peak_rank INTEGER DEFAULT 1,
total_snapshots INTEGER DEFAULT 1,
primary_pillar VARCHAR(50), -- Dipetakan ke 5 Pilar Taksonomi
taxonomy_node_id UUID REFERENCES taxonomy_nodes(id),
status VARCHAR(20) DEFAULT 'ACTIVE' -- ACTIVE | ARCHIVED
);
CREATE INDEX idx_social_topics_norm ON social_trending_topics (normalized_name);
CREATE INDEX idx_social_topics_pillar ON social_trending_topics (primary_pillar);5. Modul Pengadaan Barang & Jasa Pemerintah (LPSE / SIRUP)
Mendokumentasikan seluruh rencana dan realisasi pengadaan negara (Inaproc / LKPP) serta mendeteksi indikasi kecurangan lelang atau inefisiensi anggaran.
-- 1. Master Paket Pengadaan Nasional (SIRUP & Tender Inaproc)
CREATE TABLE fact_procurement (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
rup_id TEXT NOT NULL UNIQUE, -- Kode RUP dari portal LKPP
package_name TEXT NOT NULL, -- Nama paket kegiatan pengadaan
package_url TEXT,
pagu NUMERIC(20, 2), -- Nilai pagu anggaran (Rupiah)
procurement_type TEXT, -- Barang, Pekerjaan Konstruksi, Jasa Konsultansi
procurement_scheme TEXT, -- Penyedia vs Swakelola
method TEXT, -- Tender, Pengadaan Langsung, E-Purchasing
selection_period TEXT,
domesticProduct BOOLEAN, -- Produk Dalam Negeri (PDN)
small_business BOOLEAN, -- Alokasi UMKM/Koperasi
klpd TEXT, -- Nama Kementerian / Lembaga / Pemda
work_unit TEXT, -- Satuan Kerja (Satker) pelaksana
location TEXT,
fiscal_year INTEGER, -- Tahun Anggaran (misal: 2026)
source_org_node_id INTEGER REFERENCES organization_nodes(id),
sector_id INTEGER REFERENCES master_sectors(id),
region_id INTEGER REFERENCES master_regions(id),
payload JSONB NOT NULL DEFAULT '{}', -- Rincian spesifikasi lelang lengkap
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 2. Wilayah Jangkauan Paket Multi-Kabupaten
CREATE TABLE fact_procurement_regions (
procurement_id BIGINT NOT NULL REFERENCES fact_procurement(id) ON DELETE CASCADE,
region_id INTEGER NOT NULL REFERENCES master_regions(id),
source TEXT NOT NULL, -- manual | parsed_text
created_at TIMESTAMPTZ DEFAULT NOW(),
PRIMARY KEY (procurement_id, region_id)
);
-- 3. Evaluasi Anomali & Rekomendasi AI per Paket
CREATE TABLE fact_procurement_ai (
procurement_id BIGINT PRIMARY KEY REFERENCES fact_procurement(id) ON DELETE CASCADE,
classification TEXT NOT NULL, -- WAJAR | ANOMALI_TENDER | POTENSI_PEMBOROSAN
reason TEXT, -- Argumen penalaran logis dari model AI
confidence NUMERIC(5, 4), -- Skor probabilitas (0.0000 s/d 1.0000)
waste_amount NUMERIC(20, 2), -- Estimasi nilai pemborosan anggaran (Rp)
model TEXT, -- Nama model (misal: gpt-4o / claude-3-5-sonnet)
prompt_version TEXT,
evaluated_at TIMESTAMPTZ DEFAULT NOW(),
payload JSONB NOT NULL DEFAULT '{}'
);6. Modul Data Sektoral Pangan, Pendidikan, & Static Datasets
Menyimpan data statistik sektoral riil yang diunggah secara batch (oleh worker B2) sebagai kalibrasi silang terhadap isu pemberitaan.
| Nama Tabel | Struktur Kunci | Fungsi & Pola Akses |
|---|---|---|
master_commodities | id, commodity_name (UNIQUE), category, unit, aliases TEXT[] | Katalog komoditas pangan nasional (Beras Medium, Cabai Rawit Merah, Minyak Goreng, Daging Sapi). Kolom aliases digunakan untuk resolusi teks saat artikel membahas pangan. |
fact_indicator | id, indicator_type, region_id, product_id, period_date, value NUMERIC(18,4), unit | Deret waktu numerik harga pangan harian/mingguan dari Badan Pangan Nasional/Kemendag. Memiliki indeks unik gabungan (grain index) untuk idempotensi UPSERT mingguan. |
master_schools | id, npsn (UNIQUE), school_name, school_level, accreditation, latitude, longitude, region_id | Registri sekolah Dapodik se-Indonesia lengkap dengan koordinat geospasial untuk deteksi insiden keamanan di sekitar fasilitas pendidikan. |
static_datasets | id (UUID), file_sha256, file_path_minio, dataset_kind, status, rows_loaded | Registri berkas tabular besar yang diunggah ke Object Storage (MinIO) sebelum diekstraksi ke PostgreSQL via PostgreSQL COPY. |
static_dataset_records | id, dataset_id, row_hash, raw_payload JSONB, business_key | Penyimpanan baris data mentah dari file tabular yang diunggah untuk audit kelengkapan data. |
7. Modul Keamanan, Observabilitas, & Registry
users & audit_log
users: Mengelola akun pengguna platform dengan kolomid (UUID),name,email(UNIQUE),password(Argon2/Bcrypt hash),role(admin,intel_analyst,executive_viewer),status(active,suspended), danlast_login_at.audit_log: Mencatat setiap aktivitas manipulasi data oleh pengguna:actor_name,action(EXPORT_REPORT,UPDATE_TAXONOMY,VALIDATE_ARTICLE),target, dancreated_at.
module_registry (Konfigurasi Dinamis Sidebar Dashboard)
Menyimpan konfigurasi modul frontend tanpa perlu deploy ulang kode aplikasi:
key (PK): ID rute modul (misal:national-overview,provinces,procurement).name: Label menu antarmuka.group_key: Kelompok navigasi (strategic,tactical,operational).state: Status tayang (active,beta,pending).tier: Hak akses level pengguna.
kafka_topic_offset_samples (Monitoring Throughput Antrean)
Mencatat posisi End Offset setiap topik Kafka setiap menit dengan primary key komposit (topic, bucket_start):
- Menghitung Throughput (pesan/detik) secara presisi:
-- Komputasi Throughput Antrean Kafka per Menit SELECT t2.topic, t2.bucket_start, (t2.end_offset - t1.end_offset) / 60.0 AS throughput_msg_per_sec FROM kafka_topic_offset_samples t2 JOIN kafka_topic_offset_samples t1 ON t2.topic = t1.topic AND t1.bucket_start = t2.bucket_start - INTERVAL '1 minute' ORDER BY t2.bucket_start DESC;
Definisi Schema Drizzle ORM (TypeScript)
Berikut adalah cuplikan kode implementasi Drizzle ORM pada src/db/schema.ts di backend:
import {
pgTable, uuid, text, integer, boolean, real,
numeric, jsonb, timestamp, doublePrecision, pgEnum, primaryKey
} from "drizzle-orm/pg-core";
export const humanValidationStatusEnum = pgEnum("human_validation_status", [
"pending", "approved", "rejected"
]);
export const articles = pgTable("articles", {
id: uuid("id").primaryKey(),
code: text("code").notNull().unique(),
title: text("title").notNull(),
dataType: text("data_type").notNull(),
channel: text("channel"),
sourceName: text("source_name"),
url: text("url"),
summary: text("summary"),
pillar: text("pillar").notNull(),
primaryLabel: jsonb("primary_label").notNull(),
labels: jsonb("labels").notNull(),
sentiment: text("sentiment"),
confidence: real("confidence"),
severity: integer("severity"),
flagged: boolean("flagged").notNull().default(false),
entities: jsonb("entities"),
locationProvince: text("location_province"),
locationCity: text("location_city"),
locationLat: doublePrecision("location_lat"),
locationLng: doublePrecision("location_lng"),
humanValidationStatus: humanValidationStatusEnum("human_validation_status")
.notNull()
.default("pending"),
publishedAt: timestamp("published_at", { withTimezone: true }),
processedAt: timestamp("processed_at", { withTimezone: true }),
});Strategi Pengindeksan & Optimasi Performa
Untuk menjamin waktu respons query OLTP tetap di bawah 50 milidetik pada volume jutaan transaksi, PostgreSQL menerapkan strategi indeks khusus:
-
B-Tree Composite Indexes:
CREATE INDEX idx_articles_pub_prov ON articles (published_at DESC, location_province);
Mempercepat pemfilteran linimasa berita terkini per provinsi.CREATE INDEX idx_procurement_rup ON fact_procurement (rup_id);
Menjamin pencarian instan paket LPSE saat sinkronisasi ulang.CREATE INDEX idx_snapshots_topic_time ON social_trending_snapshots (topic_id, snapshot_at DESC);
Optimasi pembacaan kurva pergerakan ranking tren 15 menit.
-
GIN (Generalized Inverted Index) pada Kolom JSONB:
CREATE INDEX idx_articles_primary_label ON articles USING GIN (primary_label);CREATE INDEX idx_articles_labels ON articles USING GIN (labels);CREATE INDEX idx_articles_entities ON articles USING GIN (entities);
Memungkinkan pencarian operator JSON path (@>,?,?|) secara efisien tanpa full-table scan.
-
GIN Index pada Array Native (
TEXT[]):CREATE INDEX idx_org_aliases ON organization_nodes USING GIN (aliases);CREATE INDEX idx_commodity_aliases ON master_commodities USING GIN (aliases);
Mendukung query pencocokan nama variasi (aliases && ARRAY['alias_dicari']) dalam mikrodetik.
-
Idempotensi Operasi Tulis (UPSERT Pattern):
- Seluruh worker ingestion menggunakan klausa
ON CONFLICT (code) DO UPDATE ...atauON CONFLICT (rup_id) DO UPDATE ...untuk mencegah kegagalan pipeline saat memproses ulang pesan yang sama dari antrean Kafka.
- Seluruh worker ingestion menggunakan klausa
Kafka
Panduan komprehensif seluruh topik Apache Kafka, wire contract, skema JSON, consumer groups, mekanisme DLQ, dan monitoring lag pada platform Nexa Intelligence.
Elasticsearch
Spesifikasi teknis cluster Elasticsearch di Nexa, katalog lengkap 13 indeks data master & analitik, struktur mapping dokumen, serta pola query pencarian real-time.