diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..f469319 --- /dev/null +++ b/.env.production.example @@ -0,0 +1,14 @@ +# PRODUCTION ENVIRONMENT VARIABLES +# Copy this file to Cloudflare Pages / Vercel Environment Variables section for the Production branch (main). + +NEXT_PUBLIC_APP_URL="https://prisma-rt04.pages.dev" +NEXT_PUBLIC_ENVIRONMENT="production" + +# Database Configuration (Production SQLite / Supabase) +DATABASE_URL="file:./prisma_prod.db" + +# API Keys & Secrets +# TELEGRAM_BOT_TOKEN="your_prod_telegram_bot_token" +# ADMIN_CHAT_ID="your_prod_admin_chat_id" +# NEXT_PUBLIC_SUPABASE_URL="your_prod_supabase_url" +# NEXT_PUBLIC_SUPABASE_ANON_KEY="your_prod_supabase_anon_key" diff --git a/.env.staging.example b/.env.staging.example new file mode 100644 index 0000000..b96406d --- /dev/null +++ b/.env.staging.example @@ -0,0 +1,14 @@ +# STAGING ENVIRONMENT VARIABLES +# Copy this file to Cloudflare Pages / Vercel Environment Variables section for the Preview branch (staging). + +NEXT_PUBLIC_APP_URL="https://staging.prisma-rt04.pages.dev" +NEXT_PUBLIC_ENVIRONMENT="staging" + +# Database Configuration (Staging SQLite / Supabase) +DATABASE_URL="file:./prisma_staging.db" + +# API Keys & Secrets +# TELEGRAM_BOT_TOKEN="your_staging_telegram_bot_token" +# ADMIN_CHAT_ID="your_staging_admin_chat_id" +# NEXT_PUBLIC_SUPABASE_URL="your_staging_supabase_url" +# NEXT_PUBLIC_SUPABASE_ANON_KEY="your_staging_supabase_anon_key" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 962dab6..5e31b8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI/CD Pipeline - Build, Test, Security & Deploy on: push: - branches: [ main ] + branches: [ main, staging, stagging ] pull_request: - branches: [ main ] + branches: [ main, staging, stagging ] # Cancel in-progress runs for the same PR/branch concurrency: @@ -156,10 +156,10 @@ jobs: grep -l "CSRFToken\|csrf" src/lib/security*.ts && echo "✅ CSRF tokens present" || echo "❌ Missing CSRF protection" echo "--- Rate Limiting ---" - grep -l "rateLimit\|checkRateLimit" src/lib/security*.ts src/app/api/middleware.ts && echo "✅ Rate limiting present" || echo "❌ Missing rate limiting" + grep -l "rateLimit\|checkRateLimit" src/lib/security*.ts && echo "✅ Rate limiting present" || echo "❌ Missing rate limiting" echo "--- Input Sanitization ---" - grep -l "sanitizeInput\|sanitizeServerInput" src/lib/security*.ts src/app/api/middleware.ts && echo "✅ Input sanitization present" || echo "❌ Missing input sanitization" + grep -l "sanitizeInput\|sanitizeServerInput" src/lib/security*.ts && echo "✅ Input sanitization present" || echo "❌ Missing input sanitization" # ============================================ # JOB 3: Deploy to Cloudflare Pages @@ -168,7 +168,7 @@ jobs: runs-on: ubuntu-latest name: 🚀 Deploy to Cloudflare Pages needs: [build-and-test, security-audit] - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/stagging') permissions: contents: read @@ -189,7 +189,7 @@ jobs: with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy out/ --project-name=prisma-rt04 + command: pages deploy out/ --project-name=prisma-rt04 --branch=${{ github.ref_name }} - name: ✅ Deployment Summary run: | diff --git a/.gitignore b/.gitignore index ec9a7f0..d650309 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,17 @@ public/lighthouse-*.json # Bot temp files bot-temp/ + +# Secure files +prompt/ +docs/ +keys/ + +# Internal prompt/documentation files (not for GitHub) +PRISMA_PROJECT_PROMPT.md +DEPLOY_CLOUDFLARE.md +TESTING_REPORT.md +CREDENTIALS.md +datasccience prisma.txt +*.txt +!public/**/*.txt diff --git a/DEPLOY_CLOUDFLARE.md b/DEPLOY_CLOUDFLARE.md deleted file mode 100644 index 20dcec3..0000000 --- a/DEPLOY_CLOUDFLARE.md +++ /dev/null @@ -1,116 +0,0 @@ -# Panduan Deploy ke Cloudflare Pages - -## Persiapan - -### 1. Buat Akun Cloudflare (Jika Belum Punya) -- Kunjungi https://dash.cloudflare.com/sign-up -- Daftar dengan email - -### 2. Build Project Lokal -```bash -npm run build -``` -Hasil build akan ada di folder `out/` - ---- - -## Opsi A: Deploy via Git (Rekomendasi) - -### Langkah 1: Push ke GitHub/GitLab -```bash -git add . -git commit -m "Ready for Cloudflare Pages deployment" -git push origin main -``` - -### Langkah 2: Connect di Cloudflare -1. Buka https://dash.cloudflare.com -2. Pilih **Workers & Pages** di sidebar -3. Klik **Create application** → **Pages** -4. Pilih **Connect to Git** -5. Authorize dan pilih repository Anda - -### Langkah 3: Konfigurasi Build -- **Framework preset**: Next.js (Static HTML Export) -- **Build command**: `npm run build` -- **Build output directory**: `out` -- **Root directory**: `/` (kosongkan) - -### Langkah 4: Deploy -- Klik **Save and Deploy** -- Tunggu build selesai (~2-3 menit) -- Akses site di: `https://[project-name].pages.dev` - ---- - -## Opsi B: Deploy Manual (Drag & Drop) - -### Langkah 1: Build -```bash -npm run build -``` - -### Langkah 2: Upload -1. Buka https://dash.cloudflare.com -2. Pilih **Workers & Pages** → **Create application** → **Pages** -3. Pilih **Upload assets** -4. Drag & drop folder `out/` ke area upload -5. Klik **Deploy site** - ---- - -## Opsi C: Deploy via Wrangler CLI - -### Langkah 1: Install Wrangler -```bash -npm install -g wrangler -``` - -### Langkah 2: Login -```bash -wrangler login -``` - -### Langkah 3: Deploy -```bash -npm run build -npx wrangler pages deploy out --project-name=prisma-rt04 -``` - ---- - -## Custom Domain (Opsional) - -1. Di dashboard Cloudflare Pages, pilih project Anda -2. Klik tab **Custom domains** -3. Klik **Set up a custom domain** -4. Masukkan domain Anda (misal: `prisma-rt04.com`) -5. Ikuti instruksi DNS - ---- - -## Environment Variables (Jika Diperlukan) - -1. Di dashboard, pilih project → **Settings** → **Environment variables** -2. Tambahkan variabel yang diperlukan (jika ada) - ---- - -## Troubleshooting - -### Error: 404 pada halaman selain homepage -- Pastikan `trailingSlash: true` di `next.config.ts` ✅ (sudah dikonfigurasi) - -### Error: Asset tidak ditemukan -- Pastikan folder `public/` ter-include dalam build - -### Build gagal -- Cek log build di dashboard Cloudflare -- Pastikan Node.js version compatible (gunakan v18+) - ---- - -## Tips -- Setiap push ke branch `main` akan auto-deploy -- Preview deployment tersedia untuk pull request -- Analytics gratis tersedia di dashboard diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 0000000..85685c5 --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,105 @@ +# Panduan Migrasi ke Arsitektur Multi-Tenant PRISMA Kemayoran + +Dokumen ini berisi panduan lengkap untuk melakukan migrasi dari aplikasi PRISMA RT04 (Single-Tenant) ke PRISMA Kemayoran (Multi-Tenant). + +--- + +## 1. Pre-Migration Checklist + +Sebelum melakukan migrasi di environment production, pastikan Anda telah menyelesaikan hal-hal berikut: + +- [ ] **Backup Database**: Lakukan full backup database Supabase Anda saat ini melalui dashboard Supabase (Database -> Backups). +- [ ] **Staging Environment**: Sangat disarankan untuk menguji proses ini di project Supabase dan Vercel khusus staging terlebih dahulu. +- [ ] **Domain & DNS**: Pastikan domain utama (`prisma-kemayoran.id`) telah terhubung dengan Vercel/Cloudflare dan Anda bisa mengatur *wildcard DNS* (`*.prisma-kemayoran.id`) mengarah ke server Vercel. +- [ ] **Informasikan Warga**: Berikan pengumuman bahwa aplikasi akan mengalami *downtime* atau pemeliharaan singkat selama proses migrasi. + +--- + +## 2. Step-by-step Migration + +Ikuti langkah-langkah berikut secara berurutan: + +### Step 1: Jalankan SQL Migration +1. Buka Supabase Dashboard > SQL Editor. +2. Salin isi file `supabase/migrations/20260528000002_multitenant.sql`. +3. Jalankan *query* tersebut. Script ini akan: + - Membuat tabel `rt_units` dan `rw_admins`. + - Mengisi data awal untuk RT 04 (agar data yang sudah ada tidak hilang). + - Menambahkan kolom `rt_id` pada semua tabel jika belum ada, dan menghubungkannya dengan ID RT04. + - Mengganti seluruh *Row Level Security* (RLS) agar berbasis RT. + +### Step 2: Update Environment Variables +1. Perbarui environment variables di Vercel atau `.env.local` lokal Anda. +2. Pastikan variabel berikut tersedia: + ```env + NEXT_PUBLIC_DEFAULT_RT_ID="" + NEXT_PUBLIC_SITE_URL="https://prisma-kemayoran.id" + ``` + *(Opsional jika menggunakan setup lokal, ganti `NEXT_PUBLIC_SITE_URL` dengan `http://localhost:3000`)* + +### Step 3: Deploy Kode Terbaru (Middleware) +1. Lakukan push/deploy kode terbaru yang berisi pembaruan `src/middleware.ts` ke Vercel. +2. Middleware ini bertugas mencegat (*intercept*) subdomain dan mengatur *header* tenant. + +### Step 4: Setup Domain Wildcard di Vercel +1. Masuk ke dashboard proyek di Vercel > Settings > Domains. +2. Tambahkan domain: `*.prisma-kemayoran.id`. +3. Pastikan `vercel.json` dengan konfigurasi *rewrites* sudah ter-deploy. + +### Step 5: Test Subdomain RT04 +1. Buka `https://rt04.prisma-kemayoran.id` di browser. +2. Pastikan halaman termuat dengan benar. +3. Login sebagai pengurus dan warga RT 04. + +### Step 6: Verifikasi Data Aksesibilitas +1. Periksa apakah data pengumuman, keuangan, dan surat pengajuan RT04 lama masih muncul. +2. Cobalah buat surat pengajuan baru, pastikan berhasil masuk. + +### Step 7: Jalankan Isolation Test +Jika Anda memiliki akses terminal ke CI/CD atau lokal: +```bash +npm run test tests/isolation.test.ts +``` +Pastikan seluruh tes untuk *Data Isolation* berwarna hijau (Lulus). + +### Step 8: Pengumuman Berhasil +Beri tahu warga RT04 bahwa URL aplikasi sekarang telah berubah menjadi `rt04.prisma-kemayoran.id`. + +--- + +## 3. Rollback Plan + +Jika terjadi *critical failure* (misalnya: tidak ada user yang bisa login, data hilang dari dashboard) dalam waktu 24 jam setelah migrasi, ikuti prosedur berikut: + +1. **Revert Routing Vercel**: + - Hapus aturan domain wildcard `*.prisma-kemayoran.id` dari Vercel. + - Rollback *deployment* Vercel ke versi sebelum middleware baru di-deploy (menggunakan fitur *Instant Rollback* Vercel). + +2. **Revert Database RLS**: + - Buka SQL Editor di Supabase. + - Hapus policy multi-tenant dan kembalikan ke policy sederhana tanpa cek `rt_id`: + ```sql + -- Contoh untuk tabel pengumuman + DROP POLICY IF EXISTS "Warga Read pengumuman" ON public.pengumuman; + CREATE POLICY "Enable read access for all users" ON public.pengumuman FOR SELECT USING (true); + -- Lakukan hal serupa untuk policy lain jika diperlukan secara darurat. + ``` + - (Alternatif) Cukup matikan RLS sementara untuk *recovery* darurat (SANGAT TIDAK DISARANKAN KECUALI DARURAT): + ```sql + ALTER TABLE public.pengumuman DISABLE ROW LEVEL SECURITY; + ``` + +3. **Restore Backup**: + Jika skema terlanjur rusak parah, *restore* database Supabase dari *Point in Time Recovery* (PITR) ke 1 jam sebelum proses migrasi. + +--- + +## 4. Post-Migration Checklist + +Setelah migrasi selesai dan dinilai stabil: + +- [ ] Seluruh RLS policy berbasis `get_user_rt_id()` telah aktif di semua tabel. +- [ ] Isolation test passed tanpa *error*. +- [ ] Data historical RT04 dapat diakses 100%. +- [ ] Integrasi webhook Telegram bot masih merespons `chat_id` yang benar. +- [ ] PWA `manifest.json` tetap bekerja pada *start_url* subdomain. diff --git a/PRISMA_PROJECT_PROMPT.md b/PRISMA_PROJECT_PROMPT.md deleted file mode 100644 index 5267d45..0000000 --- a/PRISMA_PROJECT_PROMPT.md +++ /dev/null @@ -1,1023 +0,0 @@ -# 🏛️ PRISMA — Platform Informasi & Sistem Manajemen RT 04 -## Structured Project Prompt — Full Lifecycle Documentation - -> **Dokumen ini adalah prompt terstruktur, detail, dan spesifik** yang mencakup seluruh siklus hidup proyek PRISMA: -> Kerangka → Desain → Build → Develop → Maintain → Security → Database Schema - ---- - -## 📋 Daftar Isi - -1. [Gambaran Umum Proyek](#1-gambaran-umum-proyek) -2. [Arsitektur & Kerangka Sistem](#2-arsitektur--kerangka-sistem) -3. [Desain UI/UX Web](#3-desain-uiux-web) -4. [Build & Konfigurasi](#4-build--konfigurasi) -5. [Development Guidelines](#5-development-guidelines) -6. [Maintenance & Operasional](#6-maintenance--operasional) -7. [Security Framework](#7-security-framework) -8. [Database Schema Design](#8-database-schema-design) -9. [API & Service Layer](#9-api--service-layer) -10. [AI & Bot Integration](#10-ai--bot-integration) -11. [Testing Strategy](#11-testing-strategy) -12. [Deployment Pipeline](#12-deployment-pipeline) - ---- - -## 1. Gambaran Umum Proyek - -### 1.1 Identitas Proyek - -| Atribut | Detail | -|---|---| -| **Nama Proyek** | PRISMA (Platform Informasi & Sistem Manajemen RT 04) | -| **Versi** | 0.1.0 | -| **Repositori** | `github.com/ProgrammingDevelopment/PRISMA` | -| **Domain** | Tata kelola RT/RW digital berbasis AI | -| **Target User** | Warga RT 04/RW 09, Pengurus RT, Staff Administrasi | -| **Lokasi** | Kelurahan Kemayoran, Jakarta Pusat | - -### 1.2 Tujuan Proyek - -1. **Digitalisasi Administrasi** — Menggantikan proses manual pencatatan warga, surat-menyurat, dan kas RT menjadi digital. -2. **Transparansi Keuangan** — Membuka akses real-time data keuangan kas RT kepada seluruh warga. -3. **Keamanan Lingkungan** — Menyediakan sistem pelaporan insiden terintegrasi dengan notifikasi instan. -4. **Pelayanan AI** — Menghadirkan asisten virtual cerdas (Siaga) via web chatbot dan Telegram bot. -5. **Aksesibilitas** — Dapat diakses dari smartphone (PWA), tablet, dan desktop oleh seluruh lapisan usia warga. - -### 1.3 Tech Stack Summary - -``` -┌─────────────────────────────────────────────────────┐ -│ PRISMA STACK │ -├──────────────┬──────────────────────────────────────┤ -│ Frontend │ Next.js 16.1.4, React 19, TypeScript │ -│ Styling │ Tailwind CSS v4, PostCSS, Framer Mo. │ -│ Component │ Radix UI Primitives (@radix-ui/*) │ -│ State/Theme │ next-themes, clsx, tailwind-merge │ -│ Database │ sql.js (SQLite in-browser), Supabase │ -│ AI Frontend │ @google/generative-ai, Ollama Client │ -│ AI Backend │ Python FastAPI + Ollama LLM │ -│ Bot Engine │ node-telegram-bot-api + pdfkit │ -│ PWA │ @serwist/next (Service Worker) │ -│ Testing │ Vitest + @testing-library/react │ -│ Security │ bcryptjs, dompurify, xss, sanitize │ -│ Deploy │ Cloudflare Pages, Vercel │ -│ I18n │ next-intl (ID, EN, ZH) │ -│ SEO │ next-sitemap │ -└──────────────┴──────────────────────────────────────┘ -``` - ---- - -## 2. Arsitektur & Kerangka Sistem - -### 2.1 Arsitektur Diagram - -```mermaid -graph TB - subgraph Client["🌐 Client Layer"] - WEB["Next.js Web App
(Port 3000)"] - PWA["PWA / Mobile Browser"] - TG["Telegram Bot Client"] - end - - subgraph Presentation["🎨 Presentation (Next.js App Router)"] - PAGES["23 Pages/Routes"] - COMP["Reusable Components"] - THEME["Theme System
Dark/Light Mode"] - end - - subgraph Services["⚙️ Service Layer"] - DBSVC["databaseService.ts"] - AISVC["ai-service.ts"] - SECSVC["security.ts"] - HOOKS["security-hooks.ts"] - end - - subgraph Data["🗄️ Data Layer"] - SQLITE["sql.js (SQLite)"] - MOCK["MockDB (localStorage)"] - SUPA["Supabase (Cloud)"] - end - - subgraph AI["🤖 AI Layer"] - OLLAMA["Ollama LLM Server
(Port 11434)"] - FASTAPI["FastAPI Backend
(Port 8000)"] - RAG["RAG Chat Backend
(Port 8001)"] - end - - subgraph Bot["📱 Bot Layer"] - TGBOT["telegram-bot.ts"] - PDFGEN["PDFKit Generator"] - DSTORE["data-store.json"] - end - - Client --> Presentation - Presentation --> Services - Services --> Data - Services --> AI - TG --> Bot - Bot --> OLLAMA - Bot --> DSTORE - Bot --> PDFGEN -``` - -### 2.2 Struktur Direktori - -``` -prisma/ -├── src/ -│ ├── app/ # Next.js App Router (Pages & Routes) -│ │ ├── page.tsx # Landing/Dashboard Page -│ │ ├── layout.tsx # Root Layout + Security Init -│ │ ├── globals.css # Global Design Tokens (Tailwind v4) -│ │ ├── admin/ # Admin Panel -│ │ │ ├── page.tsx # Admin Dashboard -│ │ │ ├── audit/page.tsx # Audit Log Viewer -│ │ │ ├── files/page.tsx # File Manager -│ │ │ ├── infrastruktur/page.tsx# Infrastructure Management -│ │ │ └── login/page.tsx # Admin Login -│ │ ├── auth/ # Authentication -│ │ │ ├── login/page.tsx # User Login -│ │ │ └── register/page.tsx # User Registration -│ │ ├── galeri/page.tsx # Photo Gallery -│ │ ├── keuangan/ # Financial Module -│ │ │ ├── laporan/page.tsx # Financial Reports -│ │ │ ├── iuran/page.tsx # Monthly Dues -│ │ │ ├── pembayaran/page.tsx # Payment Processing -│ │ │ ├── custom/page.tsx # Custom Reports -│ │ │ ├── event-budget/page.tsx # Event Budget -│ │ │ └── share/page.tsx # Share Reports -│ │ ├── layanan/ # Service Center -│ │ │ ├── page.tsx # Service Hub -│ │ │ └── administrasi/page.tsx # Administration Services -│ │ ├── surat/ # Document Management -│ │ │ ├── page.tsx # Letter Templates -│ │ │ └── keamanan/page.tsx # Security Report Form -│ │ ├── profile/page.tsx # User Profile -│ │ ├── search/page.tsx # Search Page -│ │ ├── settings/database/page.tsx# Database Settings -│ │ ├── telegram-webapp/page.tsx # Telegram WebApp View -│ │ ├── sw.ts # Service Worker (Serwist) -│ │ └── manifest.ts # PWA Manifest -│ ├── components/ # Reusable UI Components -│ │ ├── chat/chatbot.tsx # AI Chatbot Widget (Floating) -│ │ ├── home/ # Landing Page Components -│ │ ├── layout/ # Navbar, Sidebar, Footer -│ │ ├── surat/ # Letter Form Components -│ │ ├── ui/ # Radix UI Primitives -│ │ ├── pwa-install-prompt.tsx # PWA Install Banner -│ │ ├── theme-provider.tsx # Dark/Light Mode Provider -│ │ ├── theme-toggle.tsx # Theme Switch Button -│ │ └── whatsapp-direct.tsx # WhatsApp Integration -│ ├── Services/ # Business Logic Services -│ │ ├── databaseService.ts # Central DB API (SQLite + MockDB) -│ │ ├── aiService.ts # AI Backend Client -│ │ ├── dataService.ts # Data Transformation -│ │ └── nlpService.ts # NLP Processing Client -│ ├── lib/ # Core Library -│ │ ├── security.ts # OWASP Security Core (567 lines) -│ │ ├── security-hooks.ts # React Security Hooks (346 lines) -│ │ ├── sqliteDB.ts # SQLite In-Browser Engine -│ │ ├── mockDatabase.ts # Mock/Seed Data Fallback -│ │ ├── ai-service.ts # Ollama AI Client -│ │ ├── demo-credentials.ts # Demo Auth Credentials -│ │ ├── financial-utils.ts # Financial Calculations -│ │ ├── performance.ts # Performance Monitoring -│ │ └── strategic-recommendations.ts # AI Recommendations -│ ├── hooks/ # Custom React Hooks -│ │ ├── useSafeNavigation.ts # Safe Navigation Hook -│ │ └── use-click-outside.ts # Click Outside Detection -│ └── config/ -│ └── apiConfig.ts # API URL Configuration -├── scripts/ # Background Scripts -│ ├── telegram-bot.ts # Telegram Bot Engine (787 lines) -│ ├── generate_db.js # SQLite DB Seeder -│ ├── data-store.json # Bot Real-Time Data Store -│ └── bot-runner.ps1 # Bot Startup Script -├── public/ # Static Assets -├── messages/ # i18n Translation Files -├── types/ # TypeScript Type Definitions -├── next.config.ts # Next.js Configuration -├── vitest.config.ts # Test Configuration -├── tsconfig.json # TypeScript Configuration -├── wrangler.json # Cloudflare Pages Config -├── vercel.json # Vercel Config -└── prisma_demo.db # SQLite Demo Database File -``` - -### 2.3 Layer Architecture - -| Layer | Tanggung Jawab | File Utama | -|---|---|---| -| **Presentation** | UI rendering, routing, theme | `src/app/**/*.tsx`, `src/components/**` | -| **Hook** | State management, side effects | `src/hooks/*`, `src/lib/security-hooks.ts` | -| **Service** | Business logic, API orchestration | `src/Services/*` | -| **Data Access** | Database CRUD, query engine | `src/lib/sqliteDB.ts`, `src/lib/mockDatabase.ts` | -| **Security** | Auth, encryption, sanitization | `src/lib/security.ts` | -| **AI/Bot** | LLM integration, bot commands | `src/lib/ai-service.ts`, `scripts/telegram-bot.ts` | - ---- - -## 3. Desain UI/UX Web - -### 3.1 Design System - -``` -┌─────────────────────────────────────────────────────┐ -│ DESIGN SYSTEM │ -├──────────────┬──────────────────────────────────────┤ -│ Framework │ Tailwind CSS v4 (utility-first) │ -│ Components │ Radix UI Primitives (A11y) │ -│ Animations │ Framer Motion (fluid transitions) │ -│ Theming │ next-themes (Dark/Light auto) │ -│ Icons │ Lucide React + React Icons │ -│ Typography │ System fonts, Inter (Google Fonts) │ -│ Approach │ Mobile-First Responsive │ -└──────────────┴──────────────────────────────────────┘ -``` - -### 3.2 Color Palette & Theming - -```css -/* Light Mode — Warm Professional */ ---primary: #0f172a /* Slate 900 (Headers, Nav) */ ---primary-accent: #1e40af /* Blue 800 (CTA, Links) */ ---surface: #ffffff /* White (Cards, Panels) */ ---background: #f8fafc /* Slate 50 (Page BG) */ ---success: #16a34a /* Green 600 */ ---warning: #f59e0b /* Amber 500 */ ---danger: #dc2626 /* Red 600 */ ---text-primary: #1e293b /* Slate 800 */ ---text-secondary: #64748b /* Slate 500 */ - -/* Dark Mode — Deep Professional */ ---primary: #e2e8f0 /* Slate 200 (Headers) */ ---primary-accent: #60a5fa /* Blue 400 */ ---surface: #1e293b /* Slate 800 (Cards) */ ---background: #0f172a /* Slate 900 (Page BG) */ -``` - -### 3.3 Layout Structure - -``` -┌──────────────────────────────────────────────────┐ -│ [≡ NAVBAR] 🏠 PRISMA RT 04 [🔍] [🌙/☀️] [👤] │ -├──────────────────────────────────────────────────┤ -│ │ -│ ┌─ MAIN CONTENT ──────────────────────────────┐ │ -│ │ │ │ -│ │ 📊 Dashboard / Page Content │ │ -│ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │ -│ │ │Stat 1│ │Stat 2│ │Stat 3│ │Stat 4│ │ │ -│ │ └──────┘ └──────┘ └──────┘ └──────┘ │ │ -│ │ │ │ -│ │ ┌──── Feature Cards Grid ───────────────┐ │ │ -│ │ │ 💰 Keuangan │ 📝 Surat │ 🚨 Keamanan│ │ │ -│ │ │ 👥 Warga │ 📢 Info │ ⚙️ Pengaturan│ │ │ -│ │ └────────────────────────────────────────┘ │ │ -│ │ │ │ -│ └──────────────────────────────────────────────┘ │ -│ │ -│ ┌─ FLOATING CHATBOT ─┐ │ -│ │ 🤖 Siaga │ │ -│ │ Tanya saya! │ │ -│ └────────────────────┘ │ -├──────────────────────────────────────────────────┤ -│ [FOOTER] © PRISMA RT 04 • Links • Contacts │ -└──────────────────────────────────────────────────┘ -``` - -### 3.4 Halaman/Route Map - -| # | Route | Fungsi | Akses | -|---|---|---|---| -| 1 | `/` | Landing/Dashboard utama | Public | -| 2 | `/auth/login` | Login warga | Public | -| 3 | `/auth/register` | Registrasi warga baru | Public | -| 4 | `/admin` | Panel admin dashboard | Admin | -| 5 | `/admin/login` | Login admin | Public | -| 6 | `/admin/audit` | Audit log viewer | Admin | -| 7 | `/admin/files` | File management | Admin | -| 8 | `/admin/infrastruktur` | Infrastruktur RT | Admin | -| 9 | `/keuangan/laporan` | Laporan keuangan bulanan | Warga | -| 10 | `/keuangan/iuran` | Status iuran warga | Warga | -| 11 | `/keuangan/pembayaran` | Proses pembayaran | Warga | -| 12 | `/keuangan/custom` | Custom financial report | Admin | -| 13 | `/keuangan/event-budget` | Anggaran event RT | Admin | -| 14 | `/keuangan/share` | Share laporan keuangan | Warga | -| 15 | `/layanan` | Hub layanan mandiri | Warga | -| 16 | `/layanan/administrasi` | Administrasi kependudukan | Warga | -| 17 | `/surat` | Template surat RT | Warga | -| 18 | `/surat/keamanan` | Form lapor keamanan | Warga | -| 19 | `/galeri` | Galeri foto RT | Public | -| 20 | `/profile` | Profil pengguna | Warga | -| 21 | `/search` | Pencarian global | Warga | -| 22 | `/settings/database` | Pengaturan database | Admin | -| 23 | `/telegram-webapp` | Telegram WebApp view | Public | - -### 3.5 Komponen Reusable - -| Komponen | Lokasi | Fungsi | -|---|---|---| -| `chatbot.tsx` | `components/chat/` | Floating AI chatbot widget | -| `pwa-install-prompt.tsx` | `components/` | Banner install PWA | -| `theme-provider.tsx` | `components/` | Dark/Light mode context | -| `theme-toggle.tsx` | `components/` | Toggle switch tema | -| `whatsapp-direct.tsx` | `components/` | Quick WA action button | -| `ui/*` | `components/ui/` | Button, Card, Input, Dialog, Accordion, etc. | - ---- - -## 4. Build & Konfigurasi - -### 4.1 Next.js Configuration - -```typescript -// next.config.ts — Key Settings -{ - output: 'export', // Static HTML Export (SSG) - images: { unoptimized: true }, - trailingSlash: true, // URL compatibility - compress: true, // Gzip compression - poweredByHeader: false, // Remove X-Powered-By (security) - turbopack: {}, // Turbopack engine - logging: { fetches: { fullUrl: true } } -} -// + @serwist/next PWA wrapper (Service Worker) -``` - -### 4.2 Build Scripts - -| Script | Perintah | Fungsi | -|---|---|---| -| `dev` | `next dev` | Development server (port 3000) | -| `build` | `next build` | Production build + static export | -| `start` | `next start` | Production server | -| `lint` | `eslint` | Code linting | -| `test` | `vitest run` | Run unit tests | -| `test:watch` | `vitest` | Watch mode testing | -| `test:ci` | `vitest run --reporter=verbose` | CI verbose tests | -| `deploy:cf` | `npm run build && npx wrangler pages deploy out` | Cloudflare Pages deploy | -| `bot` | `ts-node ... scripts/telegram-bot.ts` | Start Telegram bot | - -### 4.3 Environment Variables - -```bash -# .env.local — Web Application -NEXT_PUBLIC_AI_BACKEND_URL="http://localhost:8000" # FastAPI AI Backend -NEXT_PUBLIC_CHAT_API_URL="http://localhost:8001/chat" # RAG Chat Backend -DB_HOST=localhost # Legacy MySQL fallback -DB_PORT=3306 -DB_NAME=admin_rt - -# .env.bot — Telegram Bot -TELEGRAM_BOT_TOKEN= # Bot @mayoran04Bot -OLLAMA_API_URL=http://localhost:11434/api/chat # Ollama LLM endpoint -OLLAMA_MODEL= # Primary AI model -OLLAMA_API_KEY= # API key (if needed) -ADMIN_CHAT_ID= # Admin notification target -NEXT_PUBLIC_AI_BACKEND_URL=http://localhost:3000 # Website monitoring URL -``` - ---- - -## 5. Development Guidelines - -### 5.1 Coding Standards - -| Aspek | Standar | -|---|---| -| **Language** | TypeScript strict mode | -| **Naming** | camelCase (vars/functions), PascalCase (components/types) | -| **Components** | Functional components + hooks only | -| **Imports** | Absolute paths via `@/` alias | -| **State** | React hooks (`useState`, `useCallback`, `useEffect`) | -| **Side Effects** | Custom hooks pattern (e.g., `useSecureAuth`) | -| **Styling** | Tailwind utility classes, `clsx()` for conditionals | -| **Sanitization** | ALL user input MUST pass through `sanitizeInput()` | -| **Error Handling** | try/catch with `logSecurityEvent()` | - -### 5.2 Component Development Pattern - -```typescript -// Template: Server-safe Client Component -"use client" - -import { useState, useCallback } from 'react' -import { sanitizeInput } from '@/lib/security' -import { Button } from '@/components/ui/button' - -interface Props { - // Always define explicit interfaces -} - -export function FeatureComponent({ ...props }: Props) { - const [data, setData] = useState(initial) - - const handleAction = useCallback(async () => { - const sanitized = sanitizeInput(rawInput) // ALWAYS sanitize - // ... business logic - }, [dependencies]) - - return ( -
- {/* Mobile-first responsive layout */} -
- ) -} -``` - -### 5.3 Data Flow Pattern - -``` -User Input → sanitizeInput() → Service Layer → Database Layer → Response - │ │ - └── checkRateLimit() ──────────┘ - └── logSecurityEvent() ────────┘ -``` - ---- - -## 6. Maintenance & Operasional - -### 6.1 Monitoring Checklist - -| Item | Tool | Frekuensi | -|---|---|---| -| Website uptime | Telegram Bot auto-ping (5 min interval) | Real-time | -| Bot status | `/status` command | On-demand | -| Security audit log | `getAuditLog()` + Admin panel | Harian | -| Database size | Settings > Database page | Mingguan | -| Dependency updates | `npm audit` | Bulanan | -| SSL certificate | Cloudflare/Vercel auto-managed | Otomatis | - -### 6.2 Backup Strategy - -| Data | Metode | Lokasi Backup | -|---|---|---| -| SQLite Database | `SqliteDB.exportDB()` → download `.db` file | Manual download | -| data-store.json | Git version control | GitHub repository | -| Environment vars | Terpisah dari repo (`.gitignore`) | Secure vault | -| User uploads | Cloudflare/Vercel CDN | CDN edge nodes | - -### 6.3 Performance Targets - -| Metrik | Target | Cara Pencapaian | -|---|---|---| -| First Contentful Paint | < 1.5s | SSG + Turbopack | -| Time to Interactive | < 3s | Code splitting, lazy load | -| Lighthouse Score | > 90 | PWA, compression, semantic HTML | -| API Response Time | < 200ms | SQLite in-memory, debounced save | -| Bot Response Time | < 5s | Ollama streaming, fallback model | - -### 6.4 Scaling Plan - -``` -Level 1 (Current): Monolith SSG + Client SQLite - ↓ -Level 2: Supabase Cloud DB + Edge Functions - ↓ -Level 3: Microservices (Next.js + FastAPI + RAG separated) - ↓ -Level 4: Kubernetes orchestration + dedicated ML serving -``` - ---- - -## 7. Security Framework - -### 7.1 OWASP Top 10 Coverage - -| OWASP | Implementasi di PRISMA | File | -|---|---|---| -| **A01: Broken Access Control** | Role-based auth (`admin/staff/warga`), session fingerprinting | `security.ts` | -| **A02: Cryptographic Failures** | XOR encryption (demo) + bcryptjs hashing, runtime key derivation | `security.ts` | -| **A03: Injection** | `sanitizeInput()` — multi-layer XSS/SQL inject strip, `dompurify`, `xss` lib | `security.ts` | -| **A05: Security Misconfiguration** | `poweredByHeader: false`, console suppression in prod | `next.config.ts` | -| **A07: Auth Failures** | Rate limiting (5 login/min, 5 min block), password strength validator | `security.ts` | -| **A08: Data Integrity** | CSRF token management (`generateCSRFToken`, `validateCSRFToken`) | `security.ts` | -| **A09: Logging Failures** | Audit log system (`logSecurityEvent()`, max 1000 entries) | `security.ts` | - -### 7.2 Security Module Map - -``` -┌─────────────────────────────────────────────────────────┐ -│ security.ts (Core) │ -├─────────────────────────────────────────────────────────┤ -│ ✅ encryptData() / decryptData() — XOR + Base64 │ -│ ✅ secureStorage — Encrypted session │ -│ ✅ generateFingerprint() — Browser-based │ -│ ✅ sanitizeInput() / sanitizeObject()— Multi-layer clean │ -│ ✅ checkRateLimit() / resetRateLimit() │ -│ ✅ maskPhoneNumber/Email/NIK/Name — PII masking │ -│ ✅ storeCredentials/getCredentials — Secure session │ -│ ✅ generateCSRFToken/validateCSRF — Anti-CSRF │ -│ ✅ secureFetch() — Protected HTTP │ -│ ✅ validatePasswordStrength() — Password scoring │ -│ ✅ logSecurityEvent() / getAuditLog()— Audit trail │ -│ ✅ initSecurityProtections() — Anti-clickjack │ -└─────────────────────────────────────────────────────────┘ - -┌─────────────────────────────────────────────────────────┐ -│ security-hooks.ts (React) │ -├─────────────────────────────────────────────────────────┤ -│ ✅ useSecureAuth() — Login/logout + rate limit │ -│ ✅ useDataMasking() — Toggle sensitive data display │ -│ ✅ useSecureForm() — Auto-sanitize form inputs │ -│ ✅ useSecureApi() — Protected API calls │ -│ ✅ usePasswordStrength()— Real-time password scoring │ -│ ✅ useSecureStorage() — Encrypted localStorage hook │ -└─────────────────────────────────────────────────────────┘ -``` - -### 7.3 Bot Security (Telegram) - -| Perlindungan | Implementasi | -|---|---| -| Input Sanitization | `sanitizeBotInput()` — strip `` -**Injection Points:** - -- Login email field → **BLOCKED** (sanitizeInput strips `` - -- **BEFORE FIX:** ⚠️ Null byte could bypass WAF -- **AFTER FIX:** ✅ BLOCKED - null bytes removed - ---- - -#### TC-SEC-002: SQL Injection - -**Test Vector:** `' OR '1'='1' --` -**Injection Points:** - -- Login email field → **BLOCKED** (quotes stripped by sanitizeInput) -- Admin search → **BLOCKED** (parameterized queries in SqliteDB) - -**Test Vector (UNION):** `' UNION SELECT * FROM users --` - -- **RESULT:** ✅ BLOCKED - semicolons and quotes stripped - -**Note:** SQLite runs client-side only (sql.js in browser). No server-side SQL = reduced attack surface. - ---- - -#### TC-SEC-003: CSRF Protection - -**Test Method:** Craft external HTML form targeting PRISMA endpoints - -- **secureFetch()** adds `X-CSRF-Token` header automatically -- **X-Requested-With: XMLHttpRequest** prevents simple CSRF -- **SameSite cookie policy** enforced via CORS `same-origin` -- **RESULT:** ✅ PASS - ---- - -#### TC-SEC-004: Clickjacking - -**Test Method:** Embed PRISMA in `