Giới thiệu dự án

Trong kỷ nguyên bùng nổ dữ liệu số hóa và giải trí trực tuyến, người dùng toàn cầu phải đối mặt với hiện tượng "quá tải thông tin" (Information Overload). Theo thống kê từ Statista, thị trường Video-on-Demand (VOD) toàn cầu đạt quy mô hơn 80 tỷ USD với hàng triệu nội dung phát hành mỗi năm. Người dùng trung bình mất từ 10 đến 15 phút mỗi phiên chỉ để tìm kiếm một bộ phim phù hợp. Nếu không có hệ thống hỗ trợ ra quyết định thông minh, trải nghiệm người dùng (UX) sẽ bị suy giảm nghiêm trọng, dẫn đến tỷ lệ rời bỏ nền tảng (churn rate) tăng cao.

Đồ án tốt nghiệp "Phát triển ứng dụng di động gợi ý phim cho người dùng" (A Mobile Application for Personalized Movie Recommendations) do sinh viên Vũ Cao Nguyên thực hiện dưới sự hướng dẫn của ThS. Phạm Thế Sơn tại Trường Đại học Công nghệ Thông tin – ĐHQG TP.HCM (2021) tập trung giải quyết bài toán cốt lõi: Cá nhân hóa trải nghiệm xem phim trên thiết bị di động, đặc biệt là xử lý triệt để bài toán khởi đầu lạnh (Cold Start Problem) cho người dùng mới dựa trên nền tảng kế thừa mô hình phân rã ma trận từ khóa luận tiền nhiệm.

                  +--------------------------------------------------+
                  |         NGƯỜI DÙNG ỨNG DỤNG DI ĐỘNG             |
                  +--------------------------------------------------+
                                           |
                                [Phân loại User]
                                           |
             +-----------------------------+-----------------------------+
             |                                                           |
    [Người dùng cũ (Đã có Rating)]                              [Người dùng mới (Cold Start)]
             |                                                           |
  [Mô hình SVD Matrix Factorization]                   +------------------+------------------+
             |                                         |                                     |
[Top-N Personalized Recommendations]          [Có chọn Thể loại yêu thích]        [Không chọn Thể loại]
                                                       |                                     |
                                            [Lọc Hybrid: Genre Match]           [Lọc Content: Popularity]
                                            [+ Điểm IMDb Vote Average]          [+ Phim mới phát hành]

Mục tiêu dự án

  1. Thiết kế & hoàn thiện kiến trúc ứng dụng di động đa nền tảng bằng Flutter Framework, đảm bảo giao diện trực quan, mượt mà trên hệ điều hành Android và iOS.
  2. Xây dựng hệ thống Web API Backend hiệu năng cao dựa trên Django Rest Framework và cơ sở dữ liệu quan hệ PostgreSQL 13.
  3. Giải quyết bài toán Cold Start cho người dùng mới đăng ký qua 2 kịch bản: Gợi ý theo thể loại yêu thích kết hợp thứ hạng đánh giá (vote_average, popularity) và gợi ý ngẫu nhiên/nội dung tương đồng (Content-based exploration).
  4. Tích hợp mô hình Singular Value Decomposition (SVD) kế thừa từ bộ dữ liệu chuẩn MovieLens để phân phối danh sách phim cá nhân hóa cho người dùng cũ với độ trễ phản hồi API dưới 200ms.
  5. Cung cấp đầy đủ các tính năng tương tác mạng xã hội thu nhỏ: Đăng ký/đăng nhập, đánh giá thang điểm 1-5 sao, bình luận thời gian thực, xem trailer và tìm kiếm đa tiêu chí.

Phạm vi và giới hạn hệ thống

  • Phạm vi dữ liệu: Khai thác tập dữ liệu MovieLens (MovieLens Dataset) kết hợp siêu dữ liệu phim mở rộng từ TMDb/IMDb (poster, diễn viên, đạo diễn, tóm tắt, trailer).
  • Phạm vi kỹ thuật: Triển khai ứng dụng di động Client (Flutter 2.2 / Dart 2.13) giao tiếp với Server (Django 3.2 LTS / Python 3.8) thông qua giao thức RESTful API chuẩn JSON.
  • Giới hạn: Hệ thống tập trung vào khâu phân tích dữ liệu, giới thiệu tóm tắt và xem trailer qua URL; không lưu trữ và streaming trực tiếp toàn bộ luồng video gốc (full-length video streaming) do giới hạn hạ tầng máy chủ cục bộ.

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Khảo sát thực tế các ứng dụng giải trí và cơ sở dữ liệu phim hàng đầu hiện nay cho thấy bức tranh phân hóa rõ rệt về tính năng và kiến trúc:

Tiêu chí iTunes Store (Apple) IMDb (Amazon) Galaxy Play (Việt Nam) Hệ thống Đề tài
Nền tảng iOS, iPadOS, macOS, Windows Android, iOS, Web Android, iOS, SmartTV Android, iOS (Cross-platform)
Gợi ý phim Dựa trên lịch sử mua/thuê Phim tương tự, bảng xếp hạng Danh mục biên tập thủ công Mô hình Hybrid: SVD + Content/Cold-Start
Cơ chế Cold Start Giới hạn (Dựa trên Trending chung) Bảng xếp hạng Popularity Phim Hot/Mới phát hành Phân luồng 3 nhánh theo User Profile
Chi phí/Bản quyền Trả phí từng phim/Thuê Miễn phí (Quảng cáo/Dữ liệu) Thuê bao tháng (SVOD/TVOD) Nghiên cứu học thuật / Open Source
Tương tác xã hội Đánh giá & Review Đánh giá 10 sao, Review, Trivia Đánh giá sao đơn giản Đánh giá 5 sao (Upsert), Bình luận

Phân tích yêu cầu người dùng (MoSCoW)

  • Must have (Bắt buộc): Xác thực người dùng (Đăng ký/Đăng nhập), Động cơ gợi ý phân luồng (SVD cho User cũ, Genre-based cho User mới), Màn hình chi tiết phim, Gửi đánh giá 1-5 sao, Xem trailer.
  • Should have (Nên có): Tìm kiếm phim theo từ khóa (độ dài ký tự $> 2$), Xem danh sách phim theo diễn viên và thể loại, Hệ thống bình luận thời gian thực.
  • Could have (Có thể có): Đăng nhập bên thứ ba (Google/Facebook OAuth2), Tùy chỉnh danh sách yêu thích cá nhân hóa.
  • Won't have (Chưa hỗ trợ đợt này): Phát video trực tuyến chất lượng 4K adaptive streaming, Mua vé xem phim rạp offline.

Thiết kế hệ thống

Kiến trúc hệ thống (System Architecture)

Hệ thống tuân thủ kiến trúc phân tầng Client-Server hiện đại:

  • Presentation Layer (Mobile App): Xây dựng trên Flutter, sử dụng kiến trúc State Management theo luồng dữ liệu đơn hướng (Unidirectional Data Flow), đảm bảo phân tách hoàn toàn giữa UI Widget và Data Provider.
  • Application Layer (Django REST Backend): Thiết kế theo mô hình MVC/MVT, tiếp nhận HTTP Request, xử lý xác thực, thực hiện Serialization/Deserialization dữ liệu JSON và định tuyến luồng thuật toán gợi ý.
  • Persistence Layer (PostgreSQL Database): Cơ sở dữ liệu quan hệ tối ưu hóa các bảng liên kết customer, movie, rating, comment, và recommended_movies.
+-------------------------------------------------------------------------+
|                        FLUTTER CLIENT LAYER                             |
|  [Authentication UI]  [Home / Recommendation UI]  [Detail & Review UI]  |
|            \                     |                     /                |
|             +--------------------+--------------------+                 |
|                                  | (HTTP JSON Requests)                 |
+----------------------------------|--------------------------------------+
                                   v
+-------------------------------------------------------------------------+
|                    DJANGO REST FRAMEWORK (BACKEND)                      |
|  +--------------------+  +--------------------+  +-------------------+  |
|  | Authentication App |  | Recommendation App |  | Movie Management  |  |
|  | (Django Auth API)  |  | (SVD / Cold-Start) |  | (CRUD & Search)   |  |
|  +--------------------+  +--------------------+  +-------------------+  |
|            \                     |                     /                |
|             +--------------------+--------------------+                 |
|                                  | (Django ORM)                         |
+----------------------------------|--------------------------------------+
                                   v
+-------------------------------------------------------------------------+
|                        POSTGRESQL DATABASE                              |
|   [customer]  <--->  [rating]  <--->  [movie]  <--->  [comment]         |
|                          |                                              |
|                          +--------->  [recommended_movies]              |
+-------------------------------------------------------------------------+

Thiết kế cơ sở dữ liệu chi tiết

Cấu trúc cơ sở dữ liệu PostgreSQL chuẩn hóa bậc 3 (3NF) với các chỉ mục quan trọng:

  1. customer: Lưu trữ user_id (PK, Serial), user_name (Unique Text), password (Hashed Text), name, email (Unique Text), birthday, gender, favorite_genres (Text lưu trữ mảng JSON).
  2. movie: Lưu trữ movie_id (PK, Integer), title, overview, genres, actor, director, vote_average (Real), vote_count (Integer), popularity (Real), poster_path, backdrop_path, release_date, runtime, budget, revenue.
  3. rating: Khóa chính phức hợp (user_id, movie_id) tham chiếu tới customermovie, rating (Real, 1.0 - 5.0), time_rating (Bigint). Đảm bảo mỗi người dùng chỉ có 1 bản ghi đánh giá duy nhất cho mỗi phim (cơ chế Update khi đánh giá lại).
  4. comment: id (PK), user_id (FK), movie_id (FK), content (Text), time_rating (Date).
  5. recommended_movies: user_id (PK, FK), recommendations (Text lưu chuỗi danh sách ID phim được tiền xử lý từ mô hình SVD).

Methodology

Đề tài áp dụng mô hình phát triển phần mềm lặp Prototyping Model kết hợp các pha quản lý rủi ro từ Spiral Model:

  • Pha 1: Khảo sát & Kế thừa (Tuần 1 - Tuần 3): Tiếp nhận mô hình SVD và tập dữ liệu từ khóa luận trước; khảo sát UX từ các nền tảng lớn (IMDb, Galaxy Play).
  • Pha 2: Phân tích & Thiết kế cơ sở dữ liệu (Tuần 4 - Tuần 6): Thiết kế sơ đồ ERD, định nghĩa bảng, xây dựng chuẩn API RESTful.
  • Pha 3: Phát triển Backend API (Tuần 7 - Tuần 10): Thiết lập môi trường Django 3.2, cài đặt các app chuyên biệt (authentication, movie, rating, comment), viết Serializer và Logic gợi ý phân luồng.
  • Pha 4: Phát triển Mobile Client (Tuần 11 - Tuần 14): Xây dựng giao diện Dark Mode bằng Flutter SDK, tích hợp HTTP Client kết nối API Backend.
  • Pha 5: Tích hợp, Kiểm thử & Đánh giá (Tuần 15 - Tuần 16): Kiểm thử hộp đen (Black-box testing), đánh giá tính tương thích trên thiết bị thật và máy ảo Android.

Implementation và kết quả

Development process

1. Xây dựng Data Model và Logic Backend (Django REST Framework)

Hệ thống sử dụng ORM của Django để ánh xạ các thực thể cơ sở dữ liệu. Dưới đây là hiện thực cụ thể của các Model cốt lõi:

# movielens_api/models.py
from django.db import models

class Customer(models.Model):
    user_id = models.AutoField(primary_key=True)
    user_name = models.CharField(max_length=150, unique=True, null=False)
    password = models.CharField(max_length=255, null=False)
    name = models.CharField(max_length=255, null=False)
    email = models.EmailField(unique=True, null=False)
    address = models.TextField(blank=True, default='')
    birthday = models.DateField(null=False)
    gender = models.CharField(max_length=10, null=False)
    favorite_genres = models.TextField(null=True, blank=True)

    class Meta:
        db_table = 'customer'

class Rating(models.Model):
    user = models.ForeignKey(Customer, on_delete=models.CASCADE, db_column='user_id')
    movie_id = models.IntegerField(null=False)
    rating = models.FloatField(null=False)
    time_rating = models.BigIntegerField(null=False)

    class Meta:
        db_table = 'rating'
        unique_together = (('user', 'movie_id'),)  # Khóa phức hợp chống duplicate rating

2. Thuật toán gợi ý phân luồng (Recommendation Engine Pipeline)

Backend triển khai thuật toán định tuyến người dùng để phục vụ API gợi ý phim:

# movielens_api/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Customer, Movie, RecommendedMovies

class RecommendationView(APIView):
    def get(self, request, user_id):
        try:
            customer = Customer.objects.get(user_id=user_id)
            
            # Luồng 1: Người dùng cũ - Đã có tính toán SVD trước đó
            if RecommendedMovies.objects.filter(user_id=user_id).exists():
                rec_record = RecommendedMovies.objects.get(user_id=user_id)
                movie_ids = [int(mid) for mid in rec_record.recommendations.split(',') if mid]
                movies = Movie.objects.filter(movie_id__in=movie_ids)
                return Response({'type': 'SVD_COLLABORATIVE', 'data': MovieSerializer(movies, many=True).data})

            # Luồng 2: Người dùng mới - Có đăng ký thể loại yêu thích (Cold Start Type A)
            elif customer.favorite_genres:
                genres_list = [g.strip() for g in customer.favorite_genres.split(',')]
                # Lọc phim thuộc thể loại yêu thích, sắp xếp theo vote_average và popularity
                movies = Movie.objects.filter(genres__icontains=genres_list[0])\
                                      .order_by('-vote_average', '-popularity')[:20]
                return Response({'type': 'COLD_START_GENRE_HYBRID', 'data': MovieSerializer(movies, many=True).data})

            # Luồng 3: Người dùng mới - Không chọn thể loại (Cold Start Type B)
            else:
                movies = Movie.objects.filter(vote_count__gte=100)\
                                      .order_by('-release_date', '-popularity')[:20]
                return Response({'type': 'COLD_START_TRENDING', 'data': MovieSerializer(movies, many=True).data})

        except Customer.DoesNotExist:
            return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

3. Tích hợp Mobile Client (Flutter Framework)

Client sử dụng thư viện http của Dart để kết nối API bất đồng bộ và render giao diện chuẩn Material Dark UI:

// lib/services/api_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/movie_model.dart';

class ApiService {
  static const String baseUrl = "http://10.0.2.2:8000/api"; // Endpoint máy ảo Android

  Future<List<Movie>> fetchRecommendedMovies(int userId) async {
    final response = await http.get(Uri.parse('$baseUrl/recommendations/$userId/'));
    
    if (response.statusCode == 200) {
      final Map<String, dynamic> data = json.decode(utf8.decode(response.bodyBytes));
      List<dynamic> list = data['data'];
      return list.map((json) => Movie.fromJson(json)).toList();
    } else {
      throw Exception('Không thể tải danh sách phim gợi ý');
    }
  }
}

Testing và validation

Kiểm thử ca sử dụng (Use Case Test Coverage)

Hệ thống đã trải qua 12 kịch bản kiểm thử toàn diện trên thiết bị thật (Xiaomi Redmi Note 8, Android 10) và máy ảo Android Emulator (Pixel 4, API Level 30):

+--------------------------------------------------------------------------------+
|                         KẾT QUẢ KIỂM THỬ USE CASE                              |
+----+-----------------------+-----------------------------+-----------+---------+
| STT| Chức năng Kiểm thử    | Điều kiện Kiểm tra          | Kỳ vọng   | Kết quả |
+----+-----------------------+-----------------------------+-----------+---------+
| 1  | Đăng ký tài khoản     | Trùng email / username      | Báo lỗi   | ĐẠT     |
| 2  | Xác thực mật khẩu     | Mật khẩu < 3 ký tự          | Chặn gửi  | ĐẠT     |
| 3  | Đăng nhập             | Sai thông tin / Đúng        | Thông báo | ĐẠT     |
| 4  | Gợi ý User SVD        | User có sẵn ma trận SVD     | Trả Top-N | ĐẠT     |
| 5  | Gợi ý Cold Start A    | User mới có favorite_genres | Trả Genre | ĐẠT     |
| 6  | Gợi ý Cold Start B    | User mới không chọn genre   | Trả Trend | ĐẠT     |
| 7  | Tìm kiếm phim         | Từ khóa >= 2 ký tự          | Trả List  | ĐẠT     |
| 8  | Đánh giá phim (1-5*)  | Tạo mới / Cập nhật lại sao  | Upsert DB | ĐẠT     |
| 9  | Thêm bình luận        | Nội dung + Icon cảm xúc     | Lưu tức thì| ĐẠT    |
| 10 | Xem Trailer           | Link YouTube / Không có     | Play/Error| ĐẠT     |
+----+-----------------------+-----------------------------+-----------+---------+

Đo lường hiệu năng kỹ thuật (Performance Benchmarks)

  • Độ trễ phản hồi API (API Response Latency): Trung bình đạt 128ms đối với các truy vấn dữ liệu thông thường và 175ms đối với API tính toán gợi ý phân luồng.
  • Tốc độ hiển thị giao diện Client: Tốc độ khung hình duy trì ổn định ở mức 60 FPS, thời gian khởi tạo ứng dụng (Cold App Launch) đạt 1.4 giây.
  • Độ chính xác dữ liệu (Data Consistency): Cơ chế ràng buộc unique_together trên cặp (user_id, movie_id) ở bảng rating đảm bảo tỷ lệ toàn vẹn dữ liệu đánh giá đạt 100%, loại bỏ hoàn toàn lỗi trùng lặp khi người dùng cập nhật lại số sao.

Kết quả đạt được

  • Hoàn thành 100% các tính năng mục tiêu: Xây dựng trọn vẹn 10 màn hình giao diện chính bao gồm: Đăng nhập, Đăng ký, Trang chủ, Xem thêm danh mục, Chi tiết phim, Đánh giá, Bình luận, Tìm kiếm, Danh sách theo diễn viên/thể loại và Trang thông tin cá nhân.
  • Giải quyết thành công vấn đề Cold Start: 100% người dùng mới sau khi đăng ký đều nhận được danh sách phim gợi ý ngay lập tức mà không gặp hiện tượng màn hình trống (Empty State).

Đổi mới và đóng góp

  1. Đổi mới trong giải quyết bài toán Khởi đầu lạnh (Cold Start Solution): Khóa luận tiền nhiệm chỉ dừng lại ở việc áp dụng giải thuật Singular Value Decomposition (SVD) trên tập dữ liệu tĩnh của MovieLens cho người dùng đã có lịch sử đánh giá. Đề tài này đã cải tiến bằng cách xây dựng cơ chế định tuyến động 3 nhánh tại tầng API: Tự động phân loại trạng thái người dùng (Cũ có SVD vs Mới có Thể loại vs Mới hoàn toàn) để phối hợp linh hoạt giữa Collaborative Filtering và Content-Based Filtering.

  2. Kiến trúc phân tách rõ ràng (Decoupled Client-Server Architecture): Thay vì xây dựng ứng dụng nguyên khối (Monolith), đề tài tách biệt hoàn toàn Client di động (Flutter) và Server xử lý (Django REST Framework). Điều này giúp tối ưu hóa băng thông mạng lên đến 45% nhờ định dạng JSON tinh gọn và cho phép mở rộng sang phiên bản Web hoặc iOS trong tương lai mà không cần viết lại Logic nghiệp vụ.

  3. Cơ chế cập nhật đánh giá thông minh (Idempotent Upsert Rating): Hiện thực hóa việc tự động tính toán lại điểm trung bình (vote_average) và số lượt đánh giá (vote_count) theo thời gian thực mỗi khi người dùng gửi hoặc sửa đổi số sao, loại bỏ hoàn toàn hiện tượng bất đồng bộ dữ liệu.


Ứng dụng thực tế và triển khai

Kịch bản sử dụng thực tế (Real-world Use Cases)

  • Nền tảng VOD trực tuyến quy mô vừa và nhỏ: Triển khai làm cổng thông tin giới thiệu và gợi ý nội dung thông minh cho các rạp chiếu phim hoặc đơn vị phân phối nội dung số.
  • Hệ thống đánh giá và mạng xã hội điện ảnh: Đóng vai trò là cộng đồng đánh giá phim độc lập tương tự IMDb thu nhỏ cho thị trường bản địa.

Yêu cầu triển khai hệ thống (System & Deployment Requirements)

  • Hạ tầng Server:
    • Hệ điều hành: Ubuntu Server 20.04 LTS hoặc CentOS 8.
    • Python Environment: Python 3.8.10, Django 3.2 LTS, Django Rest Framework 3.12.4, Gunicorn / Nginx Reverse Proxy.
    • Database: PostgreSQL 13.3 với cấu hình tối thiểu 2GB RAM, 1 vCPU.
  • Yêu cầu Thiết bị Client:
    • Android 5.0 (Lollipop - API Level 21) trở lên; RAM tối thiểu 2GB; Dung lượng lưu trữ trống 50MB.

Lộ trình nâng cấp và mở rộng (Implementation Roadmap)


Hạn chế và hướng phát triển

Hạn chế kỹ thuật hiện tại

  • Mô hình SVD chạy Offline: Danh sách gợi ý cho người dùng cũ vẫn phụ thuộc vào việc tiền tính toán (Pre-computed) theo mẻ (Batch processing), chưa cập nhật tức thì (Online Incremental Learning) ngay sau khi người dùng thực hiện một lượt đánh giá mới.
  • Nguồn tài nguyên đa phương tiện: Ứng dụng mới chỉ phát trailer thông qua nhúng liên kết ngoài (YouTube/TMDb API), chưa có hệ thống Media Server riêng để phân phối luồng video thích ứng.

Hướng nghiên cứu và phát triển tiếp theo

  • Nghiên cứu ứng dụng các mô hình học sâu tiên tiến (Deep Learning for Recommendation) như Neural Collaborative Filtering (NCF) hoặc Graph Neural Networks (GNN) để khai thác sâu hơn mối quan hệ phi tuyến tính giữa người dùng và phim.
  • Xây dựng hệ thống Logging hành vi người dùng (thời gian xem, hành động cuộn trang, lượt click) để cung cấp dữ liệu đầu vào cho giải thuật gợi ý ngữ cảnh (Context-Aware Recommendation).

Đối tượng hưởng lợi

  • Sinh viên & Học viên CNTT: Nắm vững quy trình hoàn chỉnh từ nghiên cứu thuật toán Machine Learning đến triển khai ứng dụng thực tế trên Flutter và Django REST Framework.
  • Lập trình viên Mobile/Backend: Tham khảo mô hình phân lớp chuẩn mực, cách xử lý bài toán Cold Start trong Recommendation System và phương pháp thiết kế RESTful API an toàn.
  • Doanh nghiệp vừa và nhỏ (SMEs): Có được giải pháp tham khảo kiến trúc tối ưu chi phí, khả năng tái sử dụng cao để tích hợp module gợi ý sản phẩm vào hệ thống thương mại điện tử hoặc giải trí số.
  • Nhà nghiên cứu Khoa học dữ liệu: Cung cấp case-study thực nghiệm về việc chuyển đổi mô hình phân rã ma trận từ lý thuyết học thuật sang ứng dụng tương tác người dùng thời gian thực.

Câu hỏi thường gặp

1. Yêu cầu phần cứng và phần mềm tối thiểu để tự triển khai hệ thống là gì?

Để triển khai Backend, máy chủ cần cài đặt Python 3.8+, PostgreSQL 13+ và tối thiểu 2GB RAM. Phía Client yêu cầu Flutter SDK 2.2+ và Android SDK tương ứng với Android 5.0 trở lên.

2. Hệ thống giải quyết bài toán Cold Start cho người dùng mới như thế nào?

Hệ thống chia làm 2 nhánh: Nếu người dùng chọn thể loại yêu thích lúc đăng ký, Backend sẽ lọc các bộ phim thuộc thể loại đó có điểm số vote_averagepopularity cao nhất. Nếu không chọn, hệ thống sẽ đề xuất danh sách các bộ phim mới phát hành kết hợp nội dung nổi bật nhất toàn hệ thống.

3. Tại sao lại chọn mô hình SVD kết hợp Django REST và Flutter?

Mô hình SVD mang lại độ chính xác cao trong bài toán Collaborative Filtering. Django REST Framework cung cấp khả năng tạo API nhanh, an toàn, hỗ trợ ORM mạnh mẽ; trong khi Flutter giúp tối ưu hóa chi phí phát triển với một mã nguồn duy nhất (Single Codebase) chạy mượt mà trên cả Android và iOS.

4. Dữ liệu đánh giá của người dùng có bị ghi đè hay trùng lặp không?

Không. Nhờ thiết lập ràng buộc unique_together = (('user', 'movie_id'),) trong Django Model, mỗi người dùng chỉ có một bản ghi đánh giá duy nhất cho mỗi phim. Mọi lượt đánh giá sau sẽ tự động trở thành thao tác cập nhật (Update) và làm mới lại thống kê trung bình của bộ phim.

5. Chi phí vận hành và khả năng mở rộng của hệ thống ra sao?

Kiến trúc tách rời (Decoupled) cho phép Backend và Database có thể triển khai trên các hạ tầng đám mây dạng Container (Docker/Kubernetes) với chi phí ban đầu rất thấp (chỉ từ 5-10 USD/tháng trên DigitalOcean/AWS) và mở rộng linh hoạt theo tải lượng người dùng.


Kết luận

Khóa luận tốt nghiệp "Phát triển ứng dụng di động gợi ý phim cho người dùng" của tác giả Vũ Cao Nguyên đã hoàn thành xuất sắc các mục tiêu đề ra: Chuyển hóa thành công mô hình gợi ý lý thuyết thành một sản phẩm ứng dụng di động hoàn chỉnh, có tính ứng dụng thực tiễn cao. Bằng việc kết hợp sức mạnh giao diện của Flutter, nền tảng API vững chắc của Django REST Framework và giải pháp linh hoạt cho bài toán Cold Start, đề tài đã đóng góp một giải pháp tham khảo giá trị cho các hệ thống gợi ý nội dung số hóa hiện đại. Đây là bước đệm quan trọng để tiếp tục phát triển các hệ thống gợi ý thông minh thế hệ mới ứng dụng Trí tuệ nhân tạo toàn diện.