Executive Summary

PADS (Performance Appraisal & Development System) is a fully standalone Django 5 application for managing faculty self-assessment cycles, multi-tier review workflows (Faculty → HoD → Central Team → Principal), and institutional reporting. Campus+ is a Django 3.2 monolith serving KCT students and staff with hostel, transport, biometric, court-booking, and lending modules.

The integration goal is to make PADS a native sub-system of Campus+ — accessible via a new /pads/ URL namespace, authenticated through Campus+'s existing session/SSO pipeline, and rendered inside Campus+'s sb-admin-2 sidebar layout so it feels native to staff users already familiar with the platform.

Integration Strategy at a Glance

  • Auth: Campus+ wins. PADS's custom User is replaced by a StaffProfile OneToOneField pointing at Campus+'s auth.User. PADS role flags (is_group_admin, is_inst_admin) become fields on StaffProfile.
  • Models with name clashes (Institution, Department): PADS's versions are renamed with a Pads prefix (PadsInstitution, PadsDepartment) or mapped to Campus+ equivalents where fields align.
  • URL namespace: All PADS URLs live under /pads/ with app_name pads.
  • Templates: All PADS templates are rewritten to extend Campus+'s main.html using sb-admin-2 Bootstrap 4 components. PADS's own Bootstrap 5 + HTMX stack is migrated progressively.
  • Celery: PADS Celery tasks are merged into Campus+'s existing Celery beat schedule.
  • Middleware: PADS's InstitutionContextMiddleware and AuditMiddleware are ported and appended to Campus+'s MIDDLEWARE list.
1

Feature Mapping Table

Every PADS feature is mapped to its integration approach, the Campus+ components it touches, and the effort level.

PADS Feature PADS Source Integration Approach Campus+ Touch Points Effort
Login / Logout accounts/views.pylogin_view, logout_view Drop — Campus+ already handles login (social_django + session). PADS login page is not needed. KCT_Entrance_CRM/urls.py landing view None
Dashboard (role-aware) accounts/views.pydashboard(), dashboard/index.html Adapt — Port PADS dashboard as a new /pads/ landing page. Extend main.html, replace Bootstrap 5 components with Bootstrap 4 equivalents. main.html, new template pads/dashboard.html Medium
Custom User Model accounts/models.pyUser(AbstractUser) with employee_code, is_group_admin, is_inst_admin Replace — Use Campus+'s auth.User. Move employee_code and role flags to a new PadsStaffProfile model (OneToOneField to auth.User). The existing PADS StaffProfile already covers most of this. base_app/models.py, settings.py High
Microsoft SSO (allauth) accounts/adapters.pyPADSSocialAccountAdapter Evaluate — Campus+ already has Azure AD SSO via social_django. PADS's allauth-based SSO is a duplicate. Either reuse social_django's Azure pipeline for staff sign-in or accept both pipelines coexisting (riskier). settings.py SOCIAL_AUTH pipeline High
Institution Management institutions/models.pyInstitution; institutions/middleware.py Merge/Rename — PADS Institution clashes with base_app.Institution. Port as pads_institution (or map to existing if field semantics align). Port InstitutionContextMiddleware with a pads_ prefix on session key. base_app/models.py, middleware list Medium
Staff Roster (list, filter, export) staff/views.pystaff_list, staff_export Adapt — Port views under /pads/staff/. Reuse main.html + DataTables (already in Campus+). Rename PADS Department / Designation models to avoid clash with base_app.Department. base_app.Department conflict, DataTables Medium
Staff Excel Import staff/importers.py, staff/views.pystaff_import, staff_import_validate Adapt — Port HTMX-based import UI under /pads/staff/import/. HTMX is already loaded in main.html (v1.7), so partial-response pattern works. Upgrade HTMX version to match PADS's 1.9 usage. HTMX version difference, file upload settings Medium
Assessment Management (CRUD) assessments/views.py, assessments/models.py Adapt — Port under /pads/assessments/. Assessment, Category, Criterion, CriterionField, ScoringMatrix models migrate as-is (no name conflicts). Views rewritten to extend main.html. None (no model conflicts) Medium
Criterion Targeting assessments/models.pyCriterion.matches(), Criterion.is_visible_to() Port as-is — Business logic in model methods; no framework dependency. Migrations port cleanly after model rename resolution. M2M to renamed Department/Designation Low
Faculty Self-Assessment Form submissions/views.pysubmission_fill(), submissions/fill.html Heavy Adapt — The most complex PADS template (~600 lines, heavy Alpine.js + HTMX for dynamic criterion entry). Must be rewritten using Bootstrap 4 tab/card structure from main.html. Alpine.js and Chart.js dependencies need to be added to main.html. main.html needs Alpine.js + Chart.js added High
Scoring Engine submissions/scoring.py Port as-is — Pure Python, no framework ties. One adjustment needed: USE_TZ=False in Campus+ may cause issues with timezone-aware datetime comparisons in scoring; add django.utils.timezone guards. USE_TZ mismatch Low
Duplicate Detection submissions/scoring.pydetect_duplicate() Port as-is None Low
HoD Review Queue reviews/views.pyhod_queue(), review_submission() Adapt — Port views; map HoD role to Campus+ UserGroup or a new StaffProfile.role field. Rewrite templates with Bootstrap 4. Role mapping to Campus+ groups Medium
Central Team Review Queue reviews/views.pycentral_queue() Adapt — Same pattern as HoD queue. Role mapping Low
Principal Queue & Final Approval reviews/views.pyprincipal_queue() Adapt — A Principal UserGroup already exists in Campus+ permission_objects.py. Map PADS principal role to this group. Campus+ UserGroup "Principal" Low
Email Notifications notifications/service.py Port as-is — Already uses iQube API at 10.1.76.76:25001, same infrastructure as Campus+. Update hardcoded base URLs to use Campus+'s CAMPUS_BASE_URL setting. settings.CAMPUS_BASE_URL Low
Deadline Reminder Celery Task notifications/tasks.py Merge — Add entry to Campus+'s CELERY_BEAT_SCHEDULE dict with pads.notifications.tasks.send_deadline_reminders. settings.py CELERY_BEAT_SCHEDULE Low
Reports & Excel Export reports/views.pyassessment_excel() Port as-is — openpyxl already in Campus+ requirements. No UI template needed (streams file download). openpyxl version (Campus+ 3.1.2 vs PADS 3.1.5) Low
Audit Log audit/models.py, audit/middleware.py Adapt — Rename to PadsAuditLog to avoid potential future collision. Port AuditMiddleware as a new middleware in Campus+ settings. Middleware list order Low
Admin: Create Admin Users accounts/views.pyadmin_create() Adapt — Replace PADS custom admin create with a Campus+ pattern: create auth.User, assign to a PADS-specific UserGroup, create StaffProfile. Campus+ UserGroup model Medium
Institution Context Switching institutions/views.pyswitch() Adapt — Port under /pads/institutions/switch/. Prefix session key to pads_active_institution_id to avoid collision with any future session use. Session key namespace Low
PADS Base Template templates/base/base.html Replace — All PADS templates must extend main.html instead. PADS's design system (green CSS variables, card-pads classes, etc.) is adapted or inlined per template. All 23 PADS templates High
2

Conflict Analysis

A. Model Conflicts

These are the most dangerous conflicts. Resolving them requires migration planning and must be done before any PADS app is added to INSTALLED_APPS.
Model NameCampus+ VersionPADS VersionConflict TypeResolution
Institution base_app.Institution: name (CharField max 50) institutions.Institution: code (SlugField), name (200), email_domain, short_name, is_active Name collision + schema mismatch Rename PADS model to PadsInstitution in pads.institutions app. Evaluate whether Campus+ base_app.Institution can be enriched with PADS's extra fields to avoid two institution tables.
Department base_app.Department: name, Institution FK, department_head_email, biometric ZK fields (zk_uid, zk_department_code) staff.Department: institution FK, code (SlugField), name, is_active Name collision + schema mismatch Rename PADS model to PadsDepartment. The ZK biometric fields in Campus+'s version make direct reuse impossible without complicating PADS logic.
User model auth.User (default Django); extended via base_app.UserRecord OneToOneField (related_name="associated_user") accounts.User: AbstractUser with employee_code, is_group_admin, is_inst_admin, phone AUTH_USER_MODEL conflict — critical Campus+ wins. PADS must drop its custom User model. Extra fields (employee_code, role flags) move to PadsStaffProfile which maintains OneToOneField to auth.User.
StaffProfile No equivalent in Campus+ staff.StaffProfile: OneToOneField to accounts.User, institution, department, designation, role No collision but FK target must change Change user FK from accounts.User to auth.User. Rename to PadsStaffProfile to be explicit about ownership.
Designation None in Campus+ staff.Designation: institution, code, name, rank, is_active No collision Rename to PadsDesignation for consistent namespacing.
Assessment, Category, Criterion, etc. None in Campus+ Full PADS domain models No collision Port as-is under the new pads.* app namespace. No renames needed for these models.
AuditLog No equivalent (Campus+ has no request-level audit model) audit.AuditLog: user, path, status_code, ip, created_at No collision Rename to PadsAuditLog to namespace clearly. Port as-is.
DEFAULT_AUTO_FIELD AutoField (32-bit int PKs) BigAutoField (64-bit int PKs) Schema mismatch on new tables PADS models can keep BigAutoField by setting per-app default_auto_field in each PADS AppConfig. No migration impact on existing Campus+ tables.

C. URL Conflicts

PADS URL PathCampus+ Collision?Resolution
/ (dashboard)Yes — Campus+ landing page at /PADS dashboard moves to /pads/
/login/Yes — Campus+ landing/login at /Drop PADS login; use Campus+'s
/logout/Yes — Campus+ /logout/Drop PADS logout; use Campus+'s {% url 'logout' %}
/staff/No — not used in Campus+Namespace to /pads/staff/
/assessments/NoNamespace to /pads/assessments/
/submissions/NoNamespace to /pads/submissions/
/reviews/NoNamespace to /pads/reviews/
/reports/NoNamespace to /pads/reports/
/audit/NoNamespace to /pads/audit/
/institutions/NoNamespace to /pads/institutions/
/admins/NoNamespace to /pads/admins/
/accounts/Partial — allauth occupies /accounts/ in PADS; Campus+ does not have this path but social_django uses /social-auth/Drop allauth from integration; redirect rules added for any inbound allauth callbacks.
/admin/Yes — same Django adminSingle /admin/ — PADS models are registered in Campus+'s admin site.