Skip to content

219181527/student-assignment-tracker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

97 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Student Assignment Tracker

A backend system for managing academic coursework β€” built in Python, designed around clean architecture principles, and structured for extensibility.


πŸ“Œ Overview

The Student Assignment Tracker solves a common problem in higher education: students losing track of deadlines across multiple courses, and lecturers lacking a structured platform for distributing and managing coursework.

The system provides:

  • A centralised interface for students to view, filter, and monitor assignment deadlines across all enrolled courses
  • A management layer for lecturers to create, publish, update, and close assignments
  • Automated notifications triggered by deadlines, submissions, and grade releases
  • A structured submission and grading pipeline with full status tracking

🌍 Domain

Education Technology (EdTech)

The system occupies the middle ground between overengineered institutional LMS platforms and informal tools like WhatsApp groups β€” lightweight, role-based, and deadline-focused.


🎯 Goals

Goal Description
Assignment Management Lecturers can create, publish, update, and close assignments per course
Deadline Visibility Students see all upcoming deadlines across enrolled courses in one place
Submission Tracking Students can submit work and track submission and grading status
Notifications System generates alerts for deadlines, submission confirmations, and grade releases
Role-Based Access Students and lecturers see and do different things based on their role

πŸ› οΈ Tech Stack

Tool Purpose
Python 3.14 Primary implementation language
FastAPI REST API framework with auto OpenAPI docs
Uvicorn ASGI server
Pydantic v2 Request/response validation and serialisation
pytest 9.x Unit and integration testing β€” 265 tests
pytest-cov Coverage reporting
httpx HTTP client for API integration tests
Mermaid.js UML diagrams embedded in Markdown
GitHub Projects Kanban board, sprint planning, issue tracking

πŸ“ Project Structure

student-assignment-tracker/
β”‚
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── ci.yml                ← GitHub Actions CI/CD pipeline
β”‚
β”œβ”€β”€ src/                          ← Domain model classes
β”‚   β”œβ”€β”€ user.py
β”‚   β”œβ”€β”€ student.py
β”‚   β”œβ”€β”€ lecturer.py
β”‚   β”œβ”€β”€ course.py
β”‚   β”œβ”€β”€ assignment.py
β”‚   β”œβ”€β”€ submission.py
β”‚   β”œβ”€β”€ grade.py
β”‚   β”œβ”€β”€ notification.py
β”‚   └── enrollment.py
β”‚
β”œβ”€β”€ creational_patterns/          ← Object creation design patterns
β”‚   β”œβ”€β”€ simple_factory.py
β”‚   β”œβ”€β”€ factory_method.py
β”‚   β”œβ”€β”€ abstract_factory.py
β”‚   β”œβ”€β”€ builder.py
β”‚   β”œβ”€β”€ prototype.py
β”‚   └── singleton.py
β”‚
β”œβ”€β”€ repositories/                 ← Persistence layer
β”‚   β”œβ”€β”€ base.py
β”‚   β”œβ”€β”€ interfaces.py
β”‚   β”œβ”€β”€ inmemory/
β”‚   β”œβ”€β”€ filesystem/
β”‚   β”œβ”€β”€ database/
β”‚   └── factory/
β”‚
β”œβ”€β”€ services/                     ← Business logic layer
β”‚   β”œβ”€β”€ base.py
β”‚   β”œβ”€β”€ user_service.py
β”‚   β”œβ”€β”€ assignment_service.py
β”‚   └── submission_service.py
β”‚
β”œβ”€β”€ api/                          ← REST API layer (FastAPI)
β”‚   β”œβ”€β”€ main.py
β”‚   β”œβ”€β”€ schemas.py
β”‚   β”œβ”€β”€ dependencies.py
β”‚   └── routes/
β”‚       β”œβ”€β”€ users.py
β”‚       β”œβ”€β”€ assignments.py
β”‚       └── submissions.py
β”‚
β”œβ”€β”€ tests/                        ← Full test suite (395 tests)
β”‚   β”œβ”€β”€ conftest.py
β”‚   β”œβ”€β”€ test_simple_factory.py
β”‚   β”œβ”€β”€ test_factory_method.py
β”‚   β”œβ”€β”€ test_abstract_factory.py
β”‚   β”œβ”€β”€ test_builder.py
β”‚   β”œβ”€β”€ test_prototype.py
β”‚   β”œβ”€β”€ test_singleton.py
β”‚   β”œβ”€β”€ test_repository_factory.py
β”‚   β”œβ”€β”€ test_storage_backends.py
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ test_user_service.py
β”‚   β”‚   β”œβ”€β”€ test_assignment_service.py
β”‚   β”‚   └── test_submission_service.py
β”‚   └── api/
β”‚       └── test_api.py
β”‚
β”œβ”€β”€ docs/                         ← System documentation
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ openapi.yaml
β”‚   β”‚   β”œβ”€β”€ API_DOCS.md
β”‚   β”‚   β”œβ”€β”€ swagger_ui.png
β”‚   β”‚   └── swagger_ui_detail.png
β”‚   β”œβ”€β”€ export_openapi.py
β”‚   β”œβ”€β”€ DOMAIN_MODEL.md
β”‚   β”œβ”€β”€ CLASS_DIAGRAM.md
β”‚   β”œβ”€β”€ state_diagrams/
β”‚   └── activity_diagrams/
β”‚
β”œβ”€β”€ screenshots/
β”‚   β”œβ”€β”€ kanban_board.png
β”‚   β”œβ”€β”€ branch_protection.png
β”‚   β”œβ”€β”€ ci_passing.png
β”‚   β”œβ”€β”€ cd_passing.png
β”‚   β”œβ”€β”€ artifact.png
β”‚   β”œβ”€β”€ release.png
β”‚   └── pr_blocked.png
β”‚
β”œβ”€β”€ requirements.txt              ← Pinned dependencies for CI
β”œβ”€β”€ pytest.ini
β”œβ”€β”€ PROTECTION.md                 ← Branch protection documentation
β”œβ”€β”€ CHANGELOG.md
└── README.md

🀝 Contributing

Contributions are welcome! This project is open to all skill levels.

Quick Start for Contributors

  1. Fork this repository
  2. Pick an issue labelled good-first-issue from the Issues tab
  3. Clone your fork and create a feature branch from dev
  4. Write code and tests β€” all PRs must maintain 80%+ coverage
  5. Submit a PR with a clear description linking the issue

See CONTRIBUTING.md for full setup instructions, coding standards, and the PR workflow.

Features Open for Contribution

Feature Complexity Label Description
CourseService + endpoints Low good-first-issue Expose course CRUD via REST API
Enrollment API endpoint Low good-first-issue POST /api/enrollments for student enrollment
Increase test coverage Low good-first-issue lecturer.py at 64%, enrollment.py at 74%
Pagination on list endpoints Medium good-first-issue Add ?page= and ?limit= to all GET list routes
JWT Authentication Medium good-first-issue Replace role-based ID passing with JWT tokens
Email notifications Medium feature-request Integrate SendGrid for deadline/grade alerts
SQLite database backend Medium feature-request Implement database stubs in repositories/database/
React student dashboard High feature-request Frontend for deadline tracking and submissions
Docker support Medium feature-request Dockerfile and docker-compose.yml

See ROADMAP.md for the full list of planned features.


This project uses GitHub Actions for automated testing and releases.

How It Works

Push to any branch
      ↓
CI: Run 395 tests (pytest)
      ↓
  Tests pass? ──No──→ PR blocked from merging
      ↓ Yes
Merge to main approved
      ↓
CD: Build Python wheel
      ↓
GitHub Release created automatically (v1.0.x)

Workflow File

.github/workflows/ci.yml

Job Trigger What it does
Run Tests Every push, every PR Runs 395 tests, uploads results + coverage as artifacts
Build Release Artifact Merge to main only Builds Python wheel, creates GitHub Release

Running Tests Locally

# Install dependencies
pip install -r requirements.txt

# Run full test suite
pytest tests/ -v

# With coverage report
pytest tests/ -v --cov=src --cov=creational_patterns --cov=repositories --cov=services --cov=api --cov-report=term-missing

Branch Protection

The main branch is protected:

  • All changes must go through a pull request
  • CI must pass before merging is allowed
  • At least 1 review required
  • See PROTECTION.md for full details

Prerequisites

  • Python 3.8+
  • pip

Installation

git clone https://github.com/219181527/student-assignment-tracker.git
cd student-assignment-tracker
pip install pytest pytest-cov fastapi uvicorn httpx

Run the API

uvicorn api.main:app --reload
URL Description
http://localhost:8000/docs Swagger UI β€” interactive API explorer
http://localhost:8000/redoc ReDoc β€” clean reference documentation
http://localhost:8000/health Health check
http://localhost:8000/openapi.json Raw OpenAPI spec

Run Tests

# Full test suite
pytest tests/ -v

# With coverage report
pytest tests/ -v --cov=src --cov=creational_patterns --cov=repositories --cov=services --cov=api --cov-report=term-missing

Verify CRUD Operations

python -c "
from repositories.factory import RepositoryFactory
from src.student import Student

factory = RepositoryFactory('MEMORY')
repo = factory.get_student_repository()

s = Student('s1', 'Alice', 'alice@uni.ac.za', 'pass', 'STU001', 2)
s.register()
repo.save(s)

print(repo.find_by_id('s1'))        # Student object
print(repo.exists('s1'))            # True
print(repo.count())                 # 1

s.update_profile(name='Alice Updated')
repo.save(s)
print(repo.find_by_id('s1').name)   # Alice Updated

repo.delete('s1')
print(repo.find_by_id('s1'))        # None
"

πŸ—οΈ Architecture

Domain Layer (/src)

Nine domain classes with private attributes, typed method signatures, and enforced business rules:

Class Responsibility
User Base class β€” authentication, registration, profile management
Student Deadline tracking, assignment submission, enrollment access
Lecturer Assignment lifecycle management with ownership enforcement
Course Owns assignments (composition), tracks enrollments (aggregation)
Assignment DRAFT β†’ PUBLISHED β†’ CLOSED lifecycle, triggers notifications on publish
Submission Late detection at construction time, triggers grade notifications
Grade Score storage, percentage computation against total marks
Notification Typed alerts (DEADLINE, SUBMISSION, GRADE) with traceable source
Enrollment Resolves the Student ↔ Course many-to-many relationship

Creational Patterns (/creational_patterns)

Six design patterns applied to real domain problems:

Pattern Applied To Why
Simple Factory UserFactory Registration sends a role string β€” one factory creates Student or Lecturer without exposing subclass imports
Factory Method NotificationCreator Each trigger type builds differently-worded notifications β€” subclasses own their construction logic independently
Abstract Factory DashboardFactory Students and lecturers see incompatible views of the same data β€” factory guarantees compatible component families per role
Builder AssignmentBuilder + AssignmentDirector Assignments have 9+ configurable fields β€” builder prevents half-built objects; Director provides named templates (quiz, essay, project)
Prototype AssignmentTemplateRegistry Recurring assignments cloned from registered templates β€” mutations on clones never affect the stored original
Singleton NotificationService One global dispatcher prevents duplicate alerts β€” double-checked locking for thread safety

Service Layer (/services)

Business logic encapsulated in three service classes, each injected with a RepositoryFactory:

Service Responsibility
UserService Registration (duplicate prevention), login, profile updates
AssignmentService Full DRAFT β†’ PUBLISHED β†’ CLOSED lifecycle with ownership enforcement
SubmissionService Enrollment validation, one-submission rule, score range checks, grading

All services share a typed exception hierarchy that maps directly to HTTP status codes:

Exception HTTP Meaning
NotFoundError 404 Entity does not exist
ConflictError 409 Business rule violation
PermissionError 403 Unauthorised action
ValidationError 422 Invalid input data

REST API (/api)

Built with FastAPI. Auto-documented via Swagger UI at /docs.

25 endpoints across 3 routers:

Router Prefix Endpoints
Users /api/users Register, login, get, list, update students and lecturers
Assignments /api/assignments Create, publish, close, delete, update, list, overdue
Submissions /api/submissions Submit, grade, get, list by assignment/student

See docs/api/API_DOCS.md for the full endpoint reference.


Persistence Layer (/repositories)

A repository pattern implementation with swappable storage backends:

Repository[T, ID]              ← Generic interface (6 CRUD operations)
    └── StudentRepository      ← Entity interface (+ domain-specific finders)
            β”œβ”€β”€ InMemoryStudentRepository     ← dict / HashMap
            β”œβ”€β”€ FileSystemStudentRepository   ← JSON files
            └── DatabaseStudentRepository     ← SQL/NoSQL (pluggable)

Generic interfaces β€” save, find_by_id, find_all, delete, exists, count defined once in base.py, inherited by all nine entity repositories. Domain-specific finders (find_by_course, find_overdue, find_by_student_and_assignment) declared per entity interface.

In-memory β€” Python dict backing store. O(1) CRUD, zero setup. Default for testing and local development.

Filesystem β€” JSON file backing store. Data persists across restarts. Fully implemented for Student, Course, Lecturer, and Notification.

Database β€” Pluggable stub. All methods raise NotImplementedError with implementation guidance. To activate: install SQLAlchemy or PyMongo, implement the stub classes, switch RepositoryFactory("DATABASE"). Zero changes to domain classes or tests required.

Storage Abstraction β€” RepositoryFactory

Switching backends is a single line:

factory = RepositoryFactory("MEMORY")      # default β€” no setup required
factory = RepositoryFactory("FILESYSTEM")  # persistent JSON storage
factory = RepositoryFactory("DATABASE")    # production database

The Factory Pattern was chosen over Dependency Injection because the storage backend is an application-wide decision made at startup β€” not a per-service concern. All repositories share the same backend, making a factory simpler and equally flexible.

Consideration Factory βœ… Dependency Injection
Backend decision scope Application-wide Per-component
Configuration Single string DI container required
Complexity Low Higher
Best for One backend for all services Different backends per service

πŸ§ͺ Testing

265 tests | 74%+ coverage
Module Tests What's covered
test_simple_factory.py 13 Role creation, case-insensitivity, password hashing
test_factory_method.py 16 All three notification creators
test_abstract_factory.py 19 Component families, role compatibility
test_builder.py 22 Attribute setting, chaining, Director templates
test_prototype.py 15 Clone independence, registry isolation
test_singleton.py 16 Identity, thread safety (20 threads)
test_repository_factory.py 32 Backend routing, caching, isolation
test_storage_backends.py 39 FileSystem CRUD, JSON persistence
tests/services/test_user_service.py 21 Registration, login, profile management
tests/services/test_assignment_service.py 22 Assignment lifecycle, ownership rules
tests/services/test_submission_service.py 30 Submission, grading, score validation
tests/api/test_api.py 30 End-to-end API integration tests

πŸ“Š Project Management

Development tracked using GitHub's native tooling:

  • Issues β€” features, bugs, and enhancements with labels (feature, bug, enhancement)
  • Kanban Board β€” custom columns: Backlog, Ready, In Progress, Testing, Blocked, Done
  • Milestones β€” sprint goals with due dates
  • CHANGELOG.md β€” all notable changes documented per release

Kanban Board


πŸ“š Documentation

Document Description
System Specification Functional and non-functional requirements
System Architecture High-level architecture decisions
Stakeholder Analysis Roles, interests, and influence
Requirements FR1–FR9 with acceptance criteria
Use Cases UC1–UC9 with specifications
Domain Model Entities, relationships, business rules
Class Diagram Full UML with method signatures
Repository Class Diagram Repository layer UML
State Diagrams Lifecycle diagrams for all 8 entities
Activity Diagrams Flow diagrams for all 8 use cases

πŸ› Known Issues

Issue Description
#17 Increase test coverage on lecturer.py (64%) and enrollment.py (74%) to 90%+

πŸ‘€ Author

Mongameli Shasha GitHub: github.com/219181527

About

A system that allows students to track assignments, deadlines, and submissions while lecturers manage assignment postings.

Resources

License

Contributing

Stars

22 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages