Create triage workflow for issues and enhance task management#3052
Create triage workflow for issues and enhance task management#3052DevWithPranav wants to merge 33 commits into
Conversation
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
…serializing logic
feat: implement campus dashboard analytics and management views with …
Fix analytics counts and refine dashboard features
…ta and student metrics
feat: add campus dashboard views and serializers to manage college da…
Add campus dashboard views and serializers for college data
…g campus data and student details
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
…s for data management
Implement campus dashboard API views and serializers for data management
Implement campus dashboard API views and serializers for data management
Greptile SummaryThis 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
|
| 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
%%{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
Reviews (1): Last reviewed commit: "Merge pull request #3051 from gtech-mule..." | Re-trigger Greptile
| 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') |
There was a problem hiding this comment.
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.
| 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. | ||
| """ | ||
|
|
There was a problem hiding this comment.
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.
| @@ -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, | |||
There was a problem hiding this comment.
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.
No description provided.