460 lines
13 KiB
Markdown
460 lines
13 KiB
Markdown
# 📂 PROJECT STRUCTURE & FILE OVERVIEW
|
|
|
|
## Complete Project Structure
|
|
|
|
```
|
|
Starter-EAS-2025-2026/
|
|
│
|
|
├── 📄 README.md (Project description)
|
|
├── 📄 Mockup.png (UI mockup image)
|
|
├── 📄 n8n-workflow-EAS.json (Webhook configuration)
|
|
│
|
|
├── 📋 DEVELOPMENT_GUIDE.md ✨ (User & developer guide)
|
|
├── 📋 CHANGELOG.md ✨ (Version history & changes)
|
|
├── 📋 IMPLEMENTATION_NOTES.md ✨ (Technical config)
|
|
├── 📋 IMPLEMENTATION_SUMMARY.md ✨ (Project summary)
|
|
├── 📋 QUICK_REFERENCE.md ✨ (Quick lookup)
|
|
│
|
|
├── 🔧 build.gradle.kts (Project-level build config)
|
|
├── 🔧 settings.gradle.kts (Project settings)
|
|
├── 🔧 gradle.properties (Gradle properties)
|
|
├── 📜 gradlew & gradlew.bat (Gradle wrappers)
|
|
├── 📄 local.properties (Local SDK configuration)
|
|
│
|
|
├── gradle/
|
|
│ ├── wrapper/
|
|
│ │ ├── gradle-wrapper.jar
|
|
│ │ └── gradle-wrapper.properties
|
|
│ └── libs.versions.toml (Dependency versions)
|
|
│
|
|
└── app/
|
|
├── 🔧 build.gradle.kts ✨ (App-level build config)
|
|
├── 📄 proguard-rules.pro (Proguard configuration)
|
|
│
|
|
├── src/
|
|
│ ├── main/
|
|
│ │ ├── 📄 AndroidManifest.xml ✨ (App manifest & permissions)
|
|
│ │ │
|
|
│ │ ├── java/
|
|
│ │ │ └── id/ac/ubharajaya/sistemakademik/
|
|
│ │ │ ├── 📄 MainActivity.kt ✨ (Main app file)
|
|
│ │ │ │ ├── Util Functions
|
|
│ │ │ │ │ ├── bitmapToBase64()
|
|
│ │ │ │ │ ├── obfuscateCoordinates()
|
|
│ │ │ │ │ ├── calculateDistance()
|
|
│ │ │ │ │ └── isWithinAbsensiRadius()
|
|
│ │ │ │ │
|
|
│ │ │ │ ├── MainActivity Class
|
|
│ │ │ │ │ ├── onCreate()
|
|
│ │ │ │ │ └── Navigation Logic
|
|
│ │ │ │ │
|
|
│ │ │ │ ├── kirimKeN8n() ✨ (Webhook function)
|
|
│ │ │ │ │
|
|
│ │ │ │ ├── @Composables
|
|
│ │ │ │ │ ├── LoginScreen()
|
|
│ │ │ │ │ ├── RegisterScreen()
|
|
│ │ │ │ │ ├── AbsensiScreen() ✨
|
|
│ │ │ │ │ ├── HistoryScreen() ✨
|
|
│ │ │ │ │ └── AttendanceCard() ✨
|
|
│ │ │ │
|
|
│ │ │ └── 📄 DatabaseHelper.kt ✨ (Database management)
|
|
│ │ │ ├── onCreate() - Create tables
|
|
│ │ │ ├── onUpgrade() - DB migration
|
|
│ │ │ │
|
|
│ │ │ ├── User Functions
|
|
│ │ │ │ ├── addUser()
|
|
│ │ │ │ ├── checkUser()
|
|
│ │ │ │ └── getUserName()
|
|
│ │ │ │
|
|
│ │ │ ├── Attendance Functions ✨
|
|
│ │ │ │ ├── addAttendanceRecord()
|
|
│ │ │ │ └── getAttendanceHistory()
|
|
│ │ │ │
|
|
│ │ │ ├── Database Schema
|
|
│ │ │ │ ├── TABLE_USERS
|
|
│ │ │ │ └── TABLE_ATTENDANCE ✨
|
|
│ │ │ │
|
|
│ │ │ └── AttendanceRecord Data Class ✨
|
|
│ │ │
|
|
│ │ ├── res/
|
|
│ │ │ ├── drawable/ (App icons & images)
|
|
│ │ │ ├── layout/ (XML layouts)
|
|
│ │ │ ├── values/
|
|
│ │ │ │ ├── colors.xml (App color scheme)
|
|
│ │ │ │ ├── strings.xml (String resources)
|
|
│ │ │ │ ├── themes.xml (App theme)
|
|
│ │ │ │ └── other configurations
|
|
│ │ │ ├── xml/
|
|
│ │ │ │ ├── backup_rules.xml
|
|
│ │ │ │ └── data_extraction_rules.xml
|
|
│ │ │ └── ...other resources
|
|
│ │ │
|
|
│ │ └── ui/
|
|
│ │ └── theme/
|
|
│ │ ├── Color.kt
|
|
│ │ ├── Theme.kt
|
|
│ │ └── Type.kt
|
|
│ │
|
|
│ ├── androidTest/ (UI/Integration tests - empty)
|
|
│ └── test/ (Unit tests - empty)
|
|
│
|
|
└── build/ (Generated - ignore)
|
|
├── generated/
|
|
├── intermediates/
|
|
└── outputs/
|
|
|
|
Legend:
|
|
✨ = Modified or new in v1.1.0
|
|
📄 = Source code file
|
|
🔧 = Configuration file
|
|
📋 = Documentation file
|
|
📜 = Build script file
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Code Statistics
|
|
|
|
### Modified Files Summary
|
|
|
|
#### MainActivity.kt
|
|
```
|
|
Total Lines: 611
|
|
Added: ~350 lines (57%)
|
|
Components:
|
|
- 4 Utility functions (new)
|
|
- 5 @Composable screens (1 new + 1 enhanced)
|
|
- 1 Data class reference
|
|
- 50+ state management vars
|
|
- 3 activity lifecycle methods
|
|
```
|
|
|
|
#### DatabaseHelper.kt
|
|
```
|
|
Total Lines: 133
|
|
Added: ~65 lines (49%)
|
|
Components:
|
|
- 2 Database tables (1 new)
|
|
- 6 Database functions (2 new)
|
|
- 1 Data class (new)
|
|
- 2 Database migration handlers
|
|
```
|
|
|
|
#### build.gradle.kts
|
|
```
|
|
Total Lines: 66
|
|
Added: 1 dependency line (2%)
|
|
Components:
|
|
- 14 total dependencies
|
|
- 1 new: material-icons-extended
|
|
```
|
|
|
|
---
|
|
|
|
## 🗂️ File Categories
|
|
|
|
### Core Application Files
|
|
- `MainActivity.kt` - Main app logic & UI
|
|
- `DatabaseHelper.kt` - Database operations
|
|
- `AndroidManifest.xml` - App configuration & permissions
|
|
|
|
### Build & Configuration Files
|
|
- `build.gradle.kts` (app & project level)
|
|
- `settings.gradle.kts`
|
|
- `gradle.properties`
|
|
- `local.properties`
|
|
- `gradle/libs.versions.toml`
|
|
|
|
### Resource Files
|
|
- `res/values/*.xml` - Colors, strings, themes
|
|
- `res/drawable/` - Icons & images
|
|
- `res/layout/` - XML layouts (if any)
|
|
- `res/xml/` - Backup & data extraction rules
|
|
|
|
### Documentation Files (NEW)
|
|
- `DEVELOPMENT_GUIDE.md` - 650+ lines
|
|
- `CHANGELOG.md` - 400+ lines
|
|
- `IMPLEMENTATION_NOTES.md` - 500+ lines
|
|
- `IMPLEMENTATION_SUMMARY.md` - 400+ lines
|
|
- `QUICK_REFERENCE.md` - 300+ lines
|
|
- `PROJECT_STRUCTURE.md` - This file
|
|
|
|
---
|
|
|
|
## 📦 Dependency Tree
|
|
|
|
```
|
|
App Dependencies:
|
|
├── Kotlin & Android Core
|
|
│ ├── androidx.core:core-ktx
|
|
│ ├── androidx.lifecycle:lifecycle-runtime-ktx
|
|
│ └── androidx.activity:activity-compose
|
|
│
|
|
├── Compose Framework
|
|
│ ├── androidx.compose.ui:ui
|
|
│ ├── androidx.compose.ui:ui-graphics
|
|
│ ├── androidx.compose.ui:ui-tooling-preview
|
|
│ ├── androidx.compose.material3:material3
|
|
│ ├── androidx.compose.material:material-icons-extended ✨
|
|
│ └── platform(androidx.compose.bom)
|
|
│
|
|
├── Google Services
|
|
│ └── com.google.android.gms:play-services-location
|
|
│
|
|
└── Testing (included but not used)
|
|
├── junit
|
|
├── androidx.test.ext:junit
|
|
└── androidx.test.espresso:espresso-core
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Data Flow Through Files
|
|
|
|
```
|
|
USER INPUT
|
|
↓
|
|
MainActivity.kt
|
|
├─ LoginScreen() / RegisterScreen() → DatabaseHelper.addUser(), checkUser()
|
|
└─ AbsensiScreen()
|
|
├─ Location API → calculateDistance(), isWithinAbsensiRadius()
|
|
├─ Camera Intent → bitmapToBase64()
|
|
├─ kirimKeN8n()
|
|
│ ├─ DatabaseHelper.addAttendanceRecord()
|
|
│ └─ Webhook POST
|
|
└─ HistoryScreen()
|
|
└─ DatabaseHelper.getAttendanceHistory()
|
|
└─ AttendanceCard() display
|
|
```
|
|
|
|
---
|
|
|
|
## 💾 Database Schema Location
|
|
|
|
```
|
|
DatabaseHelper.kt:
|
|
|
|
Tables Definition (onCreate):
|
|
├── users
|
|
│ ├── id (INT PRIMARY KEY AUTOINCREMENT)
|
|
│ ├── username (TEXT)
|
|
│ ├── npm (TEXT UNIQUE)
|
|
│ └── password (TEXT)
|
|
│
|
|
└── attendance ✨
|
|
├── id (INT PRIMARY KEY AUTOINCREMENT)
|
|
├── npm (TEXT FOREIGN KEY)
|
|
├── timestamp (INT)
|
|
├── latitude (REAL)
|
|
├── longitude (REAL)
|
|
└── status (TEXT)
|
|
|
|
Query Methods:
|
|
├── addAttendanceRecord() - INSERT
|
|
└── getAttendanceHistory() - SELECT with ORDER BY
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Code Organization Principles
|
|
|
|
### Separation of Concerns
|
|
```
|
|
UI Layer (Composables)
|
|
↓
|
|
Business Logic Layer (Functions)
|
|
↓
|
|
Data Access Layer (DatabaseHelper)
|
|
↓
|
|
Data Layer (SQLite Database)
|
|
```
|
|
|
|
### Module Organization
|
|
```
|
|
MainActivity.kt:
|
|
├── UTIL SECTION (Helper functions)
|
|
├── ACTIVITY SECTION (Main activity)
|
|
├── SCREEN SECTIONS (UI composables)
|
|
└── COMPONENT SECTIONS (Reusable components)
|
|
|
|
DatabaseHelper.kt:
|
|
├── COMPANION CONSTANTS
|
|
├── DATABASE SCHEMA (onCreate)
|
|
├── MIGRATION LOGIC (onUpgrade)
|
|
├── USER OPERATIONS
|
|
├── ATTENDANCE OPERATIONS ✨
|
|
└── DATA CLASSES
|
|
```
|
|
|
|
---
|
|
|
|
## 🔐 Permissions Configuration
|
|
|
|
### AndroidManifest.xml
|
|
```xml
|
|
<uses-permission android:name="android.permission.INTERNET"/>
|
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
|
<uses-permission android:name="android.permission.CAMERA"/>
|
|
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
|
```
|
|
|
|
### Runtime Request (in MainActivity.kt)
|
|
```kotlin
|
|
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission())
|
|
├── ACCESS_FINE_LOCATION
|
|
└── CAMERA
|
|
```
|
|
|
|
---
|
|
|
|
## 📱 Screen Navigation Structure
|
|
|
|
### Navigation State Machine
|
|
```
|
|
MainActivity.onCreate()
|
|
├─ setContent {
|
|
│ ├─ currentScreen: String
|
|
│ │ ├── "login" → LoginScreen()
|
|
│ │ ├── "register" → RegisterScreen()
|
|
│ │ ├── "home" → AbsensiScreen()
|
|
│ │ └── "history" → HistoryScreen()
|
|
│ │
|
|
│ └─ Navigation Callbacks
|
|
│ ├─ onLoginSuccess()
|
|
│ ├─ onNavigateToRegister()
|
|
│ ├─ onLogout()
|
|
│ └─ onNavigateToHistory() ✨
|
|
```
|
|
|
|
---
|
|
|
|
## ✨ New Features by File
|
|
|
|
### MainActivity.kt Additions
|
|
```
|
|
UTIL FUNCTIONS:
|
|
├── obfuscateCoordinates() ✨
|
|
├── calculateDistance() ✨
|
|
└── isWithinAbsensiRadius() ✨
|
|
|
|
UPDATED FUNCTIONS:
|
|
├── kirimKeN8n() - with validation ✨
|
|
├── AbsensiScreen() - new params ✨
|
|
└── onCreate() - new navigation ✨
|
|
|
|
NEW SCREENS:
|
|
├── HistoryScreen() ✨
|
|
└── AttendanceCard() ✨
|
|
```
|
|
|
|
### DatabaseHelper.kt Additions
|
|
```
|
|
DATABASE:
|
|
├── TABLE_ATTENDANCE ✨
|
|
├── DATABASE_VERSION → 2 ✨
|
|
└── onUpgrade() migration ✨
|
|
|
|
FUNCTIONS:
|
|
├── addAttendanceRecord() ✨
|
|
└── getAttendanceHistory() ✨
|
|
|
|
DATA CLASSES:
|
|
└── AttendanceRecord ✨
|
|
```
|
|
|
|
### build.gradle.kts Additions
|
|
```
|
|
DEPENDENCIES:
|
|
└── material-icons-extended:1.6.0 ✨
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Lines of Code Summary
|
|
|
|
| Component | Lines | Status |
|
|
|-----------|-------|--------|
|
|
| MainActivity.kt | 611 | Modified |
|
|
| DatabaseHelper.kt | 133 | Modified |
|
|
| build.gradle.kts | 66 | Modified |
|
|
| AndroidManifest.xml | 35 | Unchanged |
|
|
| Total Code | 845 | - |
|
|
| Documentation | 2,200+ | New |
|
|
|
|
---
|
|
|
|
## 🔍 File Cross-References
|
|
|
|
### Key Relationships
|
|
```
|
|
MainActivity.kt
|
|
├─ imports DatabaseHelper
|
|
├─ imports Material Design 3
|
|
├─ uses Compose Foundation
|
|
└─ calls Google Location Services
|
|
|
|
DatabaseHelper.kt
|
|
├─ extends SQLiteOpenHelper
|
|
├─ defines AttendanceRecord
|
|
└─ no external dependencies
|
|
|
|
build.gradle.kts
|
|
├─ imports from gradle/libs.versions.toml
|
|
├─ configures app namespace
|
|
└─ defines all dependencies
|
|
|
|
AndroidManifest.xml
|
|
├─ declares MainActivity
|
|
├─ lists all permissions
|
|
└─ sets app theme & icon
|
|
```
|
|
|
|
---
|
|
|
|
## 🎬 Execution Flow
|
|
|
|
```
|
|
APP STARTUP
|
|
└─ MainActivity.onCreate()
|
|
├─ DatabaseHelper initialized
|
|
├─ UI composed with Jetpack Compose
|
|
├─ Navigation state set to "login"
|
|
└─ User sees LoginScreen()
|
|
|
|
USER LOGIN
|
|
└─ LoginScreen() button click
|
|
├─ DatabaseHelper.checkUser()
|
|
├─ If valid:
|
|
│ ├─ Set navigationState = "home"
|
|
│ └─ Show AbsensiScreen()
|
|
└─ If invalid:
|
|
└─ Show Toast error
|
|
|
|
USER ABSENSI
|
|
└─ AbsensiScreen() "Kirim Absensi" button
|
|
├─ Validate inputs (location, photo)
|
|
├─ kirimKeN8n() called
|
|
│ ├─ Validate radius: isWithinAbsensiRadius()
|
|
│ ├─ Save locally: DatabaseHelper.addAttendanceRecord()
|
|
│ ├─ Send to webhook via HTTPS POST
|
|
│ └─ Show feedback Toast
|
|
└─ Data now in database
|
|
|
|
USER HISTORY
|
|
└─ AbsensiScreen() "Lihat Riwayat" button
|
|
├─ Set navigationState = "history"
|
|
├─ HistoryScreen() loads
|
|
│ ├─ Call DatabaseHelper.getAttendanceHistory()
|
|
│ ├─ Map to List<AttendanceRecord>
|
|
│ └─ Render AttendanceCard() items
|
|
└─ User sees list with status
|
|
```
|
|
|
|
---
|
|
|
|
**Last Updated**: 14 January 2026
|
|
**Version**: 1.1.0
|
|
**Status**: ✅ Complete & Documented
|
|
|