Skip to content

PG thesis submission + examiner panel workflow - #1944

Merged
vikrantwiz02 merged 38 commits into
FusionIIIT:prod/acad-reactfrom
kotangale237:phd
Aug 6, 2026
Merged

PG thesis submission + examiner panel workflow#1944
vikrantwiz02 merged 38 commits into
FusionIIIT:prod/acad-reactfrom
kotangale237:phd

Conversation

@kotangale237

Copy link
Copy Markdown
Contributor

Summary

  • Adds a complete PG (M.Tech/M.Des) final-thesis workflow, separate from PhD's Dean Panel/Director/foreign-examiner flow:
    • PGThesisSubmission (synopsis + report upload, PDF-only, immutable once submitted)
    • Decimal-mode grading: ThesisEvaluationScore, ThesisExaminerPanel, ThesisExaminerCandidate (HOD nominates 4 Indian examiners per specialization batch, Dean ranks & invites, accepted examiner scores the batch)
    • Supervisor scoring UI, HOD nomination UI, Dean ranking UI (grouped by discipline+year for convenience; each specialization batch still gets its own independent panel)
  • Fixes PG thesis grades being excluded from transcript/SPI/CPI (examination app's PHD-only PROGRAMME_TYPE_BUCKETS gate).
  • Hardens file uploads: server-side PDF content-type check, hardcoded .pdf storage extension (was inferring from client filename, a stored-XSS risk).
  • phd is fully synced with prod/acad-react as of this PR (verified: git merge-base --is-ancestor upstream/prod/acad-react phd).

Test plan

  • python manage.py migrate runs clean (verified locally, all merge migrations applied without error)
  • python manage.py check passes
  • PG student can submit synopsis+report once, cannot resubmit
  • Supervisor scoring blocked until student submission exists
  • HOD can nominate 4 examiners per specialization batch in one screen, submitted together
  • Dean can rank/invite per specialization, grouped by discipline+year
  • Examiner accept/decline/scoring links work end to end
  • Existing PhD thesis-submission flow unaffected

kotangale237 and others added 30 commits March 14, 2026 15:29
…IT#1916

Integrate the placement backend onto prod/acad-react (production-ready,
API-only; legacy template code removed):
- Replace template-based placement_cell with the API implementation
  (api/views.py, api/urls.py, selectors.py, services.py, serializers).
- Point root urls.py placement include at placement_cell.api.urls.
- Fix Education.grade max_length 3->10: the PR migration truncated existing
  CGPA values (e.g. '8.39') and failed on real data; keep production width.
- Add migration 0013 to sync index names and updated_at with the models.
- Remove ~2600 lines of legacy template-based views, their old routes, the
  dead forms import, the unused pdf_filters templatetag, and 16 orphaned
  placementModule templates. Keep cv.html (used by generate_cv_api) and the
  5 templates shared with globals student-profile; keep forms.py (globals
  imports it).
- manage.py check clean; all 47 API URLs resolve; migrations apply on DB.

No settings or other modules changed.
- Add test_settings.py (outside the settings package) that disables
  migrations so the test DB builds from current models. The project's
  historical migrations do not apply on a fresh DB, which otherwise breaks
  test-DB creation for unrelated reasons.
- Add test_placement_api.py: self-contained regression/contract tests
  (Education.grade width guard, API-only URL wiring, auth + role authz).
- Fix the PR test fixtures: ExtraInfo is not auto-created here, so build it
  explicitly; grant self.officer the placement-officer role (denial tests
  use student/alumni users, so this is safe). This greens use_cases,
  business_rules and workflows.
- Skip test_module.PlacementCellApiTests: it needs the globals dashboard
  notification API (NotificationList / Notification.module) absent on this
  branch; placement-scoped behaviour is covered by the other modules.
- Declare PyYAML (spec-driven tests) and add tests/README.md.

Result: 173 tests, OK (skipped=36). Run with --settings=test_settings.
- Add management command 'setup_placement_roles' that creates idempotent
  login accounts for the four placement roles (placement officer, placement
  chairman, student, alumni), wires HoldsDesignation and enables
  ModuleAccess.placement_cell so the sidebar shows the module per role.
- Password is supplied at runtime (--password or PLACEMENT_ROLE_PASSWORD);
  it is never stored in the repo.
- Document the roles, what each can do, role resolution and the role
  accounts in the placement README (without any password).
Add two additive features to the placement_cell API, ported from the
job-board placement branch without disturbing the existing module:

- PlacementAnnouncement: announcements readable by any authenticated role
  and posted/deleted by the TPO.
- OffCampusPlacement: off-campus offers the TPO records against a student
  roll number.

Adds the models (migration 0014), read/write serializers, role-gated API
endpoints (/placement/api/announcements/, /placement/api/offcampus/) and
regression tests covering authentication and role authorization.
Port the published-CPI logic from the job-board placement branch: compute a
student's CPI from the examination module's latest *announced* result rather
than the static Student.cpi snapshot.

- selectors.get_student_published_cpi / batches_with_published_results
- /placement/api/cpi-batches/ lists batches with an announced result
- /placement/api/cpi-students/?batch_id= lists those students with their
  published CPI and off-campus companies; ?export=excel streams an .xls
  workbook (xlwt, matching the existing export).

Both endpoints are restricted to TPO and chairman users. Adds contract tests
covering authentication, role authorization and the Excel export.
Loading a batch's published CPI recomputed every student's CPI from the
examination module on each request (several queries plus grade aggregation
per student), making the Student CPI view slow for large batches.

- Fetch the latest announced result once per batch instead of once per
  student.
- Memoise each student's computed CPI in the cache keyed by roll number and
  semester; an announced semester's CPI does not change, so repeat loads of
  the same batch are served from cache. On a 49-student batch this cuts a
  reload from ~6s to ~0.02s.
- Use memcached-safe cache keys (no spaces or colons).
Add /placement/api/branches/ returning the distinct academic department names
students actually belong to. Branch eligibility compares a schedule's branch
against the student's department name, so the placement-event form can populate
its branch options from real data instead of a hard-coded list that had drifted
(e.g. 'MECH'/'BDES' never matched the real 'ME'/'Design' departments, silently
breaking branch eligibility).
Add a PlacementCalendarEvent model (migration 0015) plus endpoints so the
placement cell can drop arbitrary entries onto the calendar (info sessions,
deadlines, interview slots, notes):

- GET /placement/api/calendar-events/ lists events for any authenticated user.
- POST creates, PATCH/PUT updates and DELETE removes them, restricted to TPO
  and chairman users.

Includes contract tests for authentication, role authorization and CRUD.
Coerce the batch_id query parameter to an integer before using it, so it can
neither be reflected into the Content-Disposition filename nor reach the ORM
filter as arbitrary input; a non-integer value now returns 400 instead of a
500.
Add a module README covering the role model, the full feature set per role, the
backend models and grouped API endpoints, the published-CPI logic, the frontend
module, the role-account setup command and how to run the tests.
Placement Cell: drives, applications, calendar, CPI, off-campus, announcements + docs
Promote placement-pbi-v1 (placement cell module) to prod-test
…an -> Director -> external examiner review)

Adds the full examiner-nomination and invitation pipeline: student
uploads synopsis+thesis, supervisor nominates Indian/Foreign examiners,
Dean approves the panel, Director sets priority ranking, Dean sends
invitations to rank-1 examiners, and external examiners accept/reject
via emailed token links with automatic cascade to the next-ranked
examiner on decline or 15-day timeout (Celery beat task replacing a
dead django_cron job that never actually ran).

Also fixes several bugs found while wiring this up: a broken
reverse('procedures:...') call with no such URL namespace, external
review endpoints requiring login they can't have, and adds role/
ownership checks (supervisor_assign, dean panel endpoints,
director_approve) after a security review found they were only
gated by IsAuthenticated.
…email links)

- New models ThesisReview, ExaminerBankDetails, ReviewInvitation and migrations
- thesis_research module access flag in globals
- Scheduled process_review_invitations Celery task
- FRONTEND_URL setting for building examiner links; console email backend in dev
- programme_curriculum batch-management and course-audit JSON encoder changes
Implement PhD thesis submission workflow and enhance role-based access
Implement B.Tech sectioning and per-instructor grade submission
…d-react

# Conflicts:
#	FusionIIIT/applications/programme_curriculum/api/views.py
… registration

- New models + migrations 0029-0037 (comprehensive exam, open seminar,
  teaching credit, PhD course registration; seminar/teaching-credit renames)
- programme_curriculum: teaching credit + seminar models/serializers/forms (0044-0045)
- examination: registration-lineage CPI dedup with PhD thesis/seminar/teaching-credit
  grades; consolidate transcript building into _build_grade_validation_semesters helper
- Resolved merge with upstream/prod/acad-react
Bring prod-test up to date with the latest production while keeping the
placement, phd (thesis API) and B.Tech sectioning / section-aware grade
submission work. Reconcile examination grade submission: keep section-aware
roster scoping and per-section ownership (prod-test) while adopting production's
selected-role acadadmin detection, registration-based acadadmin course list
(so no-faculty courses like BTP appear), and the Summer CourseInstructor year
fix (course_instructor_year) across submit/upload/download/PDF/status.
PhD milestones + examination/grading fixes. Reconcile examination grade
submission: keep prod-test's section-aware ownership/roster scoping and Summer
CourseInstructor year handling, and adopt phd's generalized PROGRAMME_TYPE_BUCKETS
(UG/PG/PhD) programme handling. Keep phd's teaching-credit API views.
Replace the Convener placeholder role with the student's live RPC
committee (per-member consent + comments), HOD-DPGC and HOD-PGCS
review stages (both standing in for the real designations, mapped to
the student's HOD), and a real Dean Academic final sign-off.

Also includes a security/correctness pass on the new endpoints:
- Fix IDOR: supervisor_comprehensive_exam_detail and
  supervisor_open_seminar_detail had no ownership check
- Clear stale PGCS/HOD reviewer fields on RPC re-finalize so a
  resubmitted item stops showing as already-decided history
- Validate RPC result values against RESULT_CHOICES before saving
- Freeze RPC committee membership while an attempt is rpc_pending, to
  close a consent-bypass/stale-consent gap
- Remove leftover debug print statements
Examination: UG-only grade-submission sections (+ sync latest production)
Redesign Comprehensive Exam and Open Seminar: RPC/DPGC/PGCS/Dean flow
kotangale237 and others added 7 commits July 23, 2026 10:49
…value

Avoids depending on a SITE_URL setting that must be kept in sync with
the actual deployment domain; request.build_absolute_uri() reflects
whatever host the request actually arrived on.
Build review-detail media URL from the request instead of a settings value
… modules

- PG (M.Tech/M.Des) students get their own final thesis submission flow
  (PGThesisSubmission), separate from PhD's Dean Panel/Director/foreign-
  examiner workflow: decimal-mode grading (ThesisEvaluationScore,
  ThesisExaminerPanel, ThesisExaminerCandidate), HOD nominates 4 Indian
  examiners per specialization batch, Dean ranks and invites, whichever
  candidate accepts scores the whole batch.
- Fix PG thesis grades being excluded from transcript/SPI/CPI (examination
  app's PROGRAMME_TYPE_BUCKETS['PHD']-only gate).
- Harden PGThesisSubmission uploads: server-side PDF content-type check,
  hardcoded .pdf storage extension (was inferring from client filename).
- Misc: notifications_extension wiring, globals decorators/migrations,
  academic_information/programme_curriculum small fixes.
# Conflicts:
#	FusionIIIT/applications/examination/api/views.py
# Conflicts:
#	FusionIIIT/applications/examination/api/views.py
…d-react

# Conflicts:
#	FusionIIIT/applications/programme_curriculum/api/views.py
# Conflicts:
#	FusionIIIT/applications/programme_curriculum/api/views.py
@vikrantwiz02
vikrantwiz02 requested review from vikrantwiz02 and a lite review from Copilot August 5, 2026 17:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@vikrantwiz02 vikrantwiz02 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated-assisted review (risk-focused: security, permissions, migrations, grade/credit correctness). Large multi-feature PR (~26k lines); not an exhaustive line audit.

Verified clean: makemigrations --check passes (one leaf per app, state matches models); settings changes are safe; placement IDOR/scoping is otherwise solid; examiner token endpoints scope mutations to the token's object; setup_placement_roles is idempotent.

Must-fix highlights: broken access control on programme_curriculum curriculum-admin endpoints and on send_notification_api; a credit-shortage regression in calculate_cpi_for_student. NB: the examination grade/credit changes overlap the sections-branch credit fix — coordinate the merge or the shortage/double-count/F-exclusion will land on prod. See inline comments.

Comment thread FusionIIIT/applications/programme_curriculum/api/views.py
Comment thread FusionIIIT/applications/placement_cell/api/views.py
Comment thread FusionIIIT/applications/placement_cell/api/views.py
Comment thread FusionIIIT/applications/academic_procedures/api/views.py
Comment thread FusionIIIT/applications/academic_procedures/api/views.py
Comment thread FusionIIIT/applications/examination/api/views.py Outdated
Comment thread FusionIIIT/applications/examination/api/views.py Outdated
Comment thread FusionIIIT/applications/academic_procedures/api/views.py
Comment thread FusionIIIT/applications/academic_procedures/api/views.py

@vikrantwiz02 vikrantwiz02 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional lower-severity / robustness findings (complementing the earlier review). Non-blocking; grouped for convenience.

Comment thread FusionIIIT/applications/placement_cell/api/urls.py
Comment thread FusionIIIT/applications/academic_procedures/api/views.py
Comment thread FusionIIIT/applications/academic_procedures/api/views.py
Comment thread FusionIIIT/applications/academic_procedures/api/views.py
Comment thread FusionIIIT/applications/placement_cell/api/views.py
Comment thread FusionIIIT/applications/placement_cell/api/views.py
Comment thread FusionIIIT/applications/placement_cell/api/views.py
Comment thread FusionIIIT/applications/examination/api/views.py
- programme_curriculum: gate all thesis/seminar/teaching-credit CRUD + slot endpoints to acadadmin (12 DRF via IsAcadAdmin, 6 plain views via require_designation)
- placement_cell: TPO gate on send_notification_api and statistics GET; atomic next_round_api; block finalized accept/reject in application_detail_api; lock active-application cap; add name='placement' URL alias
- academic_procedures: BOLA fix on supervisor/hod review GET; faculty gate on supervisor_student_academic_info; immutability for announced thesis grades; thesis_submit PDF + duplicate guard; student_thesis_api 400 on missing fields; atomic admin_verify_enrollments; invitation actions require POST
- examination: reconcile calculate_cpi_for_student and grade-validation to production (count-once dedup, F earns credit, tu-based cumulative)
@vikrantwiz02
vikrantwiz02 merged commit 543de6e into FusionIIIT:prod/acad-react Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants