- PHP 93.9%
- CSS 3.4%
- PLpgSQL 1.9%
- JavaScript 0.6%
- HTML 0.2%
| app | ||
| db | ||
| doc | ||
| public | ||
| resources/css | ||
| tests | ||
| writable | ||
| .env.example | ||
| .gitignore | ||
| builds | ||
| composer.json | ||
| composer.lock | ||
| env | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| phpunit.dist.xml | ||
| preload.php | ||
| README.md | ||
| spark | ||
RISALAH — Portal Media Digital
"Setiap kisah adalah risalah zaman."
Portal media digital berbasis Batam & Kepulauan Riau — NEWS × STORY × PERSPECTIVE dengan CMS redaksi alur draft → review → publish. Lihat doc/PRD.md untuk dokumen produk lengkap, doc/DESIGN.md untuk design system, dan doc/TECH-STACK.md untuk pemilihan teknologi.
Tech Stack
| Layer | Teknologi |
|---|---|
| Framework | CodeIgniter 4 (PHP 8.2+) |
| Database | PostgreSQL 16+ (FTS native, JSONB) |
| CSS | Tailwind CSS (design token "Kumparan Editorial") |
| Icons | Material Design Icons (self-hosted) |
| Editor | TinyMCE (panel) + sanitasi HTML server-side |
| Cache | File (MVP) — siap tukar Redis |
| Fonts | Lora (serif judul) · Heebo (isi) |
Fitur (Status MVP)
Portal Publik
- Beranda editorial: headline, breaking, berita terkini, sorotan minggu ini, editorial pilihan
- Kanal/kategori (2 level), halaman detail artikel (cover, tag, share, bacaan terkait, catatan redaksi), halaman penulis
- Pencarian full-text (PostgreSQL FTS) + filter kategori/tanggal + highlight
- Arsip bulanan, RSS, sitemap.xml, robots.txt, JSON-LD NewsArticle + OG/Twitter
- 404 & 500 editoria; halaman statis (Tentang Kami, Struktur Redaksi, Pedoman Media Siber, Kontak)
CMS Redaksi (/panel)
- Autentikasi email+kata sandi (bcrypt), rate-limit 5×/15 menit, sesi 8 jam
- RBAC 5 role: Admin, Pemred, Editor, Reporter, Kontributor
- Artikel CRUD: slug unik, estimasi waktu baca, meta SEO, cover image, TinyMCE
- Workflow: draft → in_review → published/scheduled → archived, reject ber-catatan, snapshot revisi
- Media library: upload JPG/PNG/WebP ≤5 MB, varian WebP otomatis (400/800/1600), alt text wajib
- Kurasi beranda (headline/sorotan/editorial) dengan fallback otomatis
- Modul video Navigasi (embed YouTube dengan facade thumbnail)
- Manajemen pengguna, kategori, tag
- Audit log, pageview internal + terpopuler
- Header keamanan, CSRF, sanitasi input
Persyaratan
- PHP 8.2+ (ekstensi:
pgsql,gd,dom,json,mbstring) - PostgreSQL 16+
- Composer, Node.js (untuk build CSS)
- Nginx/Apache ataupun
php spark serve(dev) - URL aplikasi ✳ Public root = folder
public/dan wajib menunjuk kesana (bukan root proyek). Contoh nginx:
root /var/www/risalah/public;
try_files $uri $uri/ /index.php?$query_string;
Reverse Proxy (domain/IP apa saja)
Aplikasi siap dibalik proxy mana pun — baseURL dihitung otomatis dari host request dan skema X-Forwarded-Proto (app/Config/App.php). Nginx contoh:
server {
listen 80;
server_name risalah.news *.risalah.news; # domain apa pun boleh
location / {
proxy_pass http://127.0.0.1:8080; # php spark serve / upstream
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}
}
Keamanan: hanya jalankan di belakang proxy tepercaya. Jangan meneruskan header
X-Forwarded-Host/Protodari klien tak dikenal langsung ke aplikasi.
Instalasi
# 1. Dependensi PHP
composer install
# 2. Build CSS (Tailwind) + aset MDI
npm install
npm run build:css
cp -r node_modules/@mdi/font/css node_modules/@mdi/font/fonts public/assets/vendor/mdi/
# 3. Konfigurasi
cp .env.example .env # lalu isi baseURL & kredensial database
php spark key:generate
# 4. Skema & seed database (PostgreSQL)
PGPASSWORD=... psql -h 127.0.0.1 -U ... -d risalah -f db/schema.sql
PGPASSWORD=... psql -h 127.0.0.1 -U ... -d risalah -f db/seed.sql # role, kategori, video program, admin
# opsional: db/seed-content.sql (artikel contoh)
# 5. Jalankan (dev)
php spark serve --host 127.0.0.1 --port 8080
Akun Awal (dari seed)
| Role | Username | Password |
|---|---|---|
| Admin | admin |
admin123 ⚠️ ganti sebelum go-live |
Cron (produksi)
Terbitkan artikel terjadwal setiap ≤5 menit:
* * * * * cd /var/www/risalah && php spark risalah:publish-scheduled >/dev/null 2>&1
Backup
# Harian basis data, simpan 14 hari (PRD US-6.3)
pg_dump -h 127.0.0.1 -U root risalah | gzip > /backup/risalah-$(date +%F).sql.gz
Struktur Aplikasi
app/
├── Config/ Routes, Filters (auth/CSRF/cache/secure), Session
├── Controllers/ Publik: Home, Frontend, Arsip, Search, Seo, Navigasi, Pages
│ └── Panel/ CMS: Artikel, Media, Videos, Kurasi, Users, Kategori, Tags, Audit
├── Filters/ AuthFilter, PageCache, SecureHeaders
├── Libraries/ Workflow (state machine)
├── Helpers/ Authz (RBAC), EditorialHelper (slug), Sanitize
├── Models/ ArticleModel, CategoryModel, MediaModel, UserModel, dll.
└── Views/ layouts, home, frontend, panel, errors
db/ schema.sql + seed.sql (PostgreSQL)
doc/ PRD, DESIGN, TECH-STACK
public/assets/css tailwind build output
public/uploads/{YYYY}/{mm} media (git-ignored)
Perintah Berguna
| Perintah | Fungsi |
|---|---|
npm run build:css |
Build Tailwind → public/assets/css/app.css |
php spark risalah:publish-scheduled |
Eksekusi artikel terjadwal |
php spark db:table |
Cek struktur DB dari CI4 |
php spark key:generate |
Generate kunci encryption |
Dihapus dari Version Control
.env, node_modules/, public/uploads/, writable/cache|logs|session — lihat .gitignore.
Kepatuhan
Mengikuti Pedoman Media Siber (Dewan Pers): hak jawab, mekanisme ralat & catatan redaksi, struktur redaksi publik, jejak revisi, dan pemisahan fakta/opini.
Dokumentasi mengacu pada
doc/PRD.mdv1.0 (MVP Editorial Core).