# Dashboard Solusi AI Peternakan Ayam Dashboard monitoring dan manajemen peternakan ayam berbasis web dengan integrasi IoT, AI, dan database PostgreSQL untuk penyimpanan data siklus produksi. ## 📋 Daftar Isi - [Fitur Utama](#fitur-utama) - [Cara Kerja AI Insight](#-cara-kerja-ai-insight) - [Teknologi](#teknologi) - [Deployment](#deployment) - [Persyaratan Sistem](#persyaratan-sistem) - [Instalasi](#instalasi) - [Cara Menjalankan](#cara-menjalankan) - [Struktur Proyek](#struktur-proyek) - [API Documentation](#api-documentation) - [Database Schema](#database-schema) - [Troubleshooting](#troubleshooting) ## 🚀 Fitur Utama ### Frontend - **Dashboard Utama**: Monitoring real-time KPI, alert, dan kondisi kandang - **Linimasa Siklus**: Manajemen siklus produksi dengan timeline visual - **Hitung Ayam**: - Dashboard perhitungan populasi - **Manajemen Data**: CRUD data mortalitas dengan penyimpanan database - **Monitoring Berat**: Tracking berat ayam dengan distribusi dan statistik - **Standar Performa**: Perbandingan dengan standar Cobb - **Penjadwalan Pakan**: Rekomendasi jadwal pemberian pakan - **Feed Wastage**: Monitoring pemborosan pakan - **AI Insight**: Analisis per topik (dashboard, hitung ayam, berat, FCR, EEF, panel IoT, karung pakan) memakai LLM lokal + RAG buku standar CP 707. Setiap kartu menjelaskan **penyebab** dari angka yang menyimpang, bukan sekadar melaporkannya — lihat [Cara kerja AI Insight](#-cara-kerja-ai-insight). Dilengkapi pemilih hari, grafik pendukung, dan ekspor PDF berlabel lokasi & periode - **Behavior Analysis**: Analisis perilaku ayam dengan AI - **Network Monitoring**: Status koneksi IoT devices - **ERP Integration**: Sinkronisasi dengan sistem ERP ### Backend (PostgreSQL Database) - **Database**: PostgreSQL untuk penyimpanan data siklus dan mortalitas - **RESTful API**: Endpoint untuk CRUD operations - **Migrasi otomatis**: Skema dan migrasi dijalankan sendiri saat backend start - **Data TIDAK terisi otomatis**: tabel dibuat kosong. Isi dengan `backup.sql` (lihat [SETUP.md](SETUP.md)) — tanpa itu dashboard terbuka tanpa data sama sekali - **Persistent Storage**: Semua perubahan data tersimpan permanen ## 🧠 Cara Kerja AI Insight AI Insight tidak hanya melaporkan angka — ia menjelaskan **kenapa** sebuah angka menyimpang dari standar CP 707. Contoh keluarannya: > **Kesimpulan:** Mortalitas kumulatif 11,68% (2.920 ekor) jauh lebih tinggi dari standar > CP 707 3,52%, atau 3,3x standar. Penyebab utama adalah lonjakan kematian di hari ke-12 > hingga 15, didahului suhu kandang 34,2°C dan penurunan konsumsi pakan. > > **PENYEBAB:** > > 1. Suhu kandang di atas target CP 707 pada hari ke-11 s/d 15 mencapai 34,2°C > (6,2°C di atas target 28°C) — [Terbukti dari data] > 2. Penurunan konsumsi pakan >25% pada hari ke-12 — [Terbukti dari data] > > **TINDAKAN:** 1. Kembalikan suhu ke 28°C … 2. Periksa sistem pemberian pakan … ### Korelasi dihitung di kode, bukan oleh model Model 7B tidak dapat diandalkan mengkorelasikan deret angka mentah — ia cenderung melewatkan polanya atau mengarang. Karena itu korelasinya dihitung lebih dulu secara deterministik, lalu model hanya diminta mengurutkan dan menuliskannya: | Berkas | Peran | | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `utils/insightEvidence.ts` | Mengumpulkan deret lintas-domain (kematian, suhu, bobot, pakan, FCR) jadi satu objek `diagnostik`, di-cache sekali per siklus/hari | | `backend/services/rootCauseAnalysis.js` | Menghitung temuan: lonjakan kematian, deviasi terhadap standar CP 707, dan jeda 0–3 hari antara penyimpangan suhu/pakan dengan lonjakan kematian | | `backend/services/cp707Knowledge.js` | Angka standar resmi dari Lampiran 2 & 3 buku CP 707 | | `AI Insight/rag_service.py` | Kutipan teks buku CP 707 (ChromaDB) | Setiap sebab wajib berlabel `[Terbukti dari data]` atau `[Dugaan — perlu dicek: ...]`, dan metrik yang datanya kosong disebut terus terang di bagian **BELUM DAPAT DIPASTIKAN** — bukan disimpulkan aman diam-diam. ### Generate bersifat manual Kartu insight **tidak pernah** memanggil model dengan sendirinya. Membuka halaman hanya menampilkan hasil yang sudah pernah dibuat untuk periode itu (dari cache/database). Untuk membuat yang baru, tekan tombol **✨ Buat AI Insight** atau ikon refresh di kartu. Alasannya: satu generate memakan waktu menit-an, jadi menjalankannya otomatis di setiap halaman yang dibuka hanya membuang waktu model. ### Data diperbarui sekali sehari, pukul 17.00 WIB Data operasional tidak mengalir terus menerus — sumbernya memperbarui sekali sehari pada pukul 17.00 WIB. Konsekuensinya: insight yang dibuat pagi hari memakai data pembaruan **hari sebelumnya**, dan angkanya baru berganti setelah pembaruan berikutnya. Kalau hari ini belum sempat generate, masih ada waktu sampai sebelum pukul 17.00 besok tanpa datanya berubah. Karena itu setiap kartu AI Insight mencantumkan keterangan _"Data diperbarui setiap hari pukul 17.00 WIB"_ di bawah judulnya, dengan penjelasan lengkap pada tooltip-nya. Teksnya ada di `utils/insightDataSchedule.ts`. Batas jam yang sama sudah dipakai sebagai aturan D-1 di `utils/dateFilter.ts` dan `backend/utils/dateUtils.js` (`CUTOFF_HOUR = 17`): sebelum pukul 17.00, tanggal efektif untuk query data masih D-1. **Kalau jam pembaruan berubah, ketiga berkas itu harus diubah bersamaan** — `insightDataSchedule.ts` hanya keterangan untuk operator, bukan sumber aturannya. ### Generate ulang memberi jawaban yang berbeda Menekan generate untuk kedua kalinya pada periode data yang sama menghasilkan analisis yang **berbeda** — sudut pandang lain dan tindakan lain — dengan **angka yang tetap sama**, karena datanya memang tidak berubah. Sebelumnya generate kedua mengembalikan teks yang sama persis. Penyebabnya bukan data: `temperature` 0.1 **tanpa `seed`** membuat Ollama memakai seed tetap, dan pada suhu serendah itu samplingnya praktis greedy. Gejalanya menyesatkan — kartu Hitung Ayam melempar pesan _"Data belum diperbarui"_, seolah datanya yang salah. Perbaikannya tiga lapis, dan lapisan ketiga yang menentukan: 1. **Seed acak** di setiap permintaan. 2. **Temperature 0.7 hanya saat generate ulang** — generate pertama tetap 0.1. 3. **Sudut pandang yang dirotasi** (`backend/services/insightVariation.js`): enam lensa berbeda — manajemen pakan, lingkungan kandang, kesehatan & biosekuriti, air & pencahayaan, operasional harian, kehilangan pakan — dan tindakan dari jawaban sebelumnya dikirim sebagai daftar yang **dilarang diulang**. Lapisan 1 dan 2 saja tidak cukup untuk model 7B: terukur hasilnya masih 90,7% mirip dengan daftar tindakan yang identik. Menyuruh model "jangan sama" tidak berhasil; memberi lensa konkret berhasil. Setelah lapisan 3 ditambahkan, kemiripan turun ke **26,4%** dengan tindakan yang berbeda seluruhnya dan **nol angka karangan** — angka baru yang muncul hanya turunan aritmetika yang benar dari data yang sama. Pengaman angkanya adalah blok "ANGKA TIDAK BOLEH BERUBAH" di prompt variasi, bukan suhu yang rendah. Backend tahu sebuah permintaan adalah generate ulang lewat dua jalur berbeda: jalur dashboard memeriksa apakah sudah ada baris tersimpan untuk kunci cache yang sama, sedangkan jalur proxy per-halaman tidak punya cache sehingga frontend yang mengirim `previous_insight` — teks yang sedang tampil di layar. ### Kecepatan Waktu generate ditentukan perangkat keras yang menjalankan Ollama: - **Ollama native di macOS** memakai GPU (Metal) — paling cepat, disarankan untuk pengembangan - **Ollama di dalam Docker** pada macOS berjalan **CPU-only** (~6 token/detik), sehingga satu insight bisa memakan beberapa menit Periksa dengan `curl -s http://localhost:11434/api/ps` — `"size_vram": 0` berarti model sedang berjalan di CPU. ## 🛠 Teknologi ### Frontend - **React 18** dengan TypeScript - **Vite** - Build tool & dev server - **Recharts** - Data visualization - **Tailwind CSS** - Styling - **Context API** - State management ### Backend - **Node.js** dengan Express - **PostgreSQL** (pg) - Database - **CORS** - Cross-origin support ### AI - **Ollama** - LLM lokal (default `qwen2.5:7b`, ~5 GB) - **Python + FastAPI** - layanan RAG di folder `AI Insight/` - **ChromaDB** - penyimpanan vektor buku standar CP 707 ### Deployment - **Docker** - Containerization - **Docker Compose** - Orkestrasi 6 service: `database`, `backend`, `frontend`, `rag`, `llm` (Ollama), dan `llm-model-downloader` - **Nginx** - Reverse proxy & static file serving - **PostgreSQL** - Database container ## 🐳 Deployment ### Docker Deployment (Recommended for Production) Deploy dengan Docker Compose: ```bash docker compose up -d --build ``` Di mode Docker penuh, frontend disajikan Nginx di **port 5002**, backend di 15001, dan RAG di 5005 — berbeda dari mode pengembangan native. Jangan menjalankan kedua mode bersamaan; keduanya berebut port yang sama. **Keuntungan Docker:** - ✅ Easy deployment dan scaling - ✅ Isolated environment - ✅ Consistent across different servers - ✅ Automatic restarts - ✅ Built-in health checks **📚 Complete Docker Guide:** [DOCKER.md](DOCKER.md) **Setup dari nol sampai jalan:** [SETUP.md](SETUP.md) **Catatan teknis & pekerjaan yang masih terbuka:** [CATATAN-LANJUTAN.md](CATATAN-LANJUTAN.md) ### Manual Deployment Untuk development atau testing lokal, lihat [Instalasi](#instalasi) dan [Cara Menjalankan](#cara-menjalankan) di bawah. ## 📦 Persyaratan Sistem ### Untuk Docker Deployment - **Docker**: v20.10+ - **Docker Compose**: v2.0+ - **RAM**: minimum 8GB (model LLM berjalan di CPU) - **Disk**: 15GB free space — model `qwen2.5:7b` saja ~5GB - **Port**: 5002 (frontend), 15001 (backend), 15432 (Postgres), 11434 (Ollama), 5005 (RAG) ### Untuk Manual Installation - **Node.js**: v18.0.0 atau lebih tinggi - **npm**: v9.0.0 atau lebih tinggi - **Python**: v3.10+ — untuk layanan RAG - **Docker**: tetap dibutuhkan untuk PostgreSQL dan Ollama - **Port yang tersedia**: - Frontend: 3000, mundur ke 3001/3002/… bila terpakai - Backend: 5001 - RAG: 5002 - PostgreSQL: **15432** (bukan 5432 — dipetakan begitu agar tidak bentrok) - Ollama: 11434 ## 💿 Instalasi > **Panduan lengkap dan berurutan ada di [SETUP.md](SETUP.md).** Bagian di bawah ini > hanya memasang dependensi JavaScript. Aplikasi belum bisa jalan hanya dengan ini — > masih perlu file `.env`, container PostgreSQL dan Ollama, model LLM, dependensi > Python untuk RAG, serta pengisian database dari `backup.sql`. ### 1. Clone Repository ```bash git clone cd dashboard-solusi-ai-peternakan-ayam ``` ### 2. Install Dependencies Frontend ```bash npm install ``` ### 3. Install Dependencies Backend ```bash cd backend npm install cd .. ``` ## ▶️ Cara Menjalankan > Menjalankan backend dan frontend saja **tidak cukup** — AI Insight butuh layanan > RAG (port 5002) dan Ollama (port 11434) ikut hidup. Cara termudah: > > ```bash > docker compose up -d database llm # PostgreSQL + Ollama > bash start_all.sh # RAG + backend + frontend sekaligus > ``` > > `start_all.sh` menampilkan alamat frontend yang benar-benar dipakai di akhir > keluarannya. Bukalah alamat itu, jangan diasumsikan. ### Opsi 1: Menjalankan Secara Manual (Recommended untuk Development) #### Terminal 1 - Backend Server ```bash cd backend npm run dev ``` Backend akan berjalan di: **http://localhost:5001** Output yang diharapkan: ``` ======================================== 🚀 Server running on http://localhost:5001 ======================================== API Endpoints: GET /health GET /api/cycles GET /api/cycles/active ... ``` #### Terminal 2 - Frontend Server ```bash npm run dev ``` Frontend akan berjalan di: **http://localhost:3000** — atau 3001, 3002, dan seterusnya kalau port itu sedang dipakai proses lain. Backend menerima port localhost mana pun saat `NODE_ENV=development`, jadi berapa pun portnya aplikasi tetap jalan. Output yang diharapkan: ``` VITE v6.4.1 ready in 155 ms ➜ Local: http://localhost:3001/ ``` ### Opsi 2: Menjalankan dengan satu perintah Buka dua terminal secara terpisah: **Terminal 1:** ```bash cd backend && npm run dev ``` **Terminal 2:** ```bash npm run dev ``` Atau gunakan terminal multiplexer seperti `tmux` atau `screen`. ## 📁 Struktur Proyek ``` dashboard-solusi-ai-peternakan-ayam/ ├── backend/ # Backend Node.js + PostgreSQL │ ├── database/ │ │ ├── db.js # PostgreSQL connection & pool setup │ │ ├── schema.sql # Database schema │ │ ├── seed-postgres.js # Data seeding script │ │ └── migrations/ # Database migrations │ ├── models/ │ │ ├── Cycle.js # Cycle data model │ │ └── Mortality.js # Mortality data model │ ├── routes/ │ │ ├── cycles.js # Cycle endpoints │ │ └── mortality.js # Mortality endpoints │ ├── server.js # Express server │ ├── package.json │ └── .env # Environment variables ├── components/ # React components │ ├── counting/ │ │ └── DataManagementPage.tsx # Mortality data management │ ├── CycleTimeline.tsx # Cycle timeline component │ └── ... ├── context/ # React context & stores │ ├── AppContext.tsx │ └── stores/ │ └── useStaticDataStore.ts # Store with DB integration ├── services/ │ └── apiService.ts # API client with DB methods ├── scripts/ # Database & deployment scripts │ ├── backup-postgres.sh # Backup database │ ├── restore-postgres-local.sh # Restore from backup │ └── fetch-prod-db.sh # Fetch production data ├── mockData/ # Mock data for demo mode ├── types/ # TypeScript type definitions ├── public/ # Static assets ├── utils/ │ ├── insightEvidence.ts # Pengumpul data lintas-domain untuk analisis sebab │ └── insightParse.ts # Parser JSON toleran untuk jawaban model ├── AI Insight/ # Layanan RAG (Python) + ChromaDB + dokumen CP 707 ├── SETUP.md # Panduan setup dari nol ├── start_all.sh # Menyalakan RAG + backend + frontend ├── backup.sql # Data awal — WAJIB di-restore, tidak otomatis ├── docker-compose.yml # Orkestrasi 6 service ├── package.json └── README.md ``` ## 📡 API Documentation Base URL: `http://localhost:5001/api` ### Health Check ```http GET /health ``` **Response:** ```json { "status": "ok", "timestamp": "2025-12-22T03:02:20.793Z" } ``` ### Cycles Endpoints #### Get All Cycles ```http GET /api/cycles ``` **Response:** ```json { "success": true, "data": [ { "id": "CYCLE-JBW-2025-12-10", "totalDays": 42, "currentDay": 7, "startDate": "2025-12-10", "endDate": "2026-01-20", "chickInWeight": null, "docInCount": 20000, "status": "Active", "createdAt": "2025-12-22 02:59:17", "updatedAt": "2025-12-22 02:59:17" } ] } ``` #### Get Active Cycle ```http GET /api/cycles/active ``` #### Get Cycle by ID ```http GET /api/cycles/:id ``` #### Update Cycle ```http PUT /api/cycles/:id Content-Type: application/json { "totalDays": 42, "currentDay": 7, "startDate": "2025-12-10", "endDate": "2026-01-20", "chickInWeight": 42, "docInCount": 20000, "status": "Active" } ``` #### Delete Cycle ```http DELETE /api/cycles/:id ``` ### Mortality Endpoints #### Get All Mortality Records for Cycle ```http GET /api/mortality/:cycleId ``` **Response:** ```json { "success": true, "data": [ { "id": 1, "cycleId": "CYCLE-JBW-2025-12-10", "day": 0, "mortalityCount": 25, "isEdited": true, "createdAt": "2025-12-22 03:00:00", "updatedAt": "2025-12-22 03:00:00" } ] } ``` #### Get Mortality Record for Specific Day ```http GET /api/mortality/:cycleId/:day ``` #### Update/Create Mortality Record ```http PUT /api/mortality/:cycleId/:day Content-Type: application/json { "mortalityCount": 30 } ``` #### Delete Mortality Record (Reset to Default) ```http DELETE /api/mortality/:cycleId/:day ``` ## 🗄️ Database Schema ### Table: cycles Menyimpan informasi siklus produksi. | Column | Type | Description | | --------------- | ------- | ----------------------------------------- | | id | TEXT | Primary key, format: CYCLE-JBW-YYYY-MM-DD | | total_days | INTEGER | Total hari dalam siklus (biasanya 42) | | current_day | INTEGER | Hari saat ini dalam siklus | | start_date | TEXT | Tanggal mulai (ISO format: YYYY-MM-DD) | | end_date | TEXT | Tanggal akhir (ISO format: YYYY-MM-DD) | | chick_in_weight | INTEGER | Berat DOC in (gram) | | doc_in_count | INTEGER | Jumlah DOC in (ekor) | | status | TEXT | Status: 'Active', 'Completed', 'Upcoming' | | created_at | TEXT | Timestamp pembuatan | | updated_at | TEXT | Timestamp update terakhir | ### Table: mortality_records Menyimpan data mortalitas harian. | Column | Type | Description | | --------------- | ------- | ------------------------------------ | | id | INTEGER | Primary key (auto increment) | | cycle_id | TEXT | Foreign key ke cycles.id | | day | INTEGER | Hari ke berapa dalam siklus | | mortality_count | INTEGER | Jumlah mortalitas hari ini | | is_edited | BOOLEAN | Flag apakah data sudah diedit manual | | created_at | TEXT | Timestamp pembuatan | | updated_at | TEXT | Timestamp update terakhir | **Constraints:** - UNIQUE(cycle_id, day) - Satu cycle hanya bisa punya satu record per hari - FOREIGN KEY cascade delete - Jika cycle dihapus, mortality records ikut terhapus ### Indexes - `idx_mortality_cycle_id` - Index pada cycle_id untuk query cepat - `idx_mortality_day` - Index pada day - `idx_cycles_status` - Index pada status untuk filter cycle aktif - `idx_cycles_start_date` - Index pada start_date untuk sorting ## 🔧 Troubleshooting ### Port 5001 sudah terpakai Jika port 5001 sudah digunakan oleh aplikasi lain (contoh: AirPlay on macOS): 1. Edit file `backend/.env`: ```env PORT=5002 # Ganti ke port lain yang tersedia ``` 2. Update URL di `services/apiService.ts`: ```typescript const DB_API_BASE_URL = 'http://localhost:5002/api'; ``` 3. Restart backend server ### Port 3001 sudah terpakai Vite akan otomatis mencari port lain yang tersedia. Perhatikan output di terminal untuk melihat port yang digunakan. ### Database tidak terbuat Jika database tidak terbuat otomatis: ```bash cd backend node database/seed-postgres.js ``` ### CORS Error Jika frontend tidak bisa mengakses backend, pastikan: 1. Backend server sudah berjalan 2. Port di `backend/server.js` sesuai dengan konfigurasi CORS: ```javascript origin: ['http://localhost:3001', 'http://localhost:5173']; ``` ### Frontend tidak load data dari database 1. Buka browser console (F12) 2. Cek apakah ada error dari API calls 3. Pastikan backend server berjalan: `curl http://localhost:5001/health` 4. Cek network tab untuk melihat request/response ### Error "Failed to load cycles from database" 1. Pastikan backend server sudah berjalan 2. Test backend endpoint: `curl http://localhost:5001/api/cycles` 3. Cek backend logs untuk melihat error detail ### Reset Database ke Data Awal **For Local PostgreSQL Development:** ```bash # Stop backend if running, then: ./scripts/restore-postgres-local.sh --reset # Or manually run seed: cd backend node database/seed-postgres.js ``` **For Docker:** ```bash # Reset database by removing volume and restarting: docker-compose down -v docker-compose up -d ``` ## 📝 Fitur Database ### Auto-Seeding Database akan otomatis terisi dengan 4 siklus produksi saat pertama kali server backend dijalankan: 1. **CYCLE-JBW-2025-05-20** - Completed (20 Mei - 30 Juni 2025) 2. **CYCLE-JBW-2025-07-11** - Completed (11 Juli - 21 Agustus 2025) 3. **CYCLE-JBW-2025-10-22** - Completed (22 Oktober - 2 Desember 2025) 4. **CYCLE-JBW-2025-12-10** - Active (10 Desember 2025 - 20 Januari 2026) ✓ ### Data Persistence Semua perubahan data akan tersimpan permanen di PostgreSQL database: - ✅ Perubahan tanggal siklus di Linimasa - ✅ Update DOC In dan Berat DOC di pengaturan siklus - ✅ Edit data mortalitas di halaman Manajemen Data - ✅ Reset data mortalitas ke nilai default ### Backup Database **Production/Docker:** ```bash ./scripts/backup-postgres.sh ``` Backups are saved in `./backups/` as `dashboard_db-YYYYMMDD-HHMMSS.sql.gz` **Fetch from production server:** ```bash REMOTE_USER=your-user \ REMOTE_HOST=your-host \ REMOTE_PROJECT_DIR=/path/to/project \ ./scripts/fetch-prod-db.sh ``` ## 🔐 Environment Variables ### Backend (.env) File: `backend/.env` ```env PORT=5001 NODE_ENV=development # PostgreSQL Configuration DB_HOST=localhost DB_PORT=5432 DB_USER=dashboard_user DB_PASSWORD=your_password DB_NAME=dashboard_db DB_SSL=false ``` ### Frontend (.env.local) - Optional File: `.env.local` (create if needed) ```env VITE_API_URL=http://localhost:5001/api ``` ## 🎯 Testing ### Test Backend API ```bash # Health check curl http://localhost:5001/health # Get all cycles curl http://localhost:5001/api/cycles # Get active cycle curl http://localhost:5001/api/cycles/active # Get mortality records curl http://localhost:5001/api/mortality/CYCLE-JBW-2025-12-10 ``` ### Test Frontend 1. Buka http://localhost:3001 di browser 2. Navigasi ke "Linimasa Siklus Produksi" 3. Klik "Edit" pada siklus aktif 4. Ubah tanggal atau DOC count 5. Save dan refresh - data harus tetap tersimpan 6. Navigasi ke "Hitung Ayam" > "Manajemen Data" 7. Edit nilai mortalitas 8. Save dan refresh - data harus tetap tersimpan ## 📚 Cara Menggunakan Aplikasi ### 1. Mengelola Siklus Produksi **Linimasa Siklus:** - Lihat semua siklus produksi (completed, active, upcoming) - Edit tanggal mulai dan akhir - Set DOC In count dan berat DOC - Data tersimpan otomatis ke database ### 2. Manajemen Data Mortalitas **Hitung Ayam > Manajemen Data:** - Lihat data mortalitas per hari - Edit nilai mortalitas dengan klik "Edit" - Reset ke nilai default dengan klik tombol reset - Lihat statistik: populasi awal, populasi saat ini, total mortalitas, tingkat mortalitas - Filter data: cari per hari atau tampilkan hanya data yang diedit - Data tersimpan permanen di database ### 3. Monitoring Standar Performa **Standar Performa > Cobb Standard:** - Kapasitas kandang otomatis sync dengan DOC In count dari linimasa - Lihat grafik perbandingan berat aktual vs standar Cobb - Analisis FCR (Feed Conversion Ratio) ## 🚦 Status Proyek - ✅ Frontend Dashboard - ✅ Backend API dengan PostgreSQL - ✅ Database Schema & Models - ✅ CRUD Cycles - ✅ CRUD Mortality Records - ✅ Frontend-Backend Integration - ✅ Data Persistence - ✅ AI Insight per topik dengan LLM lokal + RAG CP 707 - ✅ Analisis sebab-akibat berbasis data lintas-domain (mortalitas, suhu, pakan, bobot) - ✅ Generate insight manual (tidak lagi otomatis saat halaman dibuka) - ✅ Ekspor PDF berlabel lokasi, kandang, dan periode - ✅ Docker Deployment (6 service) - ✅ Database Backup & Restore Scripts - ⏳ User Authentication (coming soon) - ⏳ Real-time WebSocket (coming soon) - ⏳ Data Export (CSV/Excel) (coming soon) ## 🤝 Kontribusi Untuk berkontribusi pada proyek ini: 1. Fork repository 2. Buat branch feature (`git checkout -b feature/AmazingFeature`) 3. Commit perubahan (`git commit -m 'Add some AmazingFeature'`) 4. Push ke branch (`git push origin feature/AmazingFeature`) 5. Buat Pull Request ## 📄 License Proyek ini menggunakan lisensi MIT. ## 👥 Tim Pengembang - Development Team - PT Cipta Pola Solusi Prima - Dashboard & AI Integration - 2025 ## 📞 Kontak Untuk pertanyaan atau dukungan, silakan hubungi: - Email: support@cpsp.id - Website: https://dashboard.cpsp.id --- **Dibuat dengan ❤️ untuk kemajuan peternakan ayam Indonesia**