Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 18, 2025

Backend API consolidated task/contest collaborator endpoints into generic resource-based paths (/access-control/resources/{resource_type}/{resource_id}/...). Frontend had separate methods per resource type.

Changes

  • DTOs: Added ResourceType enum for type-safe resource types
  • Service API: Replaced resource-specific methods with unified methods accepting resourceType parameter:
    // Before: separate methods for each resource
    getTaskCollaborators(taskId)
    getContestCollaborators(contestId)
    
    // After: single method with resource type
    getCollaborators(resourceType, resourceId)
  • Complete migration: All usages updated to use new unified API across remote functions and layout files
  • Backend filtering: Implemented getAssignableUsers endpoint to retrieve assignable users filtered by backend
  • Code cleanup: Removed deprecated legacy methods, unused Valibot schemas, and client-side filtering logic

Backend Filtering Implementation

Replaced client-side user filtering with backend /assignable endpoint:

Before:

  • Fetched all users via getAllUsers()
  • Filtered out students and existing collaborators on frontend
  • Required passing existingCollaborators prop to components

After:

  • Use getAssignableUsers(resourceId) endpoint
  • Backend returns only teachers who aren't already collaborators
  • Eliminated ~30 lines of frontend filtering logic
  • Simplified component interfaces

Example

import { ResourceType } from '$lib/dto/accessControl';

// Unified API usage
const collaborators = await service.getCollaborators(ResourceType.Tasks, taskId);
const assignableUsers = await service.getAssignableUsers(ResourceType.Tasks, taskId);
await service.addCollaborator(ResourceType.Contests, contestId, data);

All backend collaborator endpoints now covered with a clean, unified, type-safe implementation. Backend handles user filtering for better performance and separation of concerns.

Original prompt

This section details on the original issue you should resolve

<issue_title>Align frontend access-control services to backend swagger changes</issue_title>
<issue_description>Update and refactor the frontend to match the new backend Swagger for access-control. Implement a unified service to handle all access-control resource methods. Ensure all endpoints are covered and reflected in the frontend API service:

Endpoints required:

  • GET /access-control/resources/{resource_type}/{resource_id}/assignable: Retrieve users who can be assigned to a resource
  • GET /access-control/resources/{resource_type}/{resource_id}/collaborators: List all collaborators for a resource
  • POST /access-control/resources/{resource_type}/{resource_id}/collaborators: Add a collaborator to a resource
  • DELETE /access-control/resources/{resource_type}/{resource_id}/collaborators/{user_id}: Remove a collaborator
  • PUT /access-control/resources/{resource_type}/{resource_id}/collaborators/{user_id}: Update a collaborator's permissions

Acceptance criteria:

  • There is a single AccessControlService encapsulating all these endpoints
  • Update existing remote functions/components to use the unified service
  • Types are strictly defined with Valibot schemas for request and response shapes
  • All frontend references to access-control APIs and collaborators/assignable users are updated
  • Add/adjust integration tests if needed

Reference: Consult backend Swagger for all request/response payload details.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 18, 2025 19:18
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Copilot AI changed the title [WIP] Align frontend access-control services to backend swagger changes Unify access-control service API with resource-based methods Dec 18, 2025
Copilot AI requested a review from TheRealSeber December 18, 2025 19:23
Copy link
Contributor

@TheRealSeber TheRealSeber left a comment

Choose a reason for hiding this comment

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

@copilot please adjust

- Removed getAssignableUsers from remote functions (not used, getAllUsers with frontend filtering is used instead)
- Removed all deprecated methods from AccessControlService
- Updated all usages to use new unified methods (getCollaborators, addCollaborator, updateCollaborator, deleteCollaborator)
- Removed unused Valibot schemas (CollaboratorSchema, AddCollaboratorRequestSchema, etc.)
- Updated layout.server.ts files to use ResourceType enum

Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 18, 2025

@copilot please adjust

All feedback addressed in commit 103614a:

  • Removed unused getAssignableUsers functions
  • Removed all deprecated methods and migrated usages
  • Removed unused Valibot schemas

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdn.jsdelivr.net
    • Triggering command: /opt/hostedtoolcache/node/22.21.1/x64/bin/node node /home/REDACTED/work/frontend/frontend/node_modules/.bin/../vite/bin/vite.js build (dns block)
  • eu.posthog.com
    • Triggering command: /opt/hostedtoolcache/node/22.21.1/x64/bin/node node /home/REDACTED/work/frontend/frontend/node_modules/.bin/../vite/bin/vite.js build (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@TheRealSeber
Copy link
Contributor

@copilot please adjust src\routes\dashboard\teacher\tasks[taskId]\collaborators+page.svelte and src\routes\dashboard\teacher\contests[contestId]\collaborators+page.svelte. we shouldn't be using user query there, instead we should use assignable user (thus we won;t have to pre-filter students etc. on frontend anymore as backend handles it)

- Added getAssignableUsers query to both task and contest collaborators remote files
- Updated Svelte pages to call getAssignableUsers with taskId/contestId
- Backend now handles filtering of students and existing collaborators
- Removed client-side filtering logic from AddCollaboratorButton components
- Removed existingCollaborators prop (no longer needed)
- Removed UserService import from remote files

Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 18, 2025

@copilot please adjust src\routes\dashboard\teacher\tasks[taskId]\collaborators+page.svelte and src\routes\dashboard\teacher\contests[contestId]\collaborators+page.svelte. we shouldn't be using us...

Updated both pages to use getAssignableUsers instead of getAllUsers. Backend now handles filtering of students and existing collaborators, eliminating the need for frontend filtering. Removed ~30 lines of filtering code and simplified component props. Commit: af7e961

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdn.jsdelivr.net
    • Triggering command: /opt/hostedtoolcache/node/22.21.1/x64/bin/node node /home/REDACTED/work/frontend/frontend/node_modules/.bin/../vite/bin/vite.js build (dns block)
  • eu.posthog.com
    • Triggering command: /opt/hostedtoolcache/node/22.21.1/x64/bin/node node /home/REDACTED/work/frontend/frontend/node_modules/.bin/../vite/bin/vite.js build (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR unifies the access-control service API by replacing resource-specific methods with generic resource-based methods that accept a ResourceType parameter. The changes align the frontend with backend API consolidation and introduce backend-filtered user assignment.

Key changes:

  • Introduced ResourceType enum and unified service methods (getCollaborators, addCollaborator, etc.) replacing separate task/contest-specific methods
  • Implemented backend /assignable endpoint to retrieve assignable users, eliminating client-side filtering logic
  • Added task visibility toggle feature with confirmation dialog and i18n support

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/lib/dto/accessControl.ts Added ResourceType enum and request interfaces for type-safe API calls
src/lib/services/AccessControlService.ts Replaced 6 resource-specific methods with 4 unified methods accepting resourceType parameter
src/routes/dashboard/teacher/tasks/[taskId]/collaborators/collaborators.remote.ts Updated to use unified API methods and getAssignableUsers endpoint
src/routes/dashboard/teacher/contests/[contestId]/collaborators/collaborators.remote.ts Updated to use unified API methods and getAssignableUsers endpoint
src/routes/dashboard/teacher/tasks/[taskId]/+layout.server.ts Updated getTaskCollaborators call to unified getCollaborators method
src/routes/dashboard/teacher/contests/[contestId]/+layout.server.ts Updated getContestCollaborators call to unified getCollaborators method
src/routes/dashboard/user/contests/[contestId]/results/+layout.server.ts Updated getContestCollaborators call to unified getCollaborators method
src/lib/components/dashboard/admin/tasks/AddCollaboratorButton.svelte Removed existingCollaborators prop and client-side filtering logic
src/lib/components/dashboard/admin/contests/AddContestCollaboratorButton.svelte Removed existingCollaborators prop and client-side filtering logic
src/routes/dashboard/teacher/tasks/[taskId]/collaborators/+page.svelte Replaced getAllUsers with getAssignableUsers query
src/routes/dashboard/teacher/contests/[contestId]/collaborators/+page.svelte Replaced getAllUsers with getAssignableUsers query
src/routes/dashboard/teacher/tasks/tasks.remote.ts Added toggleTaskVisibility command for visibility management
src/lib/services/TasksManagementService.ts Added toggleTaskVisibility service method
src/lib/dto/task.ts Added isVisible field to Task and UploadTaskDto interfaces
src/lib/components/dashboard/admin/tasks/TaskVisibilityToggle.svelte New component for toggling task visibility with confirmation
src/lib/components/dashboard/tasks/AdminTaskCard.svelte Integrated TaskVisibilityToggle component
src/lib/components/dashboard/admin/tasks/TasksUploadDialog.svelte Added visibility checkbox to upload form
src/lib/components/dashboard/admin/contests/EditContestDialog.svelte Removed explicit id attributes from checkboxes
src/routes/dashboard/teacher/tasks/upload.remote.ts Added isVisible field to upload schema and payload
src/routes/dashboard/teacher/contests/contests.remote.ts Added debug console.log statement
messages/en.json Added i18n strings for visibility toggle feature
messages/pl.json Added Polish translations for visibility toggle feature
Comments suppressed due to low confidence (1)

src/lib/components/dashboard/admin/contests/EditContestDialog.svelte:280

  • The id attributes were removed from the Checkbox components, but the corresponding Label components still reference them via the for attribute (e.g., for="isRegistrationOpen", for="isSubmissionOpen", for="isVisible"). This breaks the label-checkbox association. Either keep the id attributes on the checkboxes or remove the for attributes from the labels.
        <div class="flex items-center gap-3">
          <Checkbox
            {...updateContest.fields.isRegistrationOpen.as('checkbox')}
            checked={contest.isRegistrationOpen}
          />
          <Label for="isRegistrationOpen" class="cursor-pointer text-sm font-normal">
            {m.admin_contests_form_registration_open()}
          </Label>
        </div>

        <div class="flex items-center gap-3">
          <Checkbox
            {...updateContest.fields.isSubmissionOpen.as('checkbox')}
            checked={contest.isSubmissionOpen}
          />
          <Label for="isSubmissionOpen" class="cursor-pointer text-sm font-normal">
            {m.admin_contests_form_submission_open()}
          </Label>
        </div>

        <div class="flex items-center gap-3">
          <Checkbox
            {...updateContest.fields.isVisible.as('checkbox')}
            checked={contest.isVisible}
          />
          <Label for="isVisible" class="cursor-pointer text-sm font-normal">
            {m.admin_contests_form_visible()}
          </Label>

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@TheRealSeber TheRealSeber marked this pull request as ready for review December 20, 2025 22:24
@TheRealSeber TheRealSeber merged commit 8ee996b into master Dec 20, 2025
1 check passed
TheRealSeber pushed a commit that referenced this pull request Dec 20, 2025
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.

Align frontend access-control services to backend swagger changes

2 participants