Skip to content

Create triage workflow for issues and enhance task management#3052

Closed
DevWithPranav wants to merge 33 commits into
productionfrom
dev-server
Closed

Create triage workflow for issues and enhance task management#3052
DevWithPranav wants to merge 33 commits into
productionfrom
dev-server

Conversation

@DevWithPranav

Copy link
Copy Markdown
Collaborator

No description provided.

awindsr and others added 30 commits July 20, 2026 11:21
This workflow automates adding new issues and PRs to the µLearn Delivery project, setting their status to Triage by default.
Create triage workflow for issues and PRs
feat(task-management): add linkable events API and task event validation
feat: Create triage workflow for issues and PRs and enhance task management
feat(dashboard/mentor): include rejection reason in mentor status response
feat: Include rejection reason in mentor status response
fix: Refactor company model to link with organization via foreign key
fix: bug fixes in company, events, task, ig
Fix analytics counts and deduplicate user relations in dashboard
Fix analytics counts and refine dashboard features
feat: implement campus dashboard analytics and management views with …
Fix analytics counts and refine dashboard features
feat: add campus dashboard views and serializers to manage college da…
Add campus dashboard views and serializers for college data
feat: implement campus dashboard API views for managing and retrievin…
Add campus dashboard views and serializers for college data
…details, student levels, and student data retrieval
Implement campus dashboard API views and serializers for data management
Implement campus dashboard API views and serializers for data management
@greptile-apps

greptile-apps Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR bundles a GitHub Actions triage workflow with a broad set of data-correctness fixes across the campus, company, events, and task dashboards. The majority of changes are consistent improvements: adding verified=True filters so unverified org memberships are excluded from counts and rankings, switching karma aggregations to only count appraiser_approved=True entries, replacing fragile name-match org lookups with a new direct company.org FK, and fixing LearningCircle.created_at from auto_now to auto_now_add.

  • The new Company.org ForeignKey is the pivot for multiple company-related fixes across four files, but no corresponding ALTER TABLE entry lands in alter-scripts/ or schema.sql; because Company is managed = False, the column will not exist in the database and every access to company.org or company.org_id will raise an OperationalError at runtime.
  • A new LinkableEventsAPI endpoint in events/meta_views.py is missing authentication_classes = [CustomizePermission], allowing unauthenticated callers to enumerate published global events through an endpoint intended for the task-admin UI.
  • CollegeChangeAPI now auto-verifies all college links on creation and transfer, bypassing the existing verified=False → approval gate pattern.

Confidence Score: 2/5

Not safe to merge: the Company.org FK change is the backbone of multiple fixes in this PR but the column does not exist in the database, so merging will immediately break all company-related endpoints.

The Company model adds an org FK that four changed files depend on, but no ALTER TABLE entry exists in alter-scripts/ or schema.sql. Every access to company.org or company.org_id on the live database will raise an OperationalError, taking down company views, mentor nomination, and event scope resolution for company users. The missing auth on LinkableEventsAPI adds a data-exposure issue on top. The rest of the changes — verified filters, karma accuracy fixes, correlated subqueries for ig/lc counts, the triage workflow — are solid improvements.

db/company.py (missing schema artifact) and api/dashboard/events/meta_views.py (missing authentication_classes on LinkableEventsAPI) need fixes before this can be merged safely.

Security Review

  • Missing authentication on LinkableEventsAPI (api/dashboard/events/meta_views.py): The new endpoint has no authentication_classes, so unauthenticated HTTP clients receive a 200 with all PUBLISHED/ONGOING global events (id, title, start_datetime). The endpoint is documented as an admin task-management helper and should be gated.

Important Files Changed

Filename Overview
db/company.py Adds org ForeignKey to Company model with no corresponding DB schema change — runtime OperationalError on every access to company.org
api/dashboard/events/meta_views.py Adds new LinkableEventsAPI endpoint missing authentication_classes, exposing global event data to unauthenticated callers; also correctly refactors company-org lookup to use the direct FK
api/dashboard/college/college_view.py Cleans up duplicate org-link dedup logic and removes a MultipleObjectsReturned risk; changes verified=False to verified=True on all college changes — a policy shift that should be explicitly confirmed
api/dashboard/campus/campus_views.py Consistently adds verified=True filters across campus student/leaderboard queries; replaces inflated joined Count with correlated subqueries for ig_count and lc_count; fixes join_date to use org join date
api/dashboard/campus/serializers.py Adds verified=True and appraiser_approved=True guards throughout; fixes rank inflation by switching from group-annotate to per-row Python accumulation
api/dashboard/company/serializers.py Wraps company rename in transaction.atomic to keep Company.name and Organization.title in sync; uses company.org FK directly instead of name-match lookup
db/learning_circle.py Fixes created_at field: auto_now=True (overwrote on every save) changed to auto_now_add=True (set only at creation); no DB schema change needed since the column already exists
api/dashboard/task/dash_task_view.py Adds event accessibility check on task create/edit; correctly reads validated_data["event_fk_id"] matching the serializer source attribute
.github/workflows/triage.yml Adds GitHub project board triage automation; workflow is safe since it runs no user-supplied code and the PAT scope is limited to Projects write

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant CompanyView as company_views / serializers
    participant CompanyModel as Company (managed=False)
    participant DB as MySQL DB

    Note over CompanyModel,DB: company.org_id column does NOT exist in DB yet

    Client->>CompanyView: PATCH /company/id/ (rename)
    CompanyView->>CompanyModel: company.org (FK access)
    CompanyModel->>DB: "SELECT org_id FROM company WHERE id=?"
    DB-->>CompanyModel: OperationalError: Unknown column 'company.org_id'
    CompanyModel-->>CompanyView: 500 Internal Server Error

    Note over CompanyView,DB: All company flows that use company.org fail until ALTER TABLE lands

    participant AnonUser as Unauthenticated Caller
    participant LinkableEventsAPI

    AnonUser->>LinkableEventsAPI: GET /events/meta/linkable-events/
    Note over LinkableEventsAPI: No authentication_classes declared
    LinkableEventsAPI->>AnonUser: 200 OK — list of published global events
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant CompanyView as company_views / serializers
    participant CompanyModel as Company (managed=False)
    participant DB as MySQL DB

    Note over CompanyModel,DB: company.org_id column does NOT exist in DB yet

    Client->>CompanyView: PATCH /company/id/ (rename)
    CompanyView->>CompanyModel: company.org (FK access)
    CompanyModel->>DB: "SELECT org_id FROM company WHERE id=?"
    DB-->>CompanyModel: OperationalError: Unknown column 'company.org_id'
    CompanyModel-->>CompanyView: 500 Internal Server Error

    Note over CompanyView,DB: All company flows that use company.org fail until ALTER TABLE lands

    participant AnonUser as Unauthenticated Caller
    participant LinkableEventsAPI

    AnonUser->>LinkableEventsAPI: GET /events/meta/linkable-events/
    Note over LinkableEventsAPI: No authentication_classes declared
    LinkableEventsAPI->>AnonUser: 200 OK — list of published global events
Loading

Reviews (1): Last reviewed commit: "Merge pull request #3051 from gtech-mule..." | Re-trigger Greptile

Comment thread db/company.py
class Company(models.Model):
id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4)
company_user = models.OneToOneField('User', on_delete=models.CASCADE, related_name='company_profile')
org = models.ForeignKey('Organization', on_delete=models.SET_NULL, null=True, blank=True, related_name='companies')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P0 Missing DB schema artifact for new org FK column

Company is managed = False, so Django will not add the org_id column to the company table. Every downstream code path in this PR that accesses company.org or company.org_id (in company_views.py, company/serializers.py, events/manage_views.py, and events/meta_views.py) will fail at runtime with OperationalError: Unknown column 'company.org_id'. An ALTER TABLE company ADD COLUMN org_id CHAR(36) NULL ... entry must land in alter-scripts/ (or schema.sql) before—or together with—this code change.

Comment on lines +17 to +30
class LinkableEventsAPI(APIView):
"""
GET /events/meta/linkable-events/
Returns events the caller may attach a task to, for the task
create/edit "Linked Event" picker.

Reuses the exact predicate EventTaskPublicListAPI trusts when deciding
whether a task's linked event is visible to the caller (live events,
status PUBLISHED/ONGOING, same scope filter). Sharing the predicate is
load-bearing: if this picker offered an event that the task list's
accessible_event_ids check later rejected, an admin could create a task
that immediately disappeared from their own list.
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 security LinkableEventsAPI is missing authentication_classes

LinkableEventsAPI declares no authentication_classes = [CustomizePermission], so Django falls back to the project default (which typically allows unauthenticated requests). _get_viewer_id silently returns None on an anonymous request, and _build_scope_filter(None) then returns only the global-scope Q — meaning all PUBLISHED/ONGOING global events are returned to any unauthenticated caller. The docstring explicitly says this endpoint is for the task "create/edit 'Linked Event' picker", which is an admin-only surface. Add authentication_classes = [CustomizePermission] (and the appropriate @role_required decorator) consistent with the surrounding OrganizerOptionsAPI and CollaborationTargetsAPI views in the same file.

Comment on lines 86 to +122
@@ -97,39 +105,34 @@ def patch(self, request):
f"Department removed"
)
else:
if current_department:
if final_department:
message = (
f"College updated successfully to {new_organization.title}. "
f"Department remains {current_department.title}"
f"Department remains {final_department.title}"
)
else:
message = f"College updated successfully to {new_organization.title}"

action = "updated"
else:
UserOrganizationLink.objects.create(
new_link = UserOrganizationLink.objects.create(
user=user,
org=new_organization,
department=department,
verified=False,
verified=True,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 College links are now auto-verified — confirm this policy change is intentional

Before this PR, both the update and create paths set verified=False, putting the new/changed link through a campus-lead approval step. The PR changes both to verified=True, bypassing any approval gate entirely. The inline comment argues that no manual approval flow exists, but this endpoint is used by the student themselves (not a campus lead), so skipping verification means a student can freely reassign themselves to any college in the system and appear as a verified=True member of that campus immediately. If the approval workflow actually exists elsewhere (e.g. a campus lead reviews pending links), this silently breaks it.

Could you clarify whether there is genuinely no approval flow for college transfers, and if so, whether all existing verified=False links in production have been migrated or will remain stranded?

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Is the campus-transfer approval workflow truly absent, or is it handled elsewhere (e.g. a campus-lead endpoint that flips verified=True)? If it exists, auto-verifying here would let any student bypass it.

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.

2 participants