-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[WEB-4045] feat: restructuring of the external APIs for better maintainability #7477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Introduced new asset-related endpoints for user assets and server assets, allowing for asset uploads and management. - Added user endpoint to retrieve current user information. - Updated URL routing to include new asset and user patterns. - Enhanced issue handling with a new search endpoint for issues across multiple fields. - Expanded member management with a new endpoint for workspace members.
…to openapi-specification
…to openapi-specification
- Updated CycleAPIEndpoint and CycleIssueAPIEndpoint to include detailed OpenAPI schema definitions for GET, POST, PATCH, and DELETE operations. - Specified allowed HTTP methods for each endpoint in the URL routing. - Improved documentation for cycle creation, updating, and deletion, including request and response examples.
…to openapi-specification
…od definitions - Added detailed OpenAPI schema definitions for various API endpoints including Intake, Module, and State. - Specified allowed HTTP methods for each endpoint in the URL routing for better clarity and documentation. - Improved request and response examples for better understanding of API usage. - Introduced unarchive functionality for cycles and modules with appropriate endpoint definitions.
…to openapi-specification
Improves the organization and maintainability of the OpenAPI documentation by modularizing the `openapi_spec_helpers.py` file. The changes include: - Migrates common parameters, responses, examples, and authentication extensions to separate modules. - Introduces helper decorators for different endpoint types. - Updates view imports to use the new module paths. - Removes the legacy `openapi_spec_helpers.py` file. This refactoring results in a more structured and easier-to-maintain OpenAPI documentation setup.
…to openapi-specification
- Removed unnecessary parameters from the OpenAPI documentation for various endpoints in the asset, cycle, and project views. - Updated request structures to improve clarity and consistency across the API documentation. - Enhanced response formatting for better readability and maintainability.
Updated various API endpoints across the application to include comprehensive docstrings that clarify their functionality. Each endpoint now features a summary and detailed description, improving the overall understanding of their purpose and usage. This change enhances the OpenAPI specifications for better developer experience and documentation clarity.
- Added new serializers for handling cycle and module issue requests, including `CycleIssueRequestSerializer`, `TransferCycleIssueRequestSerializer`, `ModuleIssueRequestSerializer`, and intake issue creation/updating serializers. - Updated existing serializers to improve clarity and maintainability, including the `UserAssetUploadSerializer` and `IssueAttachmentUploadSerializer`. - Refactored API views to utilize the new serializers, enhancing the request handling for cycle and intake issue endpoints. - Improved OpenAPI documentation by replacing inline request definitions with serializer references for better consistency and readability.
- Replaced inline schema definitions with dedicated decorators for various endpoint types, enhancing clarity and maintainability. - Updated API views to utilize new decorators for user, cycle, intake, module, and project endpoints, improving consistency in OpenAPI documentation. - Removed unnecessary parameters and responses from endpoint specifications, streamlining the documentation for better readability. - Enhanced the organization of OpenAPI documentation by modularizing endpoint-specific decorators and parameters.
- Removed unused `StateLiteSerializer` import from the serializer module. - Updated test setup to include a noqa comment for the `django_db_setup` fixture, ensuring clarity in the code. - Added missing commas in user data dictionary for consistency.
…to openapi-specification
- Updated API endpoints in asset, cycle, intake, issue, module, project, and state views to include OpenApiRequest and OpenApiExample for better request documentation. - Added example requests for creating and updating resources, improving clarity for API consumers. - Ensured consistent use of OpenApi utilities across all relevant endpoints to enhance overall API documentation quality.
- Added detailed descriptions to multiple API endpoints across asset, cycle, intake, issue, module, project, state, and user views to improve clarity for API consumers. - Ensured consistent documentation practices by including descriptions that outline the purpose and functionality of each endpoint. - This update aims to enhance the overall usability and understanding of the API documentation.
- Changed example fields in OpenAPI documentation for issue comments from "content" to "comment_html" to reflect the correct structure. - Introduced a new `get_queryset` method in the ProjectDetailAPIEndpoint to filter projects based on user membership and workspace, while also annotating additional project-related data such as total members, cycles, and modules. - Updated permission checks to use the correct attribute name for project identifiers, ensuring accurate permission handling.
- Updated multiple API endpoints across asset, cycle, intake, issue, module, project, state, and user views to include new OpenApiResponse examples for better clarity on expected outcomes. - Introduced new parameters for project and issue identifiers to improve request handling and documentation consistency. - Enhanced existing responses with detailed examples to aid API consumers in understanding the expected data structure and error handling. - This update aims to improve the overall usability and clarity of the API documentation.
…to openapi-specification
…tiple API endpoints for consistency and clarity
Conflicts: apps/api/plane/api/serializers/asset.py apps/api/plane/api/urls/asset.py apps/api/plane/api/urls/schema.py apps/api/plane/api/urls/user.py apps/api/plane/api/views/asset.py apps/api/plane/api/views/cycle.py apps/api/plane/api/views/issue.py apps/api/plane/api/views/user.py apps/api/plane/settings/openapi.py
|
Caution Review failedThe pull request is closed. WalkthroughThis update introduces a comprehensive refactor and modularization of the Plane API's OpenAPI schema generation and documentation, primarily integrating the drf-spectacular package. It splits monolithic API endpoints into granular, RESTful classes, adds domain-specific serializers, reorganizes URL routing, and centralizes OpenAPI utilities into a modular package. Numerous docstrings, enums, and validation enhancements are added throughout the codebase. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant APIView
participant Serializer
participant OpenAPIUtils
participant drf-spectacular
Client->>APIView: Sends HTTP request (e.g., POST /api/v1/projects/)
APIView->>Serializer: Validate and process request data
APIView->>OpenAPIUtils: Annotate with OpenAPI decorators, parameters, responses
APIView->>drf-spectacular: Schema generation (if enabled)
drf-spectacular->>OpenAPIUtils: Use auth extensions, parameters, hooks
APIView-->>Client: Returns serialized response (with OpenAPI docs if requested)
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Complexity: Extensive refactor and modularization, new features, many new files, significant changes to API structure, serializers, endpoints, and OpenAPI documentation. Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (8)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 introduces a comprehensive OpenAPI/Swagger documentation system for the Plane REST API by integrating drf-spectacular. The changes include modularizing OpenAPI utilities, restructuring API views for better documentation support, and establishing a maintainable documentation framework.
Key changes implemented:
- OpenAPI Module Structure: Created a modular
plane/utils/openapi/package with separate files for authentication, parameters, responses, examples, decorators, and schema processing hooks - View Restructuring: Split combined list/detail views into separate endpoints following REST conventions for better API documentation clarity
- Documentation Integration: Added comprehensive OpenAPI decorators and examples across all API endpoints with consistent parameter and response definitions
Reviewed Changes
Copilot reviewed 64 out of 64 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/api/plane/utils/openapi/*.py | New modular OpenAPI utilities replacing monolithic helpers |
| apps/api/plane/api/views/*.py | Restructured API views with OpenAPI documentation decorators |
| apps/api/plane/settings/*.py | Added OpenAPI configuration and conditional drf-spectacular integration |
| apps/api/plane/urls.py | Added OpenAPI schema and documentation UI endpoints |
| apps/api/requirements/base.txt | Added drf-spectacular dependency for OpenAPI generation |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chainI'll review this PR for you. Let me gather the necessary information about the changes first. 🏁 Script executed: Length of output: 276303 @sriramveeraghanta This is an excellent and comprehensive refactoring PR! I can see significant improvements in API structure, documentation, and maintainability. Here's my detailed review: 🎯 Overall Assessment: Excellent WorkThis PR demonstrates a mature approach to API design with proper separation of concerns, comprehensive documentation, and improved maintainability. ✅ Major Strengths1. Proper API Endpoint SeparationThe split between list/create and detail endpoints is a best practice: # Before: Single endpoint handling all operations
class IssueAPIEndpoint(BaseAPIView):
def get(self, request, slug, project_id, pk=None):
if pk:
# Detail logic
else:
# List logic
# After: Properly separated endpoints
class IssueListCreateAPIEndpoint(BaseAPIView):
def get(self, request, slug, project_id):
# List logic only
class IssueDetailAPIEndpoint(BaseAPIView):
def get(self, request, slug, project_id, pk):
# Detail logic only2. Enhanced Serializer ArchitectureThe introduction of specific create/update serializers follows Django best practices: # Create serializer with validation
class CycleCreateSerializer(BaseSerializer):
class Meta:
fields = ["name", "description", "start_date", "end_date", ...]
# Update serializer extending create
class CycleUpdateSerializer(CycleCreateSerializer):
class Meta(CycleCreateSerializer.Meta):
fields = CycleCreateSerializer.Meta.fields + ["owned_by"]3. Comprehensive OpenAPI DocumentationThe addition of detailed API documentation with examples is outstanding: @cycle_docs(
operation_id="create_cycle",
summary="Create cycle",
description="Create a new development cycle...",
request=OpenApiRequest(request=CycleCreateSerializer, examples=[CYCLE_CREATE_EXAMPLE]),
responses={201: OpenApiResponse(response=CycleSerializer, examples=[CYCLE_EXAMPLE])},
)4. Improved URL StructureThe URL patterns are now more RESTful and explicit: # Clear separation of list vs detail endpoints
path("cycles/", CycleListCreateAPIEndpoint.as_view(http_method_names=["get", "post"]))
path("cycles/<uuid:pk>/", CycleDetailAPIEndpoint.as_view(http_method_names=["get", "patch", "delete"]))🔧 Technical Improvements1. Generic Base ClassesMoving from class BaseAPIView(TimezoneMixin, GenericAPIView, BasePaginator):
# Better foundation for CRUD operations2. Asset ManagementThe new asset management system with presigned URLs is well-designed: class UserAssetEndpoint(BaseAPIView):
def post(self, request):
# Generate presigned URL for S3 upload
# Clean separation of concerns3. Consistent Response PatternsAll endpoints now follow consistent response patterns with proper HTTP status codes.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 27
🔭 Outside diff range comments (14)
apps/api/plane/authentication/provider/oauth/github.py (2)
95-103:expires_ininterpreted as Unix epoch – access-token expiry will be wrong.
GitHub returns seconds until expiry, not an epoch timestamp. Converting it withdatetime.fromtimestampskews the value to 1970-01-01 + N seconds.-"access_token_expired_at": ( - datetime.fromtimestamp( - token_response.get("expires_in"), tz=pytz.utc - ) - if token_response.get("expires_in") - else None -), +"access_token_expired_at": ( + datetime.utcnow().replace(tzinfo=pytz.utc) + + timedelta(seconds=token_response["expires_in"]) + if token_response.get("expires_in") + else None +),Same logic applies to
refresh_token_expired_at.
118-123: External HTTP calls lack a timeout – potential request hang.Add a reasonable
timeout(e.g., 5 s) and surfacerequests.Timeoutin the existingexceptblock.-emails_response = requests.get(emails_url, headers=headers).json() +emails_response = requests.get(emails_url, headers=headers, timeout=5).json()apps/api/plane/api/serializers/user.py (1)
24-34: Fix duplicate email field in Meta.fields.The
fields = [ "id", "first_name", "last_name", "email", "avatar", "avatar_url", "display_name", - "email", ]apps/api/plane/api/serializers/module.py (2)
135-152: Optimize member update logicThe current implementation deletes all members and recreates them, which is inefficient and could trigger unnecessary database operations and signals. Consider updating only the differences.
if members is not None: - ModuleMember.objects.filter(module=instance).delete() - ModuleMember.objects.bulk_create( - [ - ModuleMember( - module=instance, - member_id=str(member), - project=instance.project, - workspace=instance.project.workspace, - created_by=instance.created_by, - updated_by=instance.updated_by, - ) - for member in members - ], - batch_size=10, - ignore_conflicts=True, - ) + # Get current members + current_members = set(instance.module_members.values_list('member_id', flat=True)) + new_members = set(str(member) for member in members) + + # Remove members that are no longer in the list + members_to_remove = current_members - new_members + if members_to_remove: + ModuleMember.objects.filter(module=instance, member_id__in=members_to_remove).delete() + + # Add new members + members_to_add = new_members - current_members + if members_to_add: + ModuleMember.objects.bulk_create( + [ + ModuleMember( + module=instance, + member_id=member_id, + project=instance.project, + workspace=instance.project.workspace, + created_by=instance.created_by, + updated_by=instance.updated_by, + ) + for member_id in members_to_add + ], + batch_size=10, + ignore_conflicts=True, + )
244-251: Fix error message to reference Module instead of IssueThe error message incorrectly references "Issue" when it should reference "Module".
def create(self, validated_data): if ModuleLink.objects.filter( url=validated_data.get("url"), module_id=validated_data.get("module_id") ).exists(): raise serializers.ValidationError( - {"error": "URL already exists for this Issue"} + {"error": "URL already exists for this Module"} ) return ModuleLink.objects.create(**validated_data)apps/api/plane/api/views/member.py (2)
121-125: Use HTTP 404 for non-existent workspaceConsistent with the previous comment, return
HTTP_404_NOT_FOUNDfor better RESTful semantics.- if not Workspace.objects.filter(slug=slug).exists(): - return Response( - {"error": "Provided workspace does not exist"}, - status=status.HTTP_400_BAD_REQUEST, - ) + if not Workspace.objects.filter(slug=slug).exists(): + return Response( + {"error": "Provided workspace does not exist"}, + status=status.HTTP_404_NOT_FOUND, + )
127-130: Add project existence checkThe endpoint should verify that the project exists before attempting to query its members, consistent with the workspace check pattern.
Add this check after the workspace validation:
# Check if the project exists if not Project.objects.filter(id=project_id, workspace__slug=slug).exists(): return Response( {"error": "Provided project does not exist"}, status=status.HTTP_404_NOT_FOUND, )Note: You'll need to import the
Projectmodel at the top of the file.apps/api/plane/api/views/state.py (1)
86-108: Extract duplicate external ID validation logicThe external ID duplicate checking logic is repeated in the
patchmethod. Consider extracting this to a reusable method to follow DRY principles.Add a helper method to the class:
def check_external_id_duplicate(self, external_id, external_source, project_id, workspace_slug, exclude_id=None): """Check if an external ID already exists for the given source.""" query = State.objects.filter( project_id=project_id, workspace__slug=workspace_slug, external_source=external_source, external_id=external_id, ) if exclude_id: query = query.exclude(id=exclude_id) existing_state = query.first() if existing_state: return existing_state return NoneThen use it in both
postandpatchmethods.apps/api/plane/api/views/intake.py (1)
332-333: Replace magic numbers with named constants for role checksThe code uses magic numbers (5, 15, 20) for role comparisons without clear meaning.
Define role constants in a central location:
# In a constants file or at the module level class ProjectMemberRole: GUEST = 5 VIEWER = 10 MEMBER = 15 ADMIN = 20 # Then use in the code: if project_member.role <= ProjectMemberRole.GUEST and str(intake_issue.created_by_id) != str(request.user.id): # ... if project_member.role > ProjectMemberRole.MEMBER: # ...Also applies to: 406-406
apps/api/plane/api/serializers/issue.py (1)
31-34: Remove duplicate Django imports and consolidate at the top.These Django imports should be consolidated with the Django imports at lines 1-5 to maintain clean import organization.
# Django imports from django.utils import timezone from lxml import html from django.db import IntegrityError +from django.core.exceptions import ValidationError +from django.core.validators import URLValidator # Third party imports from rest_framework import serializers # Module imports from plane.db.models import ( Issue, IssueType, IssueActivity, IssueAssignee, FileAsset, IssueComment, IssueLabel, IssueLink, Label, ProjectMember, State, User, ) from .base import BaseSerializer from .cycle import CycleLiteSerializer, CycleSerializer from .module import ModuleLiteSerializer, ModuleSerializer from .state import StateLiteSerializer from .user import UserLiteSerializer -# Django imports -from django.core.exceptions import ValidationError -from django.core.validators import URLValidatorapps/api/plane/api/views/module.py (1)
419-421: Use ModuleUpdateSerializer for update operations.The code uses ModuleSerializer for updates, but ModuleUpdateSerializer was imported and should be used for consistency with the pattern established in other endpoints.
-serializer = ModuleSerializer( +serializer = ModuleUpdateSerializer( module, data=request.data, context={"project_id": project_id}, partial=True )apps/api/plane/api/views/issue.py (3)
285-298: API contract inconsistency with external ID filteringThe GET method returns a single issue object when
external_idandexternal_sourceparameters are provided, but returns a paginated response otherwise. This breaks the API contract as the endpoint should always return the same response structure.Consider returning a paginated response with a single item:
if external_id and external_source: - issue = Issue.objects.get( + issues = Issue.objects.filter( external_id=external_id, external_source=external_source, workspace__slug=slug, project_id=project_id, ) - return Response( - IssueSerializer(issue, fields=self.fields, expand=self.expand).data, - status=status.HTTP_200_OK, - ) + return self.paginate( + request=request, + queryset=issues, + on_results=lambda issues: IssueSerializer( + issues, many=True, fields=self.fields, expand=self.expand + ).data, + )
300-386: Extract duplicated ordering logic into a shared methodThe ordering logic for priority, state, labels, and assignees is duplicated between
IssueListCreateAPIEndpoint.get()andIssueDetailAPIEndpoint.get(). This violates the DRY principle.Create a shared method in
BaseAPIViewor a mixin:def apply_issue_ordering(self, queryset, order_by_param): """Apply custom ordering logic for issues""" # Priority Ordering if order_by_param == "priority" or order_by_param == "-priority": priority_order = ["urgent", "high", "medium", "low", "none"] priority_order = ( priority_order if order_by_param == "priority" else priority_order[::-1] ) return queryset.annotate( priority_order=Case( *[ When(priority=p, then=Value(i)) for i, p in enumerate(priority_order) ], output_field=CharField(), ) ).order_by("priority_order") # State Ordering elif order_by_param in ["state__name", "state__group", "-state__name", "-state__group"]: state_order = ["backlog", "unstarted", "started", "completed", "cancelled"] state_order = ( state_order if order_by_param in ["state__name", "state__group"] else state_order[::-1] ) return queryset.annotate( state_order=Case( *[ When(state__group=state_group, then=Value(i)) for i, state_group in enumerate(state_order) ], default=Value(len(state_order)), output_field=CharField(), ) ).order_by("state_order") # assignee and label ordering elif order_by_param in ["labels__name", "-labels__name", "assignees__first_name", "-assignees__first_name"]: return queryset.annotate( max_values=Max( order_by_param[1::] if order_by_param.startswith("-") else order_by_param ) ).order_by( "-max_values" if order_by_param.startswith("-") else "max_values" ) else: return queryset.order_by(order_by_param)Then use it in both endpoints:
issue_queryset = self.apply_issue_ordering(issue_queryset, order_by_param)Also applies to: 574-660
1119-1129: Fix incorrect model check for label external ID validationThe code checks
Issue.objectsinstead ofLabel.objectswhen validating external ID uniqueness for labels.if ( str(request.data.get("external_id")) and (label.external_id != str(request.data.get("external_id"))) - and Issue.objects.filter( + and Label.objects.filter( project_id=project_id, workspace__slug=slug, external_source=request.data.get( "external_source", label.external_source ), external_id=request.data.get("external_id"), ).exists() ):
♻️ Duplicate comments (3)
apps/api/plane/db/models/workspace.py (1)
115-115: Timezone choice optimization already coordinatedThe change from
pytz.all_timezonestopytz.common_timezonesreduces the choice set from ~594 to ~403 options, improving performance while maintaining practical timezone coverage.apps/api/plane/settings/common.py (1)
445-450: Address the unused SPECTACULAR_SETTINGS import.The
SPECTACULAR_SETTINGSis imported but not explicitly used, which could lead to it being ignored by drf-spectacular if not properly registered.Consider explicitly assigning the settings to ensure they're properly registered:
if ENABLE_DRF_SPECTACULAR: REST_FRAMEWORK["DEFAULT_SCHEMA_CLASS"] = "drf_spectacular.openapi.AutoSchema" INSTALLED_APPS.append("drf_spectacular") from .openapi import SPECTACULAR_SETTINGS # noqa: F401 + # Ensure SPECTACULAR_SETTINGS are properly registered + globals().update({"SPECTACULAR_SETTINGS": SPECTACULAR_SETTINGS})apps/api/plane/api/views/asset.py (1)
465-470: Exception handling is implemented securelyThe exception is logged internally for debugging while returning a generic error message to users, which is the correct security practice. The static analysis warning appears to be a false positive.
🧹 Nitpick comments (25)
apps/api/plane/tests/conftest.py (1)
9-12: Rename the shadowed fixture parameter instead of suppressing F811Adding
# noqa: F811silences the redefinition warning, but the parameter namedjango_db_setupstill shadows the fixture you are overriding, which is confusing to readers and linters alike. Prefer renaming the parameter (e.g._django_db_setup) and drop the noqa—clarity beats suppression.-@pytest.fixture(scope="session") -def django_db_setup(django_db_setup): # noqa: F811 +@pytest.fixture(scope="session") +def django_db_setup(_django_db_setup): """Set up the Django database for the test session""" passapps/api/plane/authentication/provider/oauth/github.py (1)
61-61: Triple-quoted f-string is overkill for a one-liner.
A simple single-quoted f-string improves readability.-redirect_uri = f"""{"https" if request.is_secure() else "http"}://{request.get_host()}/auth/github/callback/""" +redirect_uri = f'{"https" if request.is_secure() else "http"}://{request.get_host()}/auth/github/callback/'apps/api/plane/db/models/intake.py (1)
38-44: Good centralization of status constants.The
IntakeIssueStatusenum provides a clean, centralized way to manage intake issue statuses with semantic meaning. This improves maintainability and follows Django best practices.Consider updating the
IntakeIssue.statusfield to use this enum for consistency:status = models.IntegerField( - choices=( - (-2, "Pending"), - (-1, "Rejected"), - (0, "Snoozed"), - (1, "Accepted"), - (2, "Duplicate"), - ), + choices=IntakeIssueStatus.choices, default=-2, )You could also use
default=IntakeIssueStatus.PENDINGfor better semantic clarity.apps/api/plane/db/models/module.py (1)
54-61: Excellent centralization of module status constants.The
ModuleStatusenum provides a clean, semantic way to manage module statuses and improves code maintainability. The text-based choices align well with the existing field values.Consider updating the
Module.statusfield to use this enum for consistency and to eliminate duplication:status = models.CharField( - choices=( - ("backlog", "Backlog"), - ("planned", "Planned"), - ("in-progress", "In Progress"), - ("paused", "Paused"), - ("completed", "Completed"), - ("cancelled", "Cancelled"), - ), + choices=ModuleStatus.choices, default="planned", max_length=20, )You could also use
default=ModuleStatus.PLANNEDfor better semantic clarity.apps/api/plane/api/serializers/project.py (1)
78-91: Consider optimizing database queries in create method.The create method performs multiple database operations that could be optimized. Consider using
get_or_createor bulk operations where appropriate.def create(self, validated_data): identifier = validated_data.get("identifier", "").strip().upper() if identifier == "": raise serializers.ValidationError(detail="Project Identifier is required") - if ProjectIdentifier.objects.filter( - name=identifier, workspace_id=self.context["workspace_id"] - ).exists(): - raise serializers.ValidationError(detail="Project Identifier is taken") + # Use select_for_update to prevent race conditions + if ProjectIdentifier.objects.select_for_update().filter( + name=identifier, workspace_id=self.context["workspace_id"] + ).exists(): + raise serializers.ValidationError(detail="Project Identifier is taken") project = Project.objects.create( **validated_data, workspace_id=self.context["workspace_id"] ) return projectapps/api/plane/utils/openapi/hooks.py (1)
56-56: Consider handling edge cases in method mapping.The fallback method summary is appropriate, but consider adding logging for unmapped methods to help with debugging.
- return method_summaries.get(method, f"{method} {resource}") + summary = method_summaries.get(method, f"{method} {resource}") + # TODO: Consider logging unmapped HTTP methods for debugging + return summaryapps/api/plane/api/serializers/asset.py (1)
106-124: Add trailing comma for consistencyAdd a trailing comma after the last element in the
read_only_fieldslist for better diff readability and consistency with Python best practices.read_only_fields = [ "id", "created_by", "updated_by", "created_at", "updated_at", "workspace", "project", "issue", "comment", "page", "draft_issue", "user", "is_deleted", "deleted_at", "storage_metadata", "asset_url", - ] + ]apps/api/plane/utils/openapi/README.md (3)
7-16: Specify language for fenced code blockAdd a language identifier to the fenced code block for proper syntax highlighting.
-``` +```text plane/utils/openapi/ ├── __init__.py # Main module that re-exports everything ├── auth.py # Authentication extensions ├── parameters.py # Common OpenAPI parameters ├── responses.py # Common OpenAPI responses ├── examples.py # Common OpenAPI examples ├── decorators.py # Helper decorators for different endpoint types └── hooks.py # Schema processing hooks (pre/post processing)
71-71: Remove trailing colon from headingRemove the trailing punctuation from the heading to follow markdown best practices.
-### What was migrated: +### What was migrated
81-81: Remove trailing colon from headingRemove the trailing punctuation from the heading to follow markdown best practices.
-### Files updated: +### Files updatedapps/api/plane/utils/openapi/examples.py (1)
1-817: Consider splitting this file for better maintainabilityThis file contains over 800 lines of example data. Consider splitting it into multiple files organized by domain (e.g.,
examples/issues.py,examples/cycles.py,examples/modules.py) to improve maintainability and make it easier to find specific examples.Example structure:
examples/ ├── __init__.py ├── issues.py # Issue-related examples ├── cycles.py # Cycle-related examples ├── modules.py # Module-related examples ├── assets.py # Asset-related examples └── common.py # Common/shared examplesapps/api/plane/api/views/member.py (1)
128-135: Optimize database queriesThe current implementation makes two separate queries. Consider using a single query with
select_relatedfor better performance.- # Get the workspace members that are present inside the workspace - project_members = ProjectMember.objects.filter( - project_id=project_id, workspace__slug=slug - ).values_list("member_id", flat=True) - - # Get all the users that are present inside the workspace - users = UserLiteSerializer( - User.objects.filter(id__in=project_members), many=True - ).data + # Get project members with user data in a single query + project_members = ProjectMember.objects.filter( + project_id=project_id, workspace__slug=slug + ).select_related("member") + + # Serialize the users + users = UserLiteSerializer( + [pm.member for pm in project_members], many=True + ).dataapps/api/plane/api/urls/module.py (1)
29-30: Consider adding GET method for module-issue detailThe
ModuleIssueDetailAPIEndpointonly supports DELETE operations. Consider adding GET to allow retrieving individual module-issue relationships for consistency with RESTful patterns.- ModuleIssueDetailAPIEndpoint.as_view(http_method_names=["delete"]), + ModuleIssueDetailAPIEndpoint.as_view(http_method_names=["get", "delete"]),apps/api/plane/api/views/state.py (1)
154-154: Remove unnecessary parenthesesThe extra parentheses around
self.get_queryset()are redundant.return self.paginate( request=request, - queryset=(self.get_queryset()), + queryset=self.get_queryset(), on_results=lambda states: StateSerializer(apps/api/plane/api/views/project.py (2)
293-293: Optimize by avoiding redundant database queryThe project is queried again immediately after creation, which is unnecessary since you already have the instance from the serializer.
-project = self.get_queryset().filter(pk=serializer.instance.id).first() +project = serializer.instanceIf you need the annotations from
get_queryset(), consider refactoring to apply them to the single instance rather than querying again.
484-484: Avoid redundant database query after updateSimilar to the create method, this queries the project again unnecessarily.
-project = self.get_queryset().filter(pk=serializer.instance.id).first() +project = serializer.instanceapps/api/plane/api/views/intake.py (1)
407-407: Remove redundant serializer instantiationThe IntakeIssueSerializer is instantiated twice for the same object.
-serializer = IntakeIssueUpdateSerializer( +intake_serializer = IntakeIssueUpdateSerializer( intake_issue, data=request.data, partial=True ) # ... rest of the code ... -serializer = IntakeIssueSerializer(intake_issue) +serializer = IntakeIssueSerializer(intake_issue) return Response(serializer.data, status=status.HTTP_200_OK)Consider reusing the serializer or restructuring the logic to avoid redundancy.
Also applies to: 457-457
apps/api/plane/api/serializers/issue.py (2)
377-422: Robust URL validation with duplicate prevention.The serializer implements comprehensive validation. Consider whether restricting to only http/https schemes is appropriate for all use cases - other schemes like
ftp://,file://, or custom schemes might be valid for issue links.If other URL schemes should be supported, consider making the allowed schemes configurable:
ALLOWED_URL_SCHEMES = getattr(settings, 'ISSUE_LINK_ALLOWED_SCHEMES', ['http://', 'https://']) def validate_url(self, value): # Check URL format validate_url = URLValidator() try: validate_url(value) except ValidationError: raise serializers.ValidationError("Invalid URL format.") # Check URL scheme if not any(value.startswith(scheme) for scheme in ALLOWED_URL_SCHEMES): raise serializers.ValidationError(f"URL must start with one of: {', '.join(ALLOWED_URL_SCHEMES)}") return value
689-705: Consider field naming consistency with URL patterns.The field names
project__identifierandworkspace__sluguse double underscores, but according to the AI summary, URL parameters were standardized to use single underscores. Consider usingproject_identifierandworkspace_slugfor consistency.class IssueSearchSerializer(serializers.Serializer): """ Serializer for work item search result data formatting. Provides standardized search result structure including work item identifiers, project context, and workspace information for search API responses. """ id = serializers.CharField(required=True, help_text="Issue ID") name = serializers.CharField(required=True, help_text="Issue name") sequence_id = serializers.CharField(required=True, help_text="Issue sequence ID") - project__identifier = serializers.CharField( + project_identifier = serializers.CharField( required=True, help_text="Project identifier" ) project_id = serializers.CharField(required=True, help_text="Project ID") - workspace__slug = serializers.CharField(required=True, help_text="Workspace slug") + workspace_slug = serializers.CharField(required=True, help_text="Workspace slug")apps/api/plane/api/views/cycle.py (2)
962-963: Fix comment to match the actual model name.The comment refers to "CycleWorkItems" but the code uses "CycleIssue".
-# Get all CycleWorkItems already created +# Get all CycleIssues already created cycle_issues = list( CycleIssue.objects.filter(~Q(cycle_id=cycle_id), issue_id__in=issues) )
1192-1636: Consider refactoring this extensive method for better maintainability.This 400+ line method handles multiple responsibilities: validation, analytics calculation, progress snapshot creation, and issue transfer. Consider extracting helper methods for:
- Analytics calculation (estimate and issue distribution)
- Progress snapshot generation
- Issue transfer logic
This would improve readability and testability.
apps/api/plane/utils/openapi/decorators.py (2)
13-26: Consider improving the merge function implementationThe current implementation reassigns
kwargsafter removing keys, which works but could be cleaner. Also, directly mutating thedefaultsdictionary could cause issues if it's reused.Consider this cleaner implementation:
def _merge_schema_options(defaults, kwargs): """Helper function to merge responses and parameters from kwargs into defaults""" + # Create a copy to avoid mutating the original defaults + merged = defaults.copy() + # Merge responses if "responses" in kwargs: - defaults["responses"].update(kwargs["responses"]) - kwargs = {k: v for k, v in kwargs.items() if k != "responses"} + merged["responses"] = {**defaults.get("responses", {}), **kwargs["responses"]} # Merge parameters if "parameters" in kwargs: - defaults["parameters"].extend(kwargs["parameters"]) - kwargs = {k: v for k, v in kwargs.items() if k != "parameters"} + merged["parameters"] = defaults.get("parameters", []) + kwargs["parameters"] - defaults.update(kwargs) - return defaults + # Add remaining kwargs (excluding responses and parameters) + merged.update({k: v for k, v in kwargs.items() if k not in ["responses", "parameters"]}) + return mergedThis approach:
- Creates a copy to avoid side effects
- Uses cleaner syntax without reassigning kwargs
- Handles missing keys more gracefully
87-99: Ensure consistent tag naming for work item related endpointsThere's inconsistency in tag naming for work item related endpoints:
- Line 90:
"tags": ["Work Items"]- Line 135:
"tags": ["Work Items"]- Line 165:
"tags": ["Work Item Links"]- Line 180:
"tags": ["Work Item Comments"]- Line 195:
"tags": ["Work Item Activity"]- Line 210:
"tags": ["Work Item Attachments"]Consider standardizing to either singular or plural form consistently. The current mix might confuse API consumers when filtering by tags.
Also applies to: 132-144, 163-174, 177-189, 192-204, 207-219
apps/api/plane/utils/openapi/parameters.py (1)
35-40: Consider using unique example UUIDs for different entity typesAll UUID parameters use the same example value "550e8400-e29b-41d4-a716-446655440000". Using different values would make the examples more realistic and help distinguish between entity types in the documentation.
For example:
- Project:
"550e8400-e29b-41d4-a716-446655440000"- Asset:
"660e8400-e29b-41d4-a716-446655440001"- Cycle:
"770e8400-e29b-41d4-a716-446655440002"- Module:
"880e8400-e29b-41d4-a716-446655440003"- Issue:
"990e8400-e29b-41d4-a716-446655440004"Also applies to: 49-54, 94-99, 109-114, 125-129, 141-144, 155-159, 170-174, 186-190, 201-205, 216-220, 231-235, 246-250, 430-433
apps/api/plane/api/views/issue.py (1)
912-912: Standardize terminology in error messagesError messages inconsistently use "work item" vs "Issue":
- Line 912: "Only admin or creator can delete the work item"
- Line 1540: "Work item comment with the same external id..."
- Line 1697: "Work item comment with the same external id..."
While other parts of the code use "Issue".
Consider standardizing to either "work item" or "issue" throughout the codebase for consistency. Since the API documentation uses "Work Items" in tags, "work item" might be the preferred term.
Also applies to: 1540-1540, 1697-1697
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (64)
apps/api/plane/api/apps.py(1 hunks)apps/api/plane/api/serializers/__init__.py(1 hunks)apps/api/plane/api/serializers/asset.py(1 hunks)apps/api/plane/api/serializers/base.py(1 hunks)apps/api/plane/api/serializers/cycle.py(5 hunks)apps/api/plane/api/serializers/estimate.py(1 hunks)apps/api/plane/api/serializers/intake.py(2 hunks)apps/api/plane/api/serializers/issue.py(8 hunks)apps/api/plane/api/serializers/module.py(5 hunks)apps/api/plane/api/serializers/project.py(2 hunks)apps/api/plane/api/serializers/state.py(2 hunks)apps/api/plane/api/serializers/user.py(1 hunks)apps/api/plane/api/serializers/workspace.py(1 hunks)apps/api/plane/api/urls/__init__.py(1 hunks)apps/api/plane/api/urls/asset.py(1 hunks)apps/api/plane/api/urls/cycle.py(1 hunks)apps/api/plane/api/urls/intake.py(1 hunks)apps/api/plane/api/urls/issue.py(1 hunks)apps/api/plane/api/urls/member.py(1 hunks)apps/api/plane/api/urls/module.py(1 hunks)apps/api/plane/api/urls/project.py(1 hunks)apps/api/plane/api/urls/schema.py(1 hunks)apps/api/plane/api/urls/state.py(1 hunks)apps/api/plane/api/urls/user.py(1 hunks)apps/api/plane/api/views/__init__.py(1 hunks)apps/api/plane/api/views/asset.py(1 hunks)apps/api/plane/api/views/base.py(2 hunks)apps/api/plane/api/views/cycle.py(17 hunks)apps/api/plane/api/views/intake.py(8 hunks)apps/api/plane/api/views/issue.py(34 hunks)apps/api/plane/api/views/member.py(1 hunks)apps/api/plane/api/views/module.py(13 hunks)apps/api/plane/api/views/project.py(9 hunks)apps/api/plane/api/views/state.py(5 hunks)apps/api/plane/api/views/user.py(1 hunks)apps/api/plane/app/permissions/project.py(1 hunks)apps/api/plane/app/views/analytic/advance.py(0 hunks)apps/api/plane/app/views/workspace/cycle.py(0 hunks)apps/api/plane/authentication/provider/oauth/github.py(1 hunks)apps/api/plane/bgtasks/issue_activities_task.py(0 hunks)apps/api/plane/db/management/commands/update_deleted_workspace_slug.py(0 hunks)apps/api/plane/db/models/cycle.py(1 hunks)apps/api/plane/db/models/intake.py(1 hunks)apps/api/plane/db/models/module.py(1 hunks)apps/api/plane/db/models/project.py(1 hunks)apps/api/plane/db/models/user.py(1 hunks)apps/api/plane/db/models/workspace.py(2 hunks)apps/api/plane/settings/common.py(2 hunks)apps/api/plane/settings/openapi.py(1 hunks)apps/api/plane/space/serializer/__init__.py(1 hunks)apps/api/plane/tests/conftest.py(1 hunks)apps/api/plane/tests/conftest_external.py(0 hunks)apps/api/plane/tests/contract/app/test_authentication.py(1 hunks)apps/api/plane/tests/unit/models/test_workspace_model.py(1 hunks)apps/api/plane/urls.py(2 hunks)apps/api/plane/utils/openapi/README.md(1 hunks)apps/api/plane/utils/openapi/__init__.py(1 hunks)apps/api/plane/utils/openapi/auth.py(1 hunks)apps/api/plane/utils/openapi/decorators.py(1 hunks)apps/api/plane/utils/openapi/examples.py(1 hunks)apps/api/plane/utils/openapi/hooks.py(1 hunks)apps/api/plane/utils/openapi/parameters.py(1 hunks)apps/api/plane/utils/openapi/responses.py(1 hunks)apps/api/requirements/base.txt(1 hunks)
💤 Files with no reviewable changes (5)
- apps/api/plane/db/management/commands/update_deleted_workspace_slug.py
- apps/api/plane/app/views/workspace/cycle.py
- apps/api/plane/tests/conftest_external.py
- apps/api/plane/bgtasks/issue_activities_task.py
- apps/api/plane/app/views/analytic/advance.py
🧰 Additional context used
🧠 Learnings (19)
apps/api/plane/tests/unit/models/test_workspace_model.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/urls/member.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/app/permissions/project.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/space/serializer/__init__.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/db/models/project.py (1)
Learnt from: vamsikrishnamathala
PR: #6820
File: web/core/hooks/use-timezone-converter.tsx:19-39
Timestamp: 2025-03-26T07:22:45.741Z
Learning: In the Plane project, the getProjectUTCOffset function in the timezone converter hook is designed to return undefined when there is no difference between the project's timezone and UTC (when offset is 0).
apps/api/plane/api/serializers/workspace.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/project.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/__init__.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/db/models/workspace.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/module.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/intake.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/asset.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/views/intake.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/cycle.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/views/project.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/views/member.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/urls/issue.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/serializers/issue.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
apps/api/plane/api/views/issue.py (1)
Learnt from: NarayanBavisetti
PR: #7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
🧬 Code Graph Analysis (1)
apps/api/plane/utils/openapi/responses.py (1)
apps/api/plane/utils/openapi/examples.py (1)
get_sample_for_schema(801-816)
🪛 markdownlint-cli2 (0.17.2)
apps/api/plane/utils/openapi/README.md
7-7: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
71-71: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
81-81: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🔇 Additional comments (87)
apps/api/plane/tests/unit/models/test_workspace_model.py (1)
4-4: ✅ UnusedUserimport safely removed
Userwasn’t referenced in this test, so dropping it tightens the import list without side-effects. LGTM.apps/api/plane/authentication/provider/oauth/github.py (2)
21-21: Unnecessary f-string successfully removed – nice micro-cleanup.
The constant no longer incurs the runtime cost of evaluating an f-string, improving clarity.
131-135: Verify auth scheme & add timeout for org-membership check.
- GitHub accepts both
tokenandBearerschemes depending on the token type; confirm the correct one for OAuth-app tokens.- Include a
timeoutto avoid blocking.-headers = {"Authorization": f"Bearer {self.token_data.get('access_token')}"} +headers = { + "Authorization": f"Bearer {self.token_data.get('access_token')}", # change to 'token' if required + "Accept": "application/json", +} ... -response = requests.get( +response = requests.get( f"{self.org_membership_url}/{self.organization_id}/memberships/{github_username}", - headers=headers, + headers=headers, + timeout=5, )apps/api/plane/tests/contract/app/test_authentication.py (1)
9-9: Good cleanup of unused import.The removal of
MagicMockimport is correct - all the test methods use thepatchdecorator which provides standard Mock objects that are sufficient for the test assertions being performed.apps/api/plane/db/models/user.py (1)
104-104: Excellent improvement to timezone choices.Switching from
pytz.all_timezonestopytz.common_timezonesis a smart decision that:
- Reduces choice overload for users (from ~590 to ~400 options)
- Eliminates deprecated and obscure timezones
- Maintains consistency with similar changes in other models
This change is backward compatible and follows timezone selection best practices.
apps/api/plane/db/models/cycle.py (1)
74-74: Consistent timezone standardization.The change to
pytz.common_timezonesaligns with the broader timezone standardization effort across models. This is particularly beneficial for cycles since they manage time-sensitive start and end dates.apps/api/plane/api/serializers/base.py (1)
6-11: Excellent documentation addition.The comprehensive docstring clearly explains the BaseSerializer's key features and purpose. This is particularly valuable given that this is a foundational class used throughout the application. The documentation accurately reflects the implementation and aligns with the broader API documentation enhancements in this PR.
apps/api/plane/api/apps.py (1)
7-12: Proper Django app initialization pattern.The
ready()method implementation follows Django best practices:
- Correctly imports the OpenAPI auth module for side-effect registration
- Uses appropriate try-except handling to prevent startup failures
- Includes proper
# noqacomment for the intentionally unused importThis aligns well with the broader OpenAPI integration effort described in the PR.
apps/api/plane/db/models/project.py (1)
123-123: Good improvement: Switching to common timezones for better UX.This change from
pytz.all_timezonestopytz.common_timezonesis a practical improvement that reduces the timezone choices to a more manageable and user-friendly subset. This aligns with similar changes across other models (Cycle, User, Workspace) for consistency and improves the user experience by removing obscure/deprecated timezone options.apps/api/plane/api/urls/__init__.py (1)
8-9: Clean integration of new URL patterns.The addition of asset and user URL patterns follows the established pattern and supports the new asset management and user profile API endpoints mentioned in the PR objectives. The placement is logical with asset patterns at the beginning and user patterns at the end.
Also applies to: 12-12, 20-20
apps/api/requirements/base.txt (1)
68-69: drf-spectacular version is up to dateThe project specifies
drf-spectacular==0.28.0(apps/api/requirements/base.txt, lines 68–69), which matches the latest stable release on PyPI as of November 30, 2024. No update is required.apps/api/plane/api/urls/state.py (1)
3-6: Excellent RESTful API restructuring.The separation of state endpoints into distinct list-create and detail operations with explicit HTTP method restrictions follows excellent RESTful design principles. This improves API clarity, security, and aligns with the broader API restructuring effort described in the PR objectives.
Also applies to: 11-11, 16-16
apps/api/plane/space/serializer/__init__.py (1)
3-3: Good cleanup: Removing unnecessary serializer imports.The removal of
StateLiteSerializerfrom both.issueand.statemodule imports is a good cleanup that reduces unnecessary dependencies and aligns with the broader serializer modularization effort described in the PR objectives.Also applies to: 5-5
apps/api/plane/api/urls/member.py (1)
8-8: Good restriction to GET-only methods.The explicit restriction to GET methods aligns well with the refactoring effort to separate concerns and remove member creation functionality from this endpoint.
apps/api/plane/api/serializers/estimate.py (1)
7-12: Excellent documentation enhancement.The detailed docstring clearly explains the serializer's purpose and context, making it easier for developers to understand how estimation points are used in sprint planning and velocity calculations.
apps/api/plane/api/urls/user.py (1)
1-11: Clean and well-structured user endpoint configuration.The URL pattern follows REST conventions with "users/me/" for current user profile access, appropriately restricted to GET requests. This fits well with the API restructuring objectives.
apps/api/plane/db/models/workspace.py (1)
3-3: LGTM: Clean import optimizationGood cleanup removing unused type imports (
Tuple,Dict) and other unused imports mentioned in the summary. This improves code maintainability and reduces unnecessary dependencies.apps/api/plane/app/permissions/project.py (1)
78-83: LGTM: Consistent project identifier attribute namingThe change from
project__identifiertoproject_identifierstandardizes the view attribute naming and aligns with the broader API refactoring. The permission logic remains functionally equivalent while improving consistency across the codebase.apps/api/plane/api/serializers/workspace.py (1)
7-12: Excellent documentation enhancementThe expanded docstring clearly explains the serializer's purpose, scope, and intended use cases. This improves API discoverability and aligns with the comprehensive OpenAPI documentation improvements across the codebase.
apps/api/plane/api/urls/intake.py (2)
3-6: LGTM: Proper endpoint separationSplitting the monolithic endpoint into specialized
ListCreateandDetailendpoints follows RESTful design principles and improves code organization as outlined in the PR objectives.
12-19: Excellent HTTP method restrictionsExplicitly restricting HTTP methods per endpoint (
GET/POSTfor collection,GET/PATCH/DELETEfor individual resources) improves API clarity and security by preventing unintended operations.apps/api/plane/api/views/user.py (3)
14-17: LGTM: Clean class structureThe endpoint class follows Django REST framework best practices with proper inheritance from
BaseAPIViewand clear model/serializer declarations.
18-29: Excellent OpenAPI documentationComprehensive OpenAPI decoration with operation ID, summary, description, and response examples. This exemplifies the thorough documentation approach mentioned in the PR objectives and improves API discoverability.
30-37: Simple and effective implementationThe GET method implementation is straightforward and secure, using the authenticated user from the request context. The clear docstring and proper status code usage follow best practices.
apps/api/plane/api/urls/schema.py (1)
1-21: Well-structured OpenAPI schema configuration.The URL configuration follows drf-spectacular best practices with proper endpoint separation and correct view references. The schema UI views correctly reference the base schema endpoint by name, enabling proper documentation generation.
apps/api/plane/api/views/base.py (2)
16-16: Excellent foundation for the API refactoring.The switch from
APIViewtoGenericAPIViewprovides the necessary foundation for the endpoint separation strategy mentioned in the PR objectives. This enables better support for mixins, serializer integration, and the granular view classes being introduced.
39-39: Proper inheritance structure maintained.The class definition correctly maintains the existing mixin and paginator functionality while upgrading to the more capable
GenericAPIViewbase class.apps/api/plane/urls.py (2)
5-9: Good import organization for optional feature.The drf-spectacular imports are properly organized and will only be used when the feature is enabled.
22-35: Excellent feature gating implementation.The conditional inclusion of schema URLs based on
ENABLE_DRF_SPECTACULARis a best practice for optional features. The URL structure follows standard conventions and maintains consistency with the schema configuration.apps/api/plane/api/urls/project.py (2)
3-7: Improved endpoint separation aligns with PR objectives.The split from a single generic endpoint to specific list/create, detail, and archive/unarchive endpoints exemplifies the refactoring goals mentioned in the PR summary. This separation improves maintainability and follows RESTful design principles.
10-27: Excellent HTTP method restrictions and URL structure.The explicit
http_method_namesrestrictions provide clear API boundaries and improve security. The URL patterns are now more RESTful and self-documenting with proper separation of concerns.apps/api/plane/api/serializers/state.py (3)
7-12: Excellent documentation for StateSerializer.The comprehensive docstring clearly explains the serializer's role in state management, including its handling of default state validation and automatic switching behavior. This improves code maintainability and developer understanding.
34-34: Proper field protection for slug.Adding
slugtoread_only_fieldsprevents unintended modification of this system-generated field, which is a good security and data integrity practice.
39-44: Clear documentation for lightweight serializer.The docstring effectively communicates the StateLiteSerializer's purpose for minimal data transfer and UI optimization, helping developers choose the appropriate serializer for their use case.
apps/api/plane/api/urls/asset.py (1)
9-40: Excellent RESTful URL structure with proper HTTP method restrictions.The URL patterns demonstrate good separation of concerns:
- Clear distinction between creation endpoints (POST only) and detail endpoints (PATCH/DELETE or GET/PATCH)
- Consistent naming conventions for user assets, user server assets, and generic workspace assets
- Appropriate use of UUID parameters for asset identification and string slugs for workspace identification
The explicit HTTP method restrictions using
http_method_namesparameter enhance security by preventing unintended HTTP methods on each endpoint.apps/api/plane/api/serializers/user.py (1)
10-20: Well-documented serializer enhancement.The added docstring clearly explains the serializer's purpose and use cases, and the new
avatar_urlfield with proper help text enhances the API's functionality for avatar handling.apps/api/plane/api/urls/cycle.py (2)
3-10: Excellent endpoint refactoring for better separation of concerns.The import changes reflect the proper splitting of monolithic endpoints into focused, method-specific classes that follow single responsibility principle.
13-52: Well-structured RESTful URL patterns with explicit HTTP method restrictions.The refactoring demonstrates several improvements:
- Clear separation: List/create operations are distinct from detail operations
- Explicit methods: Each endpoint clearly defines allowed HTTP methods
- Consistent patterns: All cycle-related endpoints follow the same structural approach
- Enhanced functionality: New archived cycles endpoints provide additional capabilities
The URL structure aligns perfectly with REST principles and improves API maintainability.
apps/api/plane/api/views/__init__.py (1)
1-56: Comprehensive import reorganization reflecting improved API architecture.The expanded and reorganized imports demonstrate the successful modularization of the API:
- Granular separation: Monolithic endpoints split into focused list/create and detail classes
- Enhanced coverage: New domains added (assets, intake, user endpoints)
- Clear structure: Import organization makes the API's capabilities immediately apparent
- Consistent patterns: All resource types follow the same separation approach
This centralized import structure serves as an excellent overview of the refactored API's capabilities and maintains clean separation of concerns.
apps/api/plane/settings/common.py (1)
78-80: Good addition for preserving original URL parameter names.The
SCHEMA_COERCE_PATH_PK: Falsesetting is valuable for maintaining consistency between Django URL patterns and generated API schemas, preventing automatic conversion of "pk" parameters to "id".apps/api/plane/api/serializers/__init__.py (4)
3-8: LGTM! Proper serializer exposure for project operations.The addition of
ProjectCreateSerializerandProjectUpdateSerializeraligns well with the API refactoring goals of separating concerns between create and update operations.
11-24: Comprehensive issue serializer imports support enhanced functionality.The expanded issue serializer imports provide good separation of concerns with dedicated serializers for different operations (create, update, upload, search). This modular approach improves maintainability.
26-47: Well-structured module imports follow consistent patterns.The cycle, module, and intake serializer imports follow a consistent naming pattern with dedicated create/update serializers, which supports the overall API restructuring effort.
49-55: New asset management serializers enhance file handling capabilities.The asset serializer imports support the new presigned URL functionality mentioned in the PR objectives, providing secure file upload workflows.
apps/api/plane/settings/openapi.py (4)
7-32: Well-structured basic API configuration with appropriate settings.The API metadata is comprehensive and the schema generation settings are properly configured. Disabling caching (
SCHEMA_CACHE_TIMEOUT: 0) is appropriate for development but consider enabling it in production for performance.
49-256: Excellent and comprehensive API tag documentation.The tag definitions are exceptionally well-written with clear descriptions, key features, and use cases. This will greatly improve API discoverability and developer experience.
268-271: Enum overrides configuration is well-structured.The enum name overrides for
ModuleStatusEnumandIntakeWorkItemStatusEnumprovide better OpenAPI schema readability.
260-262: Verification complete: authentication class path is correct.The
plane.api.middleware.api_authentication.APIKeyAuthenticationclass is defined inapps/api/plane/api/middleware/api_authentication.pyand matches the whitelist entry. No further changes are needed.apps/api/plane/utils/openapi/auth.py (2)
11-29: Well-implemented API key authentication extension.The
APIKeyAuthenticationExtensionis properly configured with appropriate security definition for API key authentication via theX-API-Keyheader.
32-49: Proper bearer token authentication configuration.The
APITokenAuthenticationExtensioncorrectly implements bearer token authentication with appropriate OpenAPI security definition.apps/api/plane/api/serializers/project.py (6)
5-11: Appropriate model imports for enhanced validation.The additional imports (
ProjectIdentifier,WorkspaceMember,State,Estimate) support the enhanced validation logic in the new serializers.
16-54: Well-structured ProjectCreateSerializer with comprehensive field definition.The serializer properly defines all necessary fields for project creation with appropriate read-only field restrictions.
55-76: Robust validation for workspace membership.The validation logic properly ensures both project lead and default assignee are workspace members. This aligns with the retrieved learning about workspace member validation in the Plane codebase.
94-135: Excellent ProjectUpdateSerializer with proper validation extensions.The update serializer properly extends the create serializer and adds specific validation for default state and estimate references. The validation logic correctly ensures referenced objects belong to the project.
138-143: Good documentation addition to existing ProjectSerializer.The added docstring clearly describes the serializer's purpose and functionality.
218-223: Appropriate documentation for ProjectLiteSerializer.The docstring accurately describes the lightweight nature and intended use cases of this serializer.
apps/api/plane/utils/openapi/hooks.py (4)
10-23: Solid endpoint filtering logic with minor suggestions.The filtering function correctly targets
/api/v1/paths and excludes unwanted methods and server paths. The logic is sound and performant.
26-36: Robust path processing with good edge case handling.The path parsing logic properly handles empty parts and parameter placeholders. The fallback to using the tag when no path parts are found is a good defensive programming practice.
38-44: Complete HTTP method coverage with clear mappings.The method summary mappings cover all standard HTTP methods with appropriate action verbs.
46-54: Smart special case handling for archive and transfer operations.The special handling for archive/unarchive and transfer operations provides more intuitive operation summaries. The
rstrip("s")approach for singularizing tag names is simple and effective for most cases.apps/api/plane/api/serializers/asset.py (2)
41-52: LGTM!The AssetUpdateSerializer is well-designed with appropriate use of JSONField for flexible attribute storage.
80-91: LGTM!The GenericAssetUpdateSerializer is simple and well-designed for its purpose.
apps/api/plane/api/serializers/intake.py (5)
8-33: LGTM!The IssueForIntakeSerializer is well-designed with appropriate field selection and read-only constraints for audit fields.
35-65: LGTM!The IntakeIssueCreateSerializer properly implements nested serialization with clear field definitions and appropriate read-only constraints.
67-91: LGTM!Excellent addition of the docstring to improve documentation. The serializer properly handles expanded issue details and intake relationships.
93-124: LGTM!The IntakeIssueUpdateSerializer correctly implements partial update functionality with optional nested issue updates.
126-141: LGTM!The IssueDataSerializer appropriately uses a plain serializer for request validation with proper field constraints and choice validation.
apps/api/plane/api/serializers/module.py (3)
198-220: LGTM!The ModuleIssueSerializer is well-documented and properly structured for managing module-issue relationships.
254-265: LGTM!The ModuleLiteSerializer is well-documented and appropriately designed for lightweight data transfer.
267-279: LGTM!The ModuleIssueRequestSerializer is well-designed for bulk issue assignment operations with proper validation.
apps/api/plane/utils/openapi/examples.py (1)
801-817: LGTM!The
get_sample_for_schemafunction is well-implemented with proper handling of paginated response schemas.apps/api/plane/api/serializers/cycle.py (2)
11-81: Well-structured timezone-aware serializerThe
CycleCreateSerializerimplementation is excellent with proper timezone handling, date validation, and UTC conversion. The separation of concerns and comprehensive validation logic follows best practices.
98-185: Well-designed serializer architectureThe remaining serializers (
CycleSerializer,CycleIssueSerializer,CycleLiteSerializer,CycleIssueRequestSerializer, andTransferCycleIssueRequestSerializer) are well-structured with clear separation of concerns, comprehensive documentation, and appropriate field definitions for their respective use cases.apps/api/plane/api/views/asset.py (1)
405-630: Well-implemented generic asset managementThe
GenericAssetEndpointimplementation is comprehensive with proper validation, external ID conflict detection, workspace verification, and secure presigned URL generation. The error handling is appropriately granular.apps/api/plane/utils/openapi/responses.py (1)
378-378: Ignore unnecessary serializer-instantiation concernWe’ve verified that no serializers passed into
create_paginated_responseoverride__init__to require positional arguments—every one inherits DRF’s default signature, which defaults all parameters. Instantiating withitem_schema()is safe for spectacular’s schema generation.Likely an incorrect or invalid review comment.
apps/api/plane/api/serializers/issue.py (7)
37-43: Excellent documentation addition!The comprehensive docstring clearly explains the serializer's purpose and capabilities, improving code maintainability.
309-316: Clear and concise documentation for the lightweight serializer.The docstring effectively communicates the performance-oriented purpose of this serializer.
323-353: Well-structured serializer following REST best practices.The separation of create/update operations into a dedicated serializer improves API clarity and follows the single responsibility principle.
354-361: Good documentation that clarifies the serializer's comprehensive nature.The docstring effectively distinguishes this full serializer from the create/update variant.
454-476: Clean implementation of the full link serializer.Follows the established pattern of having dedicated serializers for different operations.
477-667: Comprehensive documentation improvements across all serializers.The consistent addition of descriptive docstrings significantly improves code maintainability and API documentation.
669-688: Well-designed file upload validation serializer.The serializer provides clear field documentation and validates essential metadata before file upload operations.
apps/api/plane/api/views/cycle.py (1)
171-288: Well-structured cycle filtering with comprehensive statistics.The implementation provides flexible filtering options and detailed issue count annotations. The pagination is properly applied to all views except "current" which returns all current cycles.
apps/api/plane/api/urls/issue.py (1)
20-95: Excellent URL restructuring with clear HTTP method restrictions.The refactoring improves API clarity by:
- Explicitly defining allowed HTTP methods for each endpoint
- Separating list/create from detail operations
- Adding semantic search functionality
- Maintaining consistent parameter naming with single underscores
apps/api/plane/api/views/module.py (1)
546-915: Well-implemented module issue management endpoints.The module issue endpoints follow consistent patterns with proper:
- Bulk operation handling
- Activity tracking
- Permission checks
- Optimized querysets with annotations
apps/api/plane/api/views/issue.py (2)
149-223: Well-structured workspace-level issue retrieval endpointThe refactored
WorkspaceIssueAPIEndpointwith proper OpenAPI documentation and clear parameter handling is a significant improvement. The endpoint now properly uses project and issue identifiers for workspace-level access.
2258-2333: Well-implemented semantic search functionalityThe new
IssueSearchEndpointprovides excellent search capabilities with:
- Smart regex matching for sequence IDs
- Flexible workspace/project scoping
- Efficient query construction using Q objects
The implementation is clean and follows best practices.
…esponse handling, removing redundant external ID checks and custom ordering logic.
|
Pull Request Linked with Plane Work Items Comment Automatically Generated by Plane |
…inability (#7477) * Basic setup for drf-spectacular * Updated to only handle /api/v1 endpoints * feat: add asset and user endpoints with URL routing - Introduced new asset-related endpoints for user assets and server assets, allowing for asset uploads and management. - Added user endpoint to retrieve current user information. - Updated URL routing to include new asset and user patterns. - Enhanced issue handling with a new search endpoint for issues across multiple fields. - Expanded member management with a new endpoint for workspace members. * Group endpoints by tags * Detailed schema definitions and examples for asset endpoints * Removed unnecessary extension * Specify avatar_url field separately * chore: add project docs * chore: correct all errors * chore: added open spec in work items * feat: enhance cycle API endpoints with detailed OpenAPI specifications - Updated CycleAPIEndpoint and CycleIssueAPIEndpoint to include detailed OpenAPI schema definitions for GET, POST, PATCH, and DELETE operations. - Specified allowed HTTP methods for each endpoint in the URL routing. - Improved documentation for cycle creation, updating, and deletion, including request and response examples. * chore: added open spec in labels * chore: work item properties * feat: enhance API endpoints with OpenAPI specifications and HTTP method definitions - Added detailed OpenAPI schema definitions for various API endpoints including Intake, Module, and State. - Specified allowed HTTP methods for each endpoint in the URL routing for better clarity and documentation. - Improved request and response examples for better understanding of API usage. - Introduced unarchive functionality for cycles and modules with appropriate endpoint definitions. * chore: run formatter * Removed unnecessary settings for authentication * Refactors OpenAPI documentation structure Improves the organization and maintainability of the OpenAPI documentation by modularizing the `openapi_spec_helpers.py` file. The changes include: - Migrates common parameters, responses, examples, and authentication extensions to separate modules. - Introduces helper decorators for different endpoint types. - Updates view imports to use the new module paths. - Removes the legacy `openapi_spec_helpers.py` file. This refactoring results in a more structured and easier-to-maintain OpenAPI documentation setup. * Refactor OpenAPI endpoint specifications - Removed unnecessary parameters from the OpenAPI documentation for various endpoints in the asset, cycle, and project views. - Updated request structures to improve clarity and consistency across the API documentation. - Enhanced response formatting for better readability and maintainability. * Enhance API documentation with detailed endpoint descriptions Updated various API endpoints across the application to include comprehensive docstrings that clarify their functionality. Each endpoint now features a summary and detailed description, improving the overall understanding of their purpose and usage. This change enhances the OpenAPI specifications for better developer experience and documentation clarity. * Enhance API serializers and views with new request structures - Added new serializers for handling cycle and module issue requests, including `CycleIssueRequestSerializer`, `TransferCycleIssueRequestSerializer`, `ModuleIssueRequestSerializer`, and intake issue creation/updating serializers. - Updated existing serializers to improve clarity and maintainability, including the `UserAssetUploadSerializer` and `IssueAttachmentUploadSerializer`. - Refactored API views to utilize the new serializers, enhancing the request handling for cycle and intake issue endpoints. - Improved OpenAPI documentation by replacing inline request definitions with serializer references for better consistency and readability. * Refactor OpenAPI documentation and endpoint specifications - Replaced inline schema definitions with dedicated decorators for various endpoint types, enhancing clarity and maintainability. - Updated API views to utilize new decorators for user, cycle, intake, module, and project endpoints, improving consistency in OpenAPI documentation. - Removed unnecessary parameters and responses from endpoint specifications, streamlining the documentation for better readability. - Enhanced the organization of OpenAPI documentation by modularizing endpoint-specific decorators and parameters. * chore: correct formatting * chore: correct formatting for all api folder files * refactor: clean up serializer imports and test setup - Removed unused `StateLiteSerializer` import from the serializer module. - Updated test setup to include a noqa comment for the `django_db_setup` fixture, ensuring clarity in the code. - Added missing commas in user data dictionary for consistency. * feat: add project creation and update serializers with validation - Introduced `ProjectCreateSerializer` and `ProjectUpdateSerializer` to handle project creation and updates, respectively. - Implemented validation to ensure project leads and default assignees are members of the workspace. - Updated API views to utilize the new serializers for creating and updating projects, enhancing request handling. - Added OpenAPI documentation references for the new serializers in the project API endpoints. * feat: update serializers to include additional read-only fields * refactor: rename intake issue serializers and enhance structure - Renamed `CreateIntakeIssueRequestSerializer` to `IntakeIssueCreateSerializer` and `UpdateIntakeIssueRequestSerializer` to `IntakeIssueUpdateSerializer` for clarity. - Introduced `IssueSerializer` for nested issue data in intake requests, improving the organization of serializer logic. - Updated API views to utilize the new serializer names, ensuring consistency across the codebase. * refactor: rename issue serializer for intake and enhance API documentation - Renamed `IssueSerializer` to `IssueForIntakeSerializer` for better clarity in the context of intake issues. - Updated references in `IntakeIssueCreateSerializer` and `IntakeIssueUpdateSerializer` to use the new `IssueForIntakeSerializer`. - Added OpenAPI documentation for the `get_workspace_work_item` endpoint, detailing parameters and responses for improved clarity. * chore: modules and cycles serializers * feat: add new serializers for label and issue link management - Introduced `LabelCreateUpdateSerializer`, `IssueLinkCreateSerializer`, `IssueLinkUpdateSerializer`, and `IssueCommentCreateSerializer` to enhance the handling of label and issue link data. - Updated existing API views to utilize the new serializers for creating and updating labels, issue links, and comments, improving request handling and validation. - Added `IssueSearchSerializer` for searching issues, streamlining the search functionality in the API. * Don't consider read only fields as required * Add setting to separate request and response definitions * Fixed avatar_url warning on openapi spec generation * Made spectacular disabled by default * Moved spectacular settings into separate file and added detailed descriptions to tags * Specify methods for asset urls * Better server names * Enhance API documentation with summaries for various endpoints - Added summary descriptions for user asset, cycle, intake, issue, member, module, project, state, and user API endpoints to improve clarity and usability of the API documentation. - Updated the OpenAPI specifications to reflect these changes, ensuring better understanding for developers interacting with the API. * Add contact information to OpenAPI settings - Included contact details for Plane in the OpenAPI settings to enhance API documentation and provide developers with a direct point of contact for support. - This addition aims to improve the overall usability and accessibility of the API documentation. * Reordered tags and improved description relavancy * Enhance OpenAPI documentation for cycle and issue endpoints - Added response definitions for the `get_cycle_issues` and `delete_cycle_issue` methods in the CycleIssueAPIEndpoint to clarify expected outcomes. - Included additional response codes for the IssueSearchEndpoint to handle various error scenarios, improving the overall API documentation and usability. * Enhance serializer documentation across multiple files - Updated docstrings for various serializers including UserAssetUploadSerializer, AssetUpdateSerializer, and others to provide clearer descriptions of their functionality and usage. - Improved consistency in formatting and language across serializer classes to enhance readability and maintainability. - Added detailed explanations for new serializers related to project, module, and cycle management, ensuring comprehensive documentation for developers. * Refactor API endpoints for cycles, intake, modules, projects, and states - Replaced existing API endpoint classes with more descriptive names such as CycleListCreateAPIEndpoint, CycleDetailAPIEndpoint, IntakeIssueListCreateAPIEndpoint, and others to enhance clarity. - Updated URL patterns to reflect the new endpoint names, ensuring consistency across the API. - Improved documentation and method summaries for better understanding of endpoint functionalities. - Enhanced query handling in the new endpoint classes to streamline data retrieval and improve performance. * Refactor issue and label API endpoints for clarity and functionality - Renamed existing API endpoint classes to more descriptive names such as IssueListCreateAPIEndpoint, IssueDetailAPIEndpoint, LabelListCreateAPIEndpoint, and LabelDetailAPIEndpoint to enhance clarity. - Updated URL patterns to reflect the new endpoint names, ensuring consistency across the API. - Improved method summaries and documentation for better understanding of endpoint functionalities. - Streamlined query handling in the new endpoint classes to enhance data retrieval and performance. * Refactor asset API endpoint methods and introduce new status enums - Updated the GenericAssetEndpoint to only allow POST requests for asset creation, removing the GET method. - Modified the get method to require asset_id, ensuring that asset retrieval is always tied to a specific asset. - Added new IntakeIssueStatus and ModuleStatus enums to improve clarity and management of asset and module states. - Enhanced OpenAPI settings to include these new enums for better documentation and usability. * enforce naming convention * Added LICENSE to openapi spec * Enhance OpenAPI documentation for various API endpoints - Updated API endpoints in asset, cycle, intake, issue, module, project, and state views to include OpenApiRequest and OpenApiExample for better request documentation. - Added example requests for creating and updating resources, improving clarity for API consumers. - Ensured consistent use of OpenApi utilities across all relevant endpoints to enhance overall API documentation quality. * Enhance OpenAPI documentation for various API endpoints - Added detailed descriptions to multiple API endpoints across asset, cycle, intake, issue, module, project, state, and user views to improve clarity for API consumers. - Ensured consistent documentation practices by including descriptions that outline the purpose and functionality of each endpoint. - This update aims to enhance the overall usability and understanding of the API documentation. * Update OpenAPI examples and enhance project queryset logic - Changed example fields in OpenAPI documentation for issue comments from "content" to "comment_html" to reflect the correct structure. - Introduced a new `get_queryset` method in the ProjectDetailAPIEndpoint to filter projects based on user membership and workspace, while also annotating additional project-related data such as total members, cycles, and modules. - Updated permission checks to use the correct attribute name for project identifiers, ensuring accurate permission handling. * Enhance OpenAPI documentation and add response examples - Updated multiple API endpoints across asset, cycle, intake, issue, module, project, state, and user views to include new OpenApiResponse examples for better clarity on expected outcomes. - Introduced new parameters for project and issue identifiers to improve request handling and documentation consistency. - Enhanced existing responses with detailed examples to aid API consumers in understanding the expected data structure and error handling. - This update aims to improve the overall usability and clarity of the API documentation. * refactor: update terminology from 'issues' to 'work items' across multiple API endpoints for consistency and clarity * use common timezones from pytz for choices * Moved the openapi utils to the new folder structure * Added exception logging in GenericAssetEndpoint to improve error handling * Fixed code rabbit suggestions * Refactored IssueDetailAPIEndpoint to streamline issue retrieval and response handling, removing redundant external ID checks and custom ordering logic. --------- Co-authored-by: pablohashescobar <[email protected]> Co-authored-by: NarayanBavisetti <[email protected]>
Description
Type of Change
Summary by CodeRabbit
New Features
Improvements
Documentation
Chores
drf-spectacularas a dependency for OpenAPI support.Style