An Android application for managing university courses, student enrollments, and grades through separate Student and Teacher workflows.
The project was developed as part of a Mobile Application Development course and focuses on modern Android development practices using Kotlin, Jetpack Compose, Room, Hilt, Coroutines, and ViewModels.
The application implements a complete local course-management workflow: users can register as students or teachers, students can enroll in compatible courses and monitor their grades, while teachers can create courses, inspect enrolled students, and assign grades.
Academic Course Manager is designed around two different user roles:
User
│
Login / Register
│
┌──────────┴──────────┐
│ │
Student Teacher
│ │
┌──────┴──────┐ ┌──────┴─────────┐
│ │ │ │
Grades Enroll My Courses New Course
│ │ │
│ │ └── Grade Students
│ │
ECTS-weighted Browse Courses
Average by Academic Level
The application uses a local Room database and a layered architecture to separate persistence, business logic, and UI components.
Users can create an account as either:
- Student
- Teacher
The registration flow dynamically adapts to the selected role.
Students also select their academic level during registration.
After authentication, the navigation system automatically redirects users to the correct interface according to their role.
Login
│
├── Student → Student Dashboard
│
└── Teacher → Teacher Dashboard
Authentication state is managed through a dedicated repository and exposed to the interface using Kotlin StateFlow.
Note: authentication is implemented locally for educational purposes and is not intended to represent a production authentication system.
Students can browse courses compatible with their academic level.
The application automatically:
- Filters courses according to the student's level
- Excludes courses the student is already enrolled in
- Displays course name
- Displays ECTS credits
- Displays academic level
- Allows enrollment directly from the interface
Enrollment information is persisted in the local database.
Students can view all courses they are enrolled in together with the grades assigned by teachers.
For every enrolled course, the application displays:
- Course name
- ECTS credits
- Grade
- Grading status
Courses that have not yet been graded are clearly marked.
The application automatically calculates the student's weighted average according to course ECTS credits.
The calculation follows:
Weighted Average =
Σ (Grade × ECTS)
─────────────────
Σ ECTS
Only courses with an assigned grade are included in the calculation.
The result is presented through a dedicated summary card and progress indicator.
Teachers can create new courses directly from their dashboard.
Each course contains:
- Course name
- Number of ECTS credits
- Academic level
- Teacher association
New courses are automatically linked to the teacher who created them.
Each teacher has access to a personalized list containing only the courses they created.
From this section, teachers can open a course and inspect the students enrolled in it.
For each course, teachers can access the list of enrolled students and assign or update their grades.
The grading workflow is:
Teacher
│
My Courses
│
Select Course
│
Enrolled Students
│
Assign / Update Grade
│
Room Database
Changes are persisted locally and automatically reflected in the student's grade dashboard.
The application uses Room as its local persistence layer.
The database contains four main entities.
Student
├── ID
├── First Name
├── Last Name
├── Date of Birth
├── Gender
├── Email
├── Password
└── Academic Level
Teacher
├── ID
├── First Name
├── Last Name
├── Email
└── Password
Teacher email addresses are constrained to be unique.
Course
├── ID
├── Name
├── ECTS
├── Academic Level
└── Teacher ID
Courses are linked to their creator through a foreign-key relationship.
The subscription entity represents the many-to-many relationship between students and courses.
Subscription
├── Student ID
├── Course ID
└── Grade
The combination of studentId and courseId is used as the primary key, preventing duplicate enrollments.
Foreign keys ensure consistency between students, courses, and subscriptions.
The application separates responsibilities across several layers.
┌──────────────────────────────┐
│ Jetpack Compose │
│ UI │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ ViewModels │
│ StateFlow / State │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ Domain / Use Cases │
│ Authentication Logic │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ SCRUD Repository │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ Room DAOs │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ SQLite / Room DB │
└──────────────────────────────┘
The repository acts as the main entry point for data access, preventing ViewModels from interacting directly with Room DAOs.
The application uses Dagger Hilt for dependency injection.
Hilt provides and manages:
- Room database
- Student DAO
- Teacher DAO
- Course DAO
- Subscription DAO
- Repository
- Authentication repository
- ViewModels
This reduces manual dependency creation and improves separation between application components.
Example dependency chain:
Room Database
│
├── StudentDao
├── TeacherDao
├── CourseDao
└── SubscribeDao
│
▼
SCRUDRepository
│
▼
ViewModels
│
▼
Compose Screens
The application makes extensive use of:
- Kotlin Coroutines
FlowStateFlow- Compose state
Room DAOs expose reactive data streams that propagate database changes through the repository and ViewModels to the user interface.
Database Change
│
▼
Room Flow
│
▼
Repository
│
▼
ViewModel
│
▼
StateFlow
│
▼
Jetpack Compose UI
This allows the interface to react automatically when courses, subscriptions, or grades change.
Navigation is implemented using Navigation Compose.
The root navigation graph manages:
Splash
│
├── Login
│
├── Register
│
├── Student Dashboard
│
├── Teacher Dashboard
│
└── Course Students / Grading
The splash route checks the current authentication session and redirects the user according to their role.
Student and teacher dashboards then provide their own role-specific navigation.
The user interface is built entirely with Jetpack Compose and Material Design components.
Main UI components include:
ScaffoldNavigationBarNavigationBarItemLazyColumnCardOutlinedTextFieldButtonDropdownMenuLinearProgressIndicator- Material 3 components
The UI is split into reusable screens and components instead of relying on a single activity.
The main technologies used in the project are:
- Kotlin
- Android SDK
- Jetpack Compose
- Material Design 3
- Room
- SQLite
- Dagger Hilt
- Kotlin Coroutines
- Flow / StateFlow
- Navigation Compose
- Android ViewModel
- Gradle / Kotlin DSL
scrudstudents/
│
├── data/
│ │
│ ├── local/
│ │ ├── AppDatabase.kt
│ │ ├── Converters.kt
│ │ │
│ │ ├── dao/
│ │ │ ├── StudentDao.kt
│ │ │ ├── TeacherDao.kt
│ │ │ ├── CourseDao.kt
│ │ │ └── SubscribeDao.kt
│ │ │
│ │ └── model/
│ │ ├── StudentEntity.kt
│ │ ├── TeacherEntity.kt
│ │ ├── CourseEntity.kt
│ │ ├── SubscribeEntity.kt
│ │ ├── Gender.kt
│ │ └── LevelCourse.kt
│ │
│ └── repository/
│ └── SCRUDRepository.kt
│
├── di/
│ ├── AppModule.kt
│ └── AuthModule.kt
│
├── domain/
│ └── usecase/
│ ├── auth/
│ └── student/
│
├── ui/
│ │
│ ├── auth/
│ │ ├── LoginScreen.kt
│ │ ├── RegisterScreen.kt
│ │ └── AuthViewModel.kt
│ │
│ ├── student/
│ │ ├── StudentHomeHost.kt
│ │ ├── StudentEnrollScreen.kt
│ │ ├── StudentGradesScreen.kt
│ │ └── ...
│ │
│ ├── teacher/
│ │ ├── TeacherHomeHost.kt
│ │ ├── MyCoursesScreen.kt
│ │ ├── TeacherNewCourseScreen.kt
│ │ ├── CourseStudentsScreen.kt
│ │ └── ...
│ │
│ ├── course/
│ ├── subscribe/
│ ├── components/
│ ├── navigation/
│ └── theme/
│
├── MainActivity.kt
└── SCRUDStudents.kt
This project provided hands-on experience with modern Android software development and application architecture.
In particular, it demonstrates:
- Development of a complete Android application in Kotlin
- Declarative UI development with Jetpack Compose
- Local relational data modelling with Room
- Foreign-key relationships and many-to-many associations
- Repository-based data access
- Role-based application flows
- Dependency injection with Dagger Hilt
- Reactive programming with Flow and StateFlow
- Kotlin Coroutines
- ViewModel-based state management
- Navigation between multiple application flows
- CRUD operations
- Form validation and user input management
- Separation between UI, domain, and data layers
The project strengthened my understanding of how to structure a non-trivial mobile application while keeping data access, business logic, navigation, and interface components separated.
The application was developed as part of a Mobile Application Development course.
The repository also contains smaller laboratory exercises used to explore Android fundamentals before developing the main course-management application.
These exercises cover topics such as:
- Android activity lifecycle
- Jetpack Compose fundamentals
- UI state
- ViewModels
- Task lists
- User interaction
- Basic Android application architecture
The main application of the repository is the scrudstudents module.
Federico Santavicca
Master's student in Engineering in Computer Science at Sapienza University of Rome.
Main areas of interest:
- Artificial Intelligence
- Software Engineering
- Machine Learning
- Mobile Development
- Generative AI
- Computer Vision