5.2 KiB
Project Specification: Personal PDF Learning Management System (LMS)
1. Project Overview
A web application that allows users to securely log in, upload PDF files to a personal gallery, and interact with those PDFs in a dedicated "Workbook" interface. The core feature is the ability to draw, highlight, and add text directly onto the PDF pages from any device (Desktop & Mobile), saving these annotations for future review.
2. Tech Stack Definition
Please use the following technologies for this project:
- Frontend: React.js (or Next.js) + Tailwind CSS.
- PDF Rendering: PDF.js (Mozilla) to render PDF pages to canvas/DOM.
- Annotation Layer: Fabric.js (overlaying the PDF to handle drawing, shapes, and text).
- Backend: FastAPI (Python) OR Express (Node.js) - Copilot: please ask me which one to start with.
- Database: PostgreSQL (using Prisma or SQLAlchemy for ORM).
- Authentication: JWT (JSON Web Tokens) with HttpOnly cookies.
- Storage: Local file system (Docker volume) for storing uploaded PDFs.
3. Core Features & Requirements
3.1. Authentication (JWT)
- User Registration and Login.
- Protect all API routes.
- Each user can only see and interact with their own uploaded PDFs.
3.2. PDF Gallery (Dashboard)
- Upload: Multi-file drag-and-drop upload.
- Display: Responsive CSS Grid displaying uploaded PDFs as cards. Include the document title and upload date.
- Action: Clicking a card opens the PDF in the "Workbook" view.
3.3. Interactive Workbook (The Core Viewer)
- Responsive UI: Must work seamlessly on mobile and desktop.
- PDF Viewer: Render the selected PDF file. Support pagination (Next/Prev page).
- Annotation Tools (Fabric.js):
- Pen tool (freehand drawing/circling).
- Highlighter tool (semi-transparent freehand or straight line).
- Text tool (click to type text).
- Mobile Touch UX (Crucial): Implement a toggle switch between two modes:
- Pan Mode: Touch and swipe will scroll/zoom the page. Canvas drawing is disabled.
- Draw/Edit Mode: Scrolling is locked. Touch events are passed to Fabric.js for drawing/annotating.
- Save Mechanism: A "Save" button that serializes the current Fabric.js canvas state into JSON and POSTs it to the backend.
- Load Mechanism: When opening a PDF, fetch the saved JSON annotation data and load it onto the Fabric.js canvas over the PDF.
4. Database Schema (Draft)
users: id, username, password_hash, created_atpdfs: id, user_id (FK), title, file_path, created_atannotations: id, pdf_id (FK), user_id (FK), page_number, canvas_data (JSON), updated_at
5. Deployment strategy
- Provide a
docker-compose.ymlto spin up the Frontend, Backend, and PostgreSQL database together.
6. Instructions for Copilot
Let's build this step-by-step to avoid context limits.
- First, analyze this spec and confirm you understand.
- Provide the database schema models (SQLAlchemy or Prisma).
- Wait for my confirmation before writing the Backend API routes.
7. CI/CD — Push lên GitHub Container Registry (GHCR)
7.1. Yêu cầu
- Docker đã cài và đang chạy
- GitHub Personal Access Token (PAT) với quyền
write:packagesvàread:packages- Tạo tại: https://github.com/settings/tokens → Generate new token (classic)
- File
.envđã được cấu hình (xem.env.example)
7.2. Cấu hình .env
Thêm các dòng sau vào file .env (file này đã được gitignore, không commit):
GITHUB_USER=<github_username_của_bạn>
GITHUB_TOKEN=<personal_access_token>
BACKEND_IMAGE=ghcr.io/<github_username>/lms-backend:latest
FRONTEND_IMAGE=ghcr.io/<github_username>/lms-frontend:latest
7.3. Build & Push lên GHCR
chmod +x push-ghcr.sh
./push-ghcr.sh
Script sẽ tự động:
- Đọc
GITHUB_USERvàGITHUB_TOKENtừ.env - Đăng nhập vào
ghcr.io - Build cả hai image (
lms-backend,lms-frontend) bằngdocker compose build - Tag và push lên GHCR
Để push với tag cụ thể (ví dụ: version):
./push-ghcr.sh v1.0.0
7.4. Deploy trên máy khác
Trên máy đích (server, VPS, máy tính khác):
# 1. Copy các file cần thiết
scp docker-compose.yml .env.example deploy.sh user@server:/opt/lms/
ssh user@server
# 2. Tạo .env từ example
cd /opt/lms
cp .env.example .env
# Điền các giá trị: POSTGRES_PASSWORD, JWT_SECRET_KEY, GITHUB_USER, GITHUB_TOKEN,
# BACKEND_IMAGE, FRONTEND_IMAGE
# 3. Chạy deploy
chmod +x deploy.sh
./deploy.sh
Script deploy.sh sẽ:
- Kiểm tra
.envhợp lệ - Đăng nhập GHCR (nếu có token)
- Pull image từ GHCR
- Khởi động toàn bộ stack:
db,backend,frontend
7.5. Kiểm tra packages trên GitHub
Sau khi push, image sẽ xuất hiện tại:
https://github.com/<github_username>?tab=packages
Lưu ý: Mặc định packages ở chế độ Private. Để máy khác pull mà không cần token, vào GitHub → Packages → tên package → Package settings → đổi visibility sang Public.
7.6. Sinh JWT Secret Key
python3 -c "import secrets; print(secrets.token_hex(32))"
Field Value username admin password Admin@12345 role admin status approved