diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml
new file mode 100644
index 0000000..371f2e2
--- /dev/null
+++ b/.idea/appInsightsSettings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 8b2c35e..ec57099 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,6 +1,7 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
+ id("com.google.devtools.ksp") version "1.9.22-1.0.16"
}
android {
@@ -66,4 +67,17 @@ dependencies {
androidTestImplementation(libs.ui.test.junit4)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)
+
+ // Room Database - TAMBAHKAN INI SEMUA
+ val roomVersion = "2.6.1"
+ implementation("androidx.room:room-runtime:$roomVersion")
+ implementation("androidx.room:room-ktx:$roomVersion")
+ ksp("androidx.room:room-compiler:$roomVersion")
+
+ // Coroutines
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
+
+ // ViewModel & Lifecycle
+ implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
+ implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notebook/MainActivity.kt b/app/src/main/java/com/example/notebook/MainActivity.kt
index 41a997b..2d8bde0 100644
--- a/app/src/main/java/com/example/notebook/MainActivity.kt
+++ b/app/src/main/java/com/example/notebook/MainActivity.kt
@@ -33,6 +33,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
+import com.example.notebook.data.DatabaseTest
import com.example.notebook.ui.theme.NotebookTheme
class MainActivity : ComponentActivity() {
diff --git a/app/src/main/java/com/example/notebook/data/AppDatabase.kt b/app/src/main/java/com/example/notebook/data/AppDatabase.kt
new file mode 100644
index 0000000..9464132
--- /dev/null
+++ b/app/src/main/java/com/example/notebook/data/AppDatabase.kt
@@ -0,0 +1,44 @@
+package com.example.notebook.data
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+
+/**
+ * Database utama aplikasi
+ * Version 1 = versi pertama database kamu
+ */
+@Database(
+ entities = [
+ NotebookEntity::class,
+ SourceEntity::class,
+ ChatMessageEntity::class
+ ],
+ version = 1,
+ exportSchema = false
+)
+abstract class AppDatabase : RoomDatabase() {
+
+ abstract fun notebookDao(): NotebookDao
+
+ companion object {
+ @Volatile
+ private var INSTANCE: AppDatabase? = null
+
+ /**
+ * Singleton pattern - hanya ada 1 instance database
+ */
+ fun getDatabase(context: Context): AppDatabase {
+ return INSTANCE ?: synchronized(this) {
+ val instance = Room.databaseBuilder(
+ context.applicationContext,
+ AppDatabase::class.java,
+ "notebook_database"
+ ).build()
+ INSTANCE = instance
+ instance
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notebook/data/DatabaseTest.kt b/app/src/main/java/com/example/notebook/data/DatabaseTest.kt
new file mode 100644
index 0000000..903d9a6
--- /dev/null
+++ b/app/src/main/java/com/example/notebook/data/DatabaseTest.kt
@@ -0,0 +1,31 @@
+package com.example.notebook.data
+
+import android.content.Context
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+/**
+ * Helper untuk test database
+ * Panggil fungsi ini dari MainActivity untuk test
+ */
+class DatabaseTest(private val context: Context) {
+
+ private val database = AppDatabase.getDatabase(context)
+ private val dao = database.notebookDao()
+
+ fun testInsertNotebook() {
+ CoroutineScope(Dispatchers.IO).launch {
+ val testNotebook = NotebookEntity(
+ title = "Notebook Test",
+ description = "Ini adalah test database",
+ createdAt = System.currentTimeMillis(),
+ updatedAt = System.currentTimeMillis(),
+ sourceCount = 0
+ )
+
+ val id = dao.insertNotebook(testNotebook)
+ println("✅ Database Test: Notebook berhasil disimpan dengan ID: $id")
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notebook/data/NotebookDao.kt b/app/src/main/java/com/example/notebook/data/NotebookDao.kt
new file mode 100644
index 0000000..1e64801
--- /dev/null
+++ b/app/src/main/java/com/example/notebook/data/NotebookDao.kt
@@ -0,0 +1,51 @@
+package com.example.notebook.data
+
+import androidx.room.*
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * DAO (Data Access Object) untuk mengakses database
+ * Semua fungsi ini otomatis dihandle Room
+ */
+@Dao
+interface NotebookDao {
+
+ // === NOTEBOOK OPERATIONS ===
+
+ @Insert
+ suspend fun insertNotebook(notebook: NotebookEntity): Long
+
+ @Update
+ suspend fun updateNotebook(notebook: NotebookEntity)
+
+ @Delete
+ suspend fun deleteNotebook(notebook: NotebookEntity)
+
+ @Query("SELECT * FROM notebooks ORDER BY updatedAt DESC")
+ fun getAllNotebooks(): Flow>
+
+ @Query("SELECT * FROM notebooks WHERE id = :notebookId")
+ fun getNotebookById(notebookId: Int): Flow
+
+ // === SOURCE OPERATIONS ===
+
+ @Insert
+ suspend fun insertSource(source: SourceEntity)
+
+ @Query("SELECT * FROM sources WHERE notebookId = :notebookId")
+ fun getSourcesByNotebook(notebookId: Int): Flow>
+
+ @Delete
+ suspend fun deleteSource(source: SourceEntity)
+
+ // === CHAT OPERATIONS ===
+
+ @Insert
+ suspend fun insertChatMessage(message: ChatMessageEntity)
+
+ @Query("SELECT * FROM chat_messages WHERE notebookId = :notebookId ORDER BY timestamp ASC")
+ fun getChatHistory(notebookId: Int): Flow>
+
+ @Query("DELETE FROM chat_messages WHERE notebookId = :notebookId")
+ suspend fun clearChatHistory(notebookId: Int)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/notebook/data/NotebookEntity.kt b/app/src/main/java/com/example/notebook/data/NotebookEntity.kt
new file mode 100644
index 0000000..3eeac80
--- /dev/null
+++ b/app/src/main/java/com/example/notebook/data/NotebookEntity.kt
@@ -0,0 +1,48 @@
+package com.example.notebook.data
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * Entity untuk menyimpan data Notebook di database
+ */
+@Entity(tableName = "notebooks")
+data class NotebookEntity(
+ @PrimaryKey(autoGenerate = true)
+ val id: Int = 0,
+
+ val title: String, // Judul notebook
+ val description: String, // Deskripsi singkat
+ val createdAt: Long, // Timestamp pembuatan
+ val updatedAt: Long, // Timestamp update terakhir
+ val sourceCount: Int = 0 // Jumlah sumber yang diupload
+)
+
+/**
+ * Entity untuk menyimpan sumber/dokumen yang diupload
+ */
+@Entity(tableName = "sources")
+data class SourceEntity(
+ @PrimaryKey(autoGenerate = true)
+ val id: Int = 0,
+
+ val notebookId: Int, // Foreign key ke notebook
+ val fileName: String, // Nama file
+ val fileType: String, // Tipe: PDF, Image, Text, dll
+ val filePath: String, // Path file di storage
+ val uploadedAt: Long // Timestamp upload
+)
+
+/**
+ * Entity untuk menyimpan chat history dengan AI
+ */
+@Entity(tableName = "chat_messages")
+data class ChatMessageEntity(
+ @PrimaryKey(autoGenerate = true)
+ val id: Int = 0,
+
+ val notebookId: Int, // Foreign key ke notebook
+ val message: String, // Isi pesan
+ val isUserMessage: Boolean, // true = user, false = AI
+ val timestamp: Long // Kapan pesan dikirim
+)
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index c1e23bc..15498bd 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,4 +2,5 @@
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.jetbrains.kotlin.android) apply false
+ id("com.google.devtools.ksp") version "1.9.22-1.0.16" apply false
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b0b9771..23f3239 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-agp = "8.2.2"
+agp = "8.13.1"
kotlin = "1.9.22"
coreKtx = "1.12.0"
junit = "4.13.2"