Skip to content

Staging#6238

Closed
abu-b-sidq wants to merge 83 commits intomakeplane:previewfrom
shipsy:staging
Closed

Staging#6238
abu-b-sidq wants to merge 83 commits intomakeplane:previewfrom
shipsy:staging

Conversation

@abu-b-sidq
Copy link

@abu-b-sidq abu-b-sidq commented Dec 19, 2024

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

References

Summary by CodeRabbit

  • New Features

    • Introduced a new GlobalSearchEndpoint for comprehensive searches across multiple fields within a workspace.
    • Added IssueTypeCustomProperty and IssueCustomProperty models to enhance issue management capabilities.
    • Added filter_custom_properties function for advanced filtering of issues based on custom properties.
    • Enhanced the S3Storage class with a new file_overwrite attribute to control file handling during uploads.
    • Updated the PROJECT_FEATURES_LIST to enable time tracking for all users.
  • Bug Fixes

    • Adjusted permission checks to allow superusers to bypass standard checks.
  • Documentation

    • Updated import statements for clarity and removed duplicates in model imports.
  • Chores

    • Removed the plane-mq service from the Docker configuration.
    • Updated dependency versions in requirements files.
    • Enhanced environment variable management in settings.
    • Simplified the sidebar dropdown by removing the workspace creation option.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


abu-siddique-shipsy seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2024

Walkthrough

This pull request introduces significant changes across multiple components of the Plane application, focusing on enhancing issue management, authentication, and system configuration. The modifications span several key areas including API serializers, models, middleware, authentication flows, and Docker configurations. The changes aim to improve custom property handling for issues, refine user authentication processes, and streamline deployment configurations.

Changes

File/Module Change Summary
admin/Dockerfile.admin Updated build process with turbo prune and added server start command.
apiserver/Dockerfile.api Added environment file path handling and conditional container startup.
admin/ce/components/common/upgrade-button.tsx Removed functionality of the UpgradeButton component by commenting out the anchor element.
admin/core/components/admin-sidebar/help-section.tsx Removed help toggle button and associated tooltip from the HelpSection component.
apiserver/plane/api/middleware/api_authentication.py Enhanced API token validation with a static token check and added a new method for project ID rewriting.
apiserver/plane/api/serializers/__init__.py Added new imports for IssueTypeSerializer and IssueTypeCustomPropertySerializer.
apiserver/plane/api/serializers/issue.py Introduced IssueCustomPropertySerializer and enhanced IssueSerializer for custom properties.
apiserver/plane/api/serializers/issue_type.py Added IssueTypeSerializer and IssueTypeCustomPropertySerializer for handling issue types.
apiserver/plane/api/urls/__init__.py Updated urlpatterns to include new patterns for issue types and search.
apiserver/plane/api/urls/issue.py Changed project_id parameter type from uuid to str and updated endpoint for attachments.
apiserver/plane/api/views/attachment.py Introduced IssueAttachmentV2Endpoint for managing issue attachments.
apiserver/plane/db/models/issue.py Added IssueCustomProperty model for flexible issue property management.
apiserver/plane/db/migrations/0084_projectcustomproperty_issuecustomproperty_and_more.py Introduced ProjectCustomProperty and IssueCustomProperty models.
apiserver/plane/settings/common.py Updated environment variable loading and configuration.
docker-compose-local.yml Removed RabbitMQ service and updated database and API service configurations.
demo.Jenkinsfile Introduced a new pipeline configuration for the "plane" project in the "demo" environment.

Poem

🐰 In CodeRabbit's digital warren,
Where bits and bytes are always carin',
We've pruned and built with gentle might,
Our Plane now soars to greater height!
A rabbit's code, both swift and bright! 🚀


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9bec624 and 2c5c9b7.

📒 Files selected for processing (1)
  • web/Dockerfile.web (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/Dockerfile.web

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 42

🔭 Outside diff range comments (2)
apiserver/plane/db/models/__init__.py (1)

Line range hint 73-115: Remove duplicate imports

Several modules are imported multiple times. This creates unnecessary code duplication and potential confusion.

- from .deploy_board import DeployBoard
- from .importer import Importer
- from .page import Page, PageLog, PageLabel
- from .estimate import Estimate, EstimatePoint
- from .inbox import Inbox, InboxIssue
- from .analytic import AnalyticView
- from .notification import (
-     Notification,
-     UserNotificationPreference,
-     EmailNotificationLog,
- )
- from .exporter import ExporterHistory
- from .webhook import Webhook, WebhookLog
- from .dashboard import Dashboard, DashboardWidget, Widget
🧰 Tools
🪛 Ruff (0.8.2)

113-113: .favorite.UserFavorite imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


115-115: .issue_type.IssueType imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


115-115: .issue_type.IssueTypeCustomProperty imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


117-117: .recent_visit.UserRecentVisit imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

docker-compose-local.yml (1)

RabbitMQ dependencies still present and need to be addressed

The verification reveals that RabbitMQ dependencies are still present in the codebase:

  • RabbitMQ configuration exists in .env.example with default settings
  • Celery is configured to use RabbitMQ as broker in apiserver/plane/settings/common.py
  • Multiple Celery tasks are actively being used in the application

The removal of the plane-mq service from docker-compose without addressing these dependencies could cause issues. The following need attention:

  • Update broker configuration to use Redis instead of RabbitMQ
  • Remove RabbitMQ-related environment variables
  • Ensure Celery tasks are configured to work with the new broker
🔗 Analysis chain

Line range hint 1-195: Verify removal of message queue dependencies

The AI summary indicates that the plane-mq (RabbitMQ) service was removed. Ensure all related message queue dependencies and configurations have been properly addressed.


Let me gather more information about the Celery configuration and broker settings to verify if the message queue dependencies have been properly addressed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for remaining RabbitMQ references
echo "Checking for RabbitMQ configurations..."
rg -l "RABBITMQ|CELERY" .env* || true
rg -l "rabbitmq" apiserver/plane/settings/* || true

# Check for Celery tasks that might depend on RabbitMQ
echo "Checking for Celery tasks..."
rg -l "celery" apiserver/plane/ || true

Length of output: 1782


Script:

#!/bin/bash
# Check Celery configuration and broker settings
echo "Checking Celery configuration in settings..."
rg -A 5 "CELERY" apiserver/plane/settings/common.py

echo "\nChecking broker configuration in celery.py..."
cat apiserver/plane/celery.py

echo "\nChecking environment variables template..."
grep -A 5 "CELERY\|RABBITMQ" .env.example || true

Length of output: 3070

🧹 Nitpick comments (27)
apiserver/plane/authentication/utils/redirection_path.py (1)

9-10: Remove commented code if change is intentional

If the removal of onboarding redirection is intentional, the commented code should be removed rather than left as comments. This improves code maintainability and prevents confusion.

-    # if not profile.is_onboarded:
-    #     return "onboarding"
apiserver/Dockerfile.api (3)

57-57: Security consideration for environment files
Including an environment file inside the image may inadvertently reveal secrets. Ensure sensitive data is not stored permanently in the Docker image layers.


60-60: Validate environment variable usage
Double-check that ENV_FILE_PATH is correctly mapped to downstream processes and not overwritten at runtime.


62-71: Consider adding a default fallback
If ENV_TYPE is omitted or misspelled, the container exits. A default fallback or a more descriptive usage message could help.

apiserver/plane/api/views/attachment.py (1)

9-9: Remove unused import
Ruff flags “allow_permission” as unused. Please remove it to keep the codebase clean.

- from plane.app.permissions import ProjectEntityPermission, allow_permission
+ from plane.app.permissions import ProjectEntityPermission
🧰 Tools
🪛 Ruff (0.8.2)

9-9: plane.app.permissions.allow_permission imported but unused

Remove unused import: plane.app.permissions.allow_permission

(F401)

apiserver/plane/api/views/issue_type.py (3)

8-19: Remove unused imports
Many django.db.models imports are unused (Case, CharField, Exists, F, Func, Max, OuterRef, Q, Value, When, Subquery).
Likewise, MultiPartParser, FormParser, and issue_activity appear unused.

- from django.db.models import (
-     Case,
-     CharField,
-     Exists,
-     F,
-     Func,
-     Max,
-     OuterRef,
-     Q,
-     Value,
-     When,
-     Subquery,
- )
- from rest_framework.parsers import MultiPartParser, FormParser
- from plane.bgtasks.issue_activities_task import issue_activity
+ from django.db.models import Q  # Keep only what's actually needed, or remove entirely if unused.
🧰 Tools
🪛 Ruff (0.8.2)

8-8: django.db.models.Case imported but unused

Remove unused import

(F401)


9-9: django.db.models.CharField imported but unused

Remove unused import

(F401)


10-10: django.db.models.Exists imported but unused

Remove unused import

(F401)


11-11: django.db.models.F imported but unused

Remove unused import

(F401)


12-12: django.db.models.Func imported but unused

Remove unused import

(F401)


13-13: django.db.models.Max imported but unused

Remove unused import

(F401)


14-14: django.db.models.OuterRef imported but unused

Remove unused import

(F401)


15-15: django.db.models.Q imported but unused

Remove unused import

(F401)


16-16: django.db.models.Value imported but unused

Remove unused import

(F401)


17-17: django.db.models.When imported but unused

Remove unused import

(F401)


18-18: django.db.models.Subquery imported but unused

Remove unused import

(F401)


140-141: Remove unused variables
“requested_data” and “current_instance” are never used.

- requested_data = json.dumps(self.request.data, cls=DjangoJSONEncoder)
- current_instance = json.dumps(
-     IssueTypeSerializer(issue_comment).data,
-     cls=DjangoJSONEncoder,
- )
🧰 Tools
🪛 Ruff (0.8.2)

140-140: Local variable requested_data is assigned to but never used

Remove assignment to unused variable requested_data

(F841)


141-141: Local variable current_instance is assigned to but never used

Remove assignment to unused variable current_instance

(F841)


200-200: Remove unused variable
“workspace” is assigned but never used.

- workspace = Workspace.objects.get(slug=slug)
🧰 Tools
🪛 Ruff (0.8.2)

200-200: Local variable workspace is assigned to but never used

Remove assignment to unused variable workspace

(F841)

apiserver/plane/api/views/search.py (1)

250-258: Limited search types
Only the "issue" filter is currently enabled in the MODELS_MAPPER. If you plan to enable the other entities, ensure they are thoroughly tested for correct authorization and performance.

apiserver/plane/authentication/views/app/magic.py (1)

95-102: Recommend removing debug prints in production
Using print statements can clutter logs and potentially expose internal data. Consider replacing them with structured logging, at a debug level if necessary.

apiserver/plane/api/serializers/issue.py (2)

243-259: Bulk insert for custom properties
The bulk insert approach is efficient, but watch out for potential partial failures. If a single record fails validation or insertion, the entire bulk create will fail. Ensure rollback and error management is in place.


307-324: Re-creating custom properties on update
Deleting and re-inserting custom properties ensures data consistency but might cause versioning or audit log gaps. If historical tracking is required, consider a soft-delete or versioning approach.

apiserver/plane/api/views/issue.py (3)

36-36: Remove unused import to avoid lint issues.

According to the static analysis hints (F401), this import is unused. Removing it will help keep the codebase clean.

-    IssueTypeSerializer
🧰 Tools
🪛 Ruff (0.8.2)

36-36: plane.api.serializers.IssueTypeSerializer imported but unused

Remove unused import: plane.api.serializers.IssueTypeSerializer

(F401)


54-54: Remove unused import to avoid lint issues.

Similar to the previous note, this import is also flagged as unused (F401). Consider removing it.

-    IssueType
🧰 Tools
🪛 Ruff (0.8.2)

54-54: plane.db.models.IssueType imported but unused

Remove unused import: plane.db.models.IssueType

(F401)


1111-1111: Remove commented debug statement.

Stray debugger calls can clutter production code. Consider removing this commented-out line before merging.

-            # import pdb;pdb.set_trace()
apiserver/plane/api/urls/issue_type.py (1)

23-25: Add missing trailing comma

Add a trailing comma after the last URL pattern to maintain consistency and make future additions cleaner.

     path(
         "workspaces/<str:slug>/issue-type/<uuid:issue_type>/custom-properties/",
         IssueTypeCustomPropertyAPIEndpoint.as_view(),
         name="issue-type-custom-property",
-    )
+    ),
apiserver/plane/api/serializers/issue_type.py (2)

1-6: Remove unused import

The serializers import from rest_framework is unused and can be removed.

-from rest_framework import serializers

from plane.db.models import IssueType, IssueTypeCustomProperty

from .base import BaseSerializer
🧰 Tools
🪛 Ruff (0.8.2)

1-1: rest_framework.serializers imported but unused

Remove unused import: rest_framework.serializers

(F401)


12-24: Resolve redundant field specifications

The created_by field is listed in both read_only_fields and exclude, which is redundant.

Choose one approach:

     class Meta:
         model = IssueType
         read_only_fields = [
             "id",
             "workspace",
-            "created_by",
             "updated_by",
             "created_at",
             "updated_at",
         ]
         exclude = [
             "created_by",
             "updated_by",
         ]
apiserver/plane/middleware/api_log_middleware.py (1)

22-32: Remove commented-out code

The process_view method is entirely commented out. Either implement it properly or remove it completely to maintain clean code.

apiserver/plane/api/serializers/project.py (1)

Line range hint 92-107: Document the purpose of ProjectLiteSerializer

The new ProjectLiteSerializer appears to be a lightweight version of ProjectSerializer, but its intended use case and the rationale for its introduction are not documented.

Consider adding a docstring explaining:

  • The purpose of this serializer
  • When to use it vs. the full ProjectSerializer
  • Any performance benefits it provides
apiserver/plane/app/permissions/project.py (1)

56-56: Remove unnecessary empty lines.

Multiple consecutive empty lines affect code readability.

-
-        
+

Also applies to: 73-73, 123-123

apiserver/plane/settings/storage.py (1)

22-26: Address TODO and improve method documentation.

The TODO comment about max_length should be addressed, and the method could benefit from better documentation.

     def get_available_name(self, name, max_length=None):
-        # TODO: something with max_length?
+        """
+        Returns a filename that's free on the target storage system.
+        
+        Args:
+            name: Base filename
+            max_length: Maximum length of filename (currently not enforced)
+        
+        Returns:
+            Available filename that won't overwrite existing files if file_overwrite=False
+        """
         if self.file_overwrite:
             return name
         return super().get_available_name(name, max_length=max_length)
apiserver/plane/api/views/member.py (1)

133-133: Remove unnecessary empty line.

Extra empty line affects code readability.

-        
apiserver/plane/api/views/base.py (1)

166-168: Remove commented debug code

Debug code should be removed rather than commented out. This includes the pdb trace statement.

-        # if project_id == "DEFAULT":
-        #     import pdb;pdb.set_trace
-        #     return self.workspace.workspace_project.filter(name='default').first().id
apiserver/plane/authentication/provider/credentials/magic_code.py (1)

119-124: Improve Redis data handling

Consider the following improvements:

  1. Move expiration time to settings
  2. Add data compression for large objects
  3. Use Redis hash instead of storing JSON string
+    REDIS_EXPIRY = settings.MAGIC_CODE_EXPIRY_SECONDS
+
     def _store_redis_data(self, key, value):
-        expiry = 600
-        ri.set(key, json.dumps(value), ex=expiry)
+        ri.hmset(key, value)
+        ri.expire(key, self.REDIS_EXPIRY)
apiserver/plane/utils/issue_filters.py (1)

590-590: Consider adding documentation for custom properties filter.

The custom properties filter is a complex feature that would benefit from documentation explaining its usage and expected format.

Add docstring to explain the feature:

+    # Add to ISSUE_FILTER docstring:
+    # custom_properties: Filter issues by custom properties using format "key:value,key2:value2"
+    #                   Example: "priority_id:high,status_id:active"
     "custom_properties": filter_custom_properties,
apiserver/plane/api/views/__init__.py (1)

Line range hint 1-36: Consider adding __all__ to make exports explicit.

The module has several imports that appear unused. If these are meant to be re-exported, make it explicit by defining __all__.

Add this at the end of the file:

__all__ = [
    'ProjectAPIEndpoint',
    'ProjectArchiveUnarchiveAPIEndpoint',
    'StateAPIEndpoint',
    'WorkspaceIssueAPIEndpoint',
    'IssueAPIEndpoint',
    'LabelAPIEndpoint',
    'IssueLinkAPIEndpoint',
    'IssueCommentAPIEndpoint',
    'IssueActivityAPIEndpoint',
    'IssueAttachmentEndpoint',
    'IssueTypeAPIEndpoint',
    'IssueTypeCustomPropertyAPIEndpoint',
    'IssueAttachmentV2Endpoint',
    'CycleAPIEndpoint',
    'CycleIssueAPIEndpoint',
    'TransferCycleIssueAPIEndpoint',
    'CycleArchiveUnarchiveAPIEndpoint',
    'ModuleAPIEndpoint',
    'ModuleIssueAPIEndpoint',
    'ModuleArchiveUnarchiveAPIEndpoint',
    'ProjectMemberAPIEndpoint',
    'InboxIssueAPIEndpoint',
    'GlobalSearchEndpoint',
]
🧰 Tools
🪛 Ruff (0.8.2)

12-12: .issue.IssueLinkAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


13-13: .issue.IssueCommentAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .issue.IssueActivityAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


15-15: .issue.IssueAttachmentEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


17-17: .issue_type.IssueTypeAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


17-17: .issue_type.IssueTypeCustomPropertyAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


18-18: .attachment.IssueAttachmentV2Endpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


20-20: .cycle.CycleAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


21-21: .cycle.CycleIssueAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f10f9cb and 7c5f5ea.

📒 Files selected for processing (52)
  • admin/Dockerfile.admin (1 hunks)
  • admin/ce/components/common/upgrade-button.tsx (1 hunks)
  • admin/core/components/admin-sidebar/help-section.tsx (0 hunks)
  • apiserver/Dockerfile.api (1 hunks)
  • apiserver/plane/api/middleware/api_authentication.py (3 hunks)
  • apiserver/plane/api/serializers/__init__.py (1 hunks)
  • apiserver/plane/api/serializers/issue.py (9 hunks)
  • apiserver/plane/api/serializers/issue_type.py (1 hunks)
  • apiserver/plane/api/serializers/project.py (2 hunks)
  • apiserver/plane/api/urls/__init__.py (2 hunks)
  • apiserver/plane/api/urls/issue.py (2 hunks)
  • apiserver/plane/api/urls/issue_type.py (1 hunks)
  • apiserver/plane/api/urls/project.py (2 hunks)
  • apiserver/plane/api/urls/search.py (1 hunks)
  • apiserver/plane/api/views/__init__.py (3 hunks)
  • apiserver/plane/api/views/attachment.py (1 hunks)
  • apiserver/plane/api/views/base.py (6 hunks)
  • apiserver/plane/api/views/issue.py (6 hunks)
  • apiserver/plane/api/views/issue_type.py (1 hunks)
  • apiserver/plane/api/views/member.py (1 hunks)
  • apiserver/plane/api/views/project.py (3 hunks)
  • apiserver/plane/api/views/search.py (1 hunks)
  • apiserver/plane/app/permissions/project.py (5 hunks)
  • apiserver/plane/app/views/issue/base.py (2 hunks)
  • apiserver/plane/authentication/adapter/base.py (2 hunks)
  • apiserver/plane/authentication/provider/credentials/magic_code.py (4 hunks)
  • apiserver/plane/authentication/utils/redirection_path.py (1 hunks)
  • apiserver/plane/authentication/views/app/magic.py (5 hunks)
  • apiserver/plane/db/migrations/0084_projectcustomproperty_issuecustomproperty_and_more.py (1 hunks)
  • apiserver/plane/db/migrations/0085_remove_issuecustomproperty_project_custom_property_and_more.py (1 hunks)
  • apiserver/plane/db/migrations/0086_issuetypecustomproperty_delete_projectcustomproperty_and_more.py (1 hunks)
  • apiserver/plane/db/migrations/0087_issuecustomproperty_issue_type_and_more.py (1 hunks)
  • apiserver/plane/db/migrations/0088_alter_issuecustomproperty_issue_type.py (1 hunks)
  • apiserver/plane/db/migrations/0089_rename_issue_type_issuecustomproperty_issue_type_custom_proerty.py (1 hunks)
  • apiserver/plane/db/migrations/0090_rename_issue_type_custom_proerty_issuecustomproperty_issue_type_custom_property.py (1 hunks)
  • apiserver/plane/db/models/__init__.py (3 hunks)
  • apiserver/plane/db/models/base.py (1 hunks)
  • apiserver/plane/db/models/issue.py (1 hunks)
  • apiserver/plane/db/models/issue_type.py (1 hunks)
  • apiserver/plane/middleware/api_log_middleware.py (2 hunks)
  • apiserver/plane/settings/common.py (4 hunks)
  • apiserver/plane/settings/redis.py (1 hunks)
  • apiserver/plane/settings/storage.py (1 hunks)
  • apiserver/plane/utils/issue_filters.py (3 hunks)
  • apiserver/requirements/base.txt (3 hunks)
  • demo.Jenkinsfile (1 hunks)
  • docker-compose-local.yml (2 hunks)
  • web/Dockerfile.web (2 hunks)
  • web/ce/constants/project/settings/features.tsx (1 hunks)
  • web/core/components/workspace/sidebar/dropdown.tsx (0 hunks)
  • web/core/components/workspace/sidebar/help-section.tsx (1 hunks)
  • web/core/constants/dashboard.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • admin/core/components/admin-sidebar/help-section.tsx
  • web/core/components/workspace/sidebar/dropdown.tsx
✅ Files skipped from review due to trivial changes (4)
  • apiserver/plane/settings/redis.py
  • admin/ce/components/common/upgrade-button.tsx
  • apiserver/plane/db/migrations/0089_rename_issue_type_issuecustomproperty_issue_type_custom_proerty.py
  • apiserver/plane/db/migrations/0090_rename_issue_type_custom_proerty_issuecustomproperty_issue_type_custom_property.py
🧰 Additional context used
🪛 Ruff (0.8.2)
apiserver/plane/api/serializers/__init__.py

14-14: .issue_type.IssueTypeSerializer imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .issue_type.IssueTypeCustomPropertySerializer imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

apiserver/plane/api/views/project.py

253-253: Undefined name user

(F821)

apiserver/plane/api/serializers/project.py

12-12: .issue_type.IssueTypeSerializer imported but unused

Remove unused import: .issue_type.IssueTypeSerializer

(F401)

apiserver/plane/db/models/__init__.py

44-44: .issue.IssueCustomProperty imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


71-71: .project.ProjectPublicMember imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


115-115: .issue_type.IssueType imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


115-115: .issue_type.IssueTypeCustomProperty imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

apiserver/plane/api/urls/issue.py

11-11: plane.api.views.IssueTypeAPIEndpoint imported but unused

Remove unused import: plane.api.views.IssueTypeAPIEndpoint

(F401)

apiserver/plane/api/serializers/issue_type.py

1-1: rest_framework.serializers imported but unused

Remove unused import: rest_framework.serializers

(F401)

apiserver/plane/api/views/issue_type.py

8-8: django.db.models.Case imported but unused

Remove unused import

(F401)


9-9: django.db.models.CharField imported but unused

Remove unused import

(F401)


10-10: django.db.models.Exists imported but unused

Remove unused import

(F401)


11-11: django.db.models.F imported but unused

Remove unused import

(F401)


12-12: django.db.models.Func imported but unused

Remove unused import

(F401)


13-13: django.db.models.Max imported but unused

Remove unused import

(F401)


14-14: django.db.models.OuterRef imported but unused

Remove unused import

(F401)


15-15: django.db.models.Q imported but unused

Remove unused import

(F401)


16-16: django.db.models.Value imported but unused

Remove unused import

(F401)


17-17: django.db.models.When imported but unused

Remove unused import

(F401)


18-18: django.db.models.Subquery imported but unused

Remove unused import

(F401)


25-25: rest_framework.parsers.MultiPartParser imported but unused

Remove unused import

(F401)


25-25: rest_framework.parsers.FormParser imported but unused

Remove unused import

(F401)


35-35: plane.bgtasks.issue_activities_task.issue_activity imported but unused

Remove unused import: plane.bgtasks.issue_activities_task.issue_activity

(F401)


140-140: Local variable requested_data is assigned to but never used

Remove assignment to unused variable requested_data

(F841)


141-141: Local variable current_instance is assigned to but never used

Remove assignment to unused variable current_instance

(F841)


142-142: Undefined name issue_comment

(F821)


162-162: Undefined name issue_comment

(F821)


200-200: Local variable workspace is assigned to but never used

Remove assignment to unused variable workspace

(F841)


236-236: Undefined name ValidationError

(F821)

apiserver/plane/api/serializers/issue.py

38-38: Local variable uuid_obj is assigned to but never used

Remove assignment to unused variable uuid_obj

(F841)

apiserver/plane/api/views/base.py

89-89: Multiple statements on one line (semicolon)

(E702)

apiserver/plane/api/views/attachment.py

9-9: plane.app.permissions.allow_permission imported but unused

Remove unused import: plane.app.permissions.allow_permission

(F401)

apiserver/plane/api/views/issue.py

36-36: plane.api.serializers.IssueTypeSerializer imported but unused

Remove unused import: plane.api.serializers.IssueTypeSerializer

(F401)


54-54: plane.db.models.IssueType imported but unused

Remove unused import: plane.db.models.IssueType

(F401)

apiserver/plane/authentication/views/app/magic.py

287-287: Local variable is_app is assigned to but never used

Remove assignment to unused variable is_app

(F841)

apiserver/plane/api/views/__init__.py

2-2: .project.ProjectAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


3-3: .project.ProjectArchiveUnarchiveAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


15-15: .issue.IssueAttachmentEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


17-17: .issue_type.IssueTypeAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


17-17: .issue_type.IssueTypeCustomPropertyAPIEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


18-18: .attachment.IssueAttachmentV2Endpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


36-36: .search.GlobalSearchEndpoint imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

🔇 Additional comments (45)
apiserver/plane/authentication/utils/redirection_path.py (1)

9-10: Verify: Is bypassing onboarding redirection intentional?

The removal of onboarding redirection could have significant implications:

  • Users might access workspaces without completing necessary setup
  • Other parts of the system might expect users to be onboarded
  • Could affect user experience and data integrity

Let's verify the impact:

apiserver/Dockerfile.api (2)

53-55: Clarify handling when no ENV_FILE_PATH is given
If ENV_FILE_PATH is not provided at build time, COPY will fail. Consider a default or conditional copy logic to avoid unexpected build failures.


74-74: No changes detected

apiserver/plane/db/migrations/0084_projectcustomproperty_issuecustomproperty_and_more.py (1)

1-69: Migration logic appears correct
Both new models and constraints look good. Indexing “name” may improve query performance, but that can be addressed later.

demo.Jenkinsfile (3)

95-126: Parallel build stages are well-structured
The parallelized Docker image build logic is clear and straightforward, allowing multiple builds to run concurrently without blocking one another. This is functional and aligns with best practices for CI pipelines.


129-156: Effective parallel push to registry
Similarly, pushing images to the registry in parallel is a time-saving measure. The approach is valid and merges well with the rest of the pipeline.


158-228: Deployment strategy is aligned with ECS best practices
The parallel deployment steps for each ECS service improve speed and maintain clarity in the pipeline.

apiserver/plane/api/views/search.py (2)

68-78: Good approach for partial integer matching
The logic correctly isolates whole numbers in the search term for matching sequence IDs, ensuring fractional or partial matches won't break the query.


99-123: Consistent filtering usage
The repeated pattern (filter on slug, membership checks, is_active checks) is consistent across multiple filter methods. This improves maintainability and clarity.

apiserver/plane/api/serializers/issue.py (1)

78-79: New field 'custom_properties'
Introducing custom properties in issue serialization is a solid approach to handle dynamic fields. Validate that the ingestion of these properties meets performance requirements for large data sets.

apiserver/plane/api/views/issue.py (7)

56-56: LGTM on filter modularization.

The import for “issue_filters” keeps filtering logic modular. Looks good.


137-139: Good approach for applying base filters.

The logic to pop the "base" filter and apply it conditionally is clear and flexible. No issues found.


146-147: All good with project and workspace filters.

These filter clauses appropriately constrain the query. Looks fine.


148-149: Conditional base_filter usage looks correct.

No concerns; straightforward application of the filter.


151-152: Applying filters from query params is fine.

The usage of dictionary unpacking (filter(**filters)) is idiomatic and easy to maintain.


159-160: User-supplied ordering can pose a safety concern in some contexts.

Django generally sanitizes order_by fields, but consider validating user-supplied order_by strings to ensure no malicious injection or unknown fields are used.


352-355: Potential security check for user assignment.

Allowing request data to override the creator field could be abused if not properly validated. Confirm that only privileged contexts can assign “created_by” to avoid impersonation or data tampering.

apiserver/plane/api/urls/search.py (1)

1-13: New search route looks good overall.

The URL pattern and view import are straightforward, enabling a workspace-level search endpoint. No issues found.

apiserver/plane/api/urls/project.py (3)

5-5: No issues with the import.

Importing “ProjectArchiveUnarchiveAPIEndpoint” remains valid. No additional improvements required.


15-15: Switching from UUID to string key for project.

Changing uuid:pk to str:pk can increase flexibility. Ensure your business logic handles non-UUID strings properly (such as slug-based IDs).

[approve]


20-20: Consistency in using string for project_id.

Similarly, switching uuid:project_id to str:project_id can be beneficial if not all IDs are UUID. Confirm any existing references or DB relations referencing UUID remain consistent.

[approve]

apiserver/plane/db/migrations/0088_alter_issuecustomproperty_issue_type.py (1)

1-19: Migration logic appears correct.

Altering the foreign key to allow null and setting on_delete=SET_NULL is a common pattern. Ensure you handle any data consistency checks if needed.

apiserver/plane/db/migrations/0085_remove_issuecustomproperty_project_custom_property_and_more.py (1)

8-10: Verify migration dependencies

Please ensure that migration 0084 has been properly tested and deployed before this migration.

✅ Verification successful

Let me verify if there are any migrations between 0084 and 0085 to ensure the dependency chain is correct.


Migration dependency chain is correct

The migration files listing confirms that migration 0084_projectcustomproperty_issuecustomproperty_and_more.py is the direct predecessor of 0085_remove_issuecustomproperty_project_custom_property_and_more.py. There are no intermediate migrations between them, confirming that the dependency chain is properly configured.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any intermediate migrations between 0084 and this one
fd --type f "^0084.*\.py$" "apiserver/plane/db/migrations/"

Length of output: 148


Script:

#!/bin/bash
# List all migration files to check the sequence
fd --type f "^\d{4}.*\.py$" "apiserver/plane/db/migrations/" | sort

Length of output: 6310

apiserver/plane/api/urls/issue_type.py (1)

3-6: Verify view implementations

Ensure that the imported view classes exist and are properly implemented.

✅ Verification successful

Let me check the actual implementation of these classes to ensure they are properly implemented.


Let me verify if these classes inherit properly from BaseAPIView and have the necessary methods implemented.


Let me try a different approach using ripgrep to get the full class implementations.


View implementations are properly defined

Both view classes are correctly implemented:

  • IssueTypeAPIEndpoint extends BaseAPIView with proper serializer, model, and permission classes defined
  • IssueTypeCustomPropertyAPIEndpoint extends BaseAPIView with GET and POST methods implemented correctly
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the view classes exist in the codebase
rg -l "class IssueTypeAPIEndpoint|class IssueTypeCustomPropertyAPIEndpoint" "apiserver/plane/api/views/"

Length of output: 144


Script:

#!/bin/bash
# Check the implementation of the view classes
rg -A 5 "class IssueTypeAPIEndpoint|class IssueTypeCustomPropertyAPIEndpoint" "apiserver/plane/api/views/issue_type.py"

Length of output: 601


Script:

#!/bin/bash
# Get the full implementation of both classes
ast-grep --pattern 'class IssueTypeAPIEndpoint {
  $$$
}'

ast-grep --pattern 'class IssueTypeCustomPropertyAPIEndpoint {
  $$$
}'

Length of output: 133


Script:

#!/bin/bash
# Get the complete class implementations with more context
rg -U "class IssueTypeAPIEndpoint\(.*?\)|class IssueTypeCustomPropertyAPIEndpoint\(.*?\)" -A 20 "apiserver/plane/api/views/issue_type.py"

Length of output: 1668

apiserver/plane/api/serializers/__init__.py (1)

14-14: Consider documenting or utilizing the imported serializers

While these serializers might be needed for URL routing, they appear unused in this file. Consider either:

  1. Adding them to __all__ if they're meant to be exposed at the module level
  2. Adding a comment explaining their purpose if they're required for URL routing
  3. Moving them to where they're actually used if they're not needed here
🧰 Tools
🪛 Ruff (0.8.2)

14-14: .issue_type.IssueTypeSerializer imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .issue_type.IssueTypeCustomPropertySerializer imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

apiserver/plane/db/migrations/0087_issuecustomproperty_issue_type_and_more.py (2)

19-23: LGTM: Field modification is well-defined

The modification to allow null/blank values in the value field is appropriate and follows Django's best practices.


14-18: Consider data migration needs

The addition of the issue_type field looks good, but consider if existing records need to be updated with appropriate issue types.

✅ Verification successful

Let me gather more information about the migration history and any existing data.


Let me check the specific migration files related to IssueCustomProperty to understand the evolution of the model.


Based on the migration history, I can now provide the final response:

Data migration is not required for this change

The migration chain shows this is part of a larger refactoring from project-based to issue-type-based custom properties. The issue_type field is being added as nullable (blank=True, null=True) with SET_NULL on delete, which means:

  • Existing records can safely continue without an issue type
  • The field is optional, so no data migration is needed
  • The change is backward compatible with existing records
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are existing records that might need migration
rg "class IssueCustomProperty|class IssueType" -A 10 -t py

Length of output: 6703


Script:

#!/bin/bash
# Check migration history and related migrations
rg "IssueCustomProperty" apiserver/plane/db/migrations/*.py

Length of output: 6438


Script:

#!/bin/bash
# Check the content of relevant migrations
cat apiserver/plane/db/migrations/0084_projectcustomproperty_issuecustomproperty_and_more.py apiserver/plane/db/migrations/0085_remove_issuecustomproperty_project_custom_property_and_more.py apiserver/plane/db/migrations/0086_issuetypecustomproperty_delete_projectcustomproperty_and_more.py apiserver/plane/db/migrations/0087_issuecustomproperty_issue_type_and_more.py

Length of output: 8684

apiserver/requirements/base.txt (1)

13-13: LGTM: Dependency updates look good

The addition of python-dotenv and upgrade of django-storages are appropriate improvements:

  • python-dotenv (1.0.0) will enhance environment configuration management
  • django-storages upgrade (1.14.4) includes latest improvements

Also applies to: 33-33

apiserver/plane/api/urls/issue.py (1)

71-79: Verify impact of switching to IssueAttachmentV2Endpoint

The change from IssueAttachmentEndpoint to IssueAttachmentV2Endpoint suggests a breaking change in the API. Please ensure:

  1. API consumers are notified of this change
  2. Proper API versioning strategy is in place
  3. Migration path is documented for existing clients
apiserver/plane/db/migrations/0086_issuetypecustomproperty_delete_projectcustomproperty_and_more.py (2)

40-47: LGTM: Robust constraint implementation

The implementation of both a conditional unique constraint and a unique_together constraint provides robust data integrity:

  1. Ensures unique names per issue type when not deleted
  2. Allows for soft deletion without constraint violations

37-39: Verify data migration plan for ProjectCustomProperty deletion

The deletion of ProjectCustomProperty model requires careful consideration:

  1. Is there existing data that needs to be migrated to the new IssueTypeCustomProperty model?
  2. Has a data migration strategy been documented?
  3. Are there any foreign key dependencies that need to be handled?
✅ Verification successful

Let me gather more information about the migration history and any potential data dependencies.


Migration path for ProjectCustomProperty deletion is properly handled

The migration sequence shows a clear and safe transition:

  1. Migration 0084 created both ProjectCustomProperty and IssueCustomProperty models
  2. Migration 0085 removed the foreign key from IssueCustomProperty to ProjectCustomProperty
  3. Migration 0086 safely deletes ProjectCustomProperty after dependencies were removed

The code shows a planned transition to IssueTypeCustomProperty, with proper handling of dependencies and data migration through intermediate steps. No remaining foreign key references exist to ProjectCustomProperty, and the model can be safely deleted.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining references to ProjectCustomProperty
rg "ProjectCustomProperty" --type py

# Look for potential foreign key references
ast-grep --pattern 'models.ForeignKey($_, to="db.ProjectCustomProperty")'

Length of output: 385


Script:

#!/bin/bash
# Check the migration that created ProjectCustomProperty
cat apiserver/plane/db/migrations/0084_projectcustomproperty_issuecustomproperty_and_more.py

# Check for any custom property related models and their relationships
ast-grep --pattern 'class $_ (models.Model):
  $$$
  custom_property $$$
  $$$'

# Look for any usage of custom properties in views or APIs
rg "custom_property" --type py -A 3

Length of output: 11979

admin/Dockerfile.admin (1)

86-88: LGTM! Docker configuration changes look good.

The addition of the EXPOSE directive and CMD instruction properly configures the container to:

  1. Expose port 3000 for the admin server
  2. Start the admin server using the correct entry point
apiserver/plane/db/models/issue_type.py (1)

62-83: Model structure looks good!

The IssueTypeCustomProperty model is well-designed with:

  • Appropriate fields and relationships
  • Proper unique constraints
  • Good meta options for ordering and verbose names
apiserver/plane/middleware/api_log_middleware.py (1)

33-44: Verify path manipulation security

The path rewriting functionality could potentially be exploited if not properly secured.

✅ Verification successful

Path manipulation code is currently inactive and safe

The code in question is completely commented out and the function simply returns the original request path without any modifications. The commented-out code shows it was intended for a specific project ID replacement pattern (DEFAULT -> specific UUID), but since it's not active, there are no security concerns.

Additionally, the middleware is properly integrated with Django's URL resolution system:

  • Path changes are properly synchronized with Django's path handling (request.path, request.path_info)
  • URL resolution is handled through Django's resolve() function
  • The middleware follows standard Django patterns for path handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for path manipulation validation in the codebase
echo "Searching for path validation patterns..."
rg -l 'path\.(join|split|normalize)' 

# Search for similar middleware security patterns
echo "Searching for security patterns in middleware..."
rg -l 'sanitize|validate|clean.*path' --type py ./apiserver/plane/middleware/

Length of output: 622


Script:

#!/bin/bash
# Let's examine the middleware implementation more closely
echo "Checking the middleware implementation:"
rg -A 10 -B 10 'project_rewiter' ./apiserver/plane/middleware/api_log_middleware.py

# Check for URL/path processing in the middleware
echo "Checking URL/path processing:"
rg -A 5 'request\.path' ./apiserver/plane/middleware/api_log_middleware.py

# Look for any authentication or permission checks
echo "Checking for authentication/permission checks:"
rg -A 5 'authenticate|permission|auth' ./apiserver/plane/middleware/api_log_middleware.py

Length of output: 3827

apiserver/plane/api/serializers/project.py (1)

Line range hint 28-36: Security concern: Verify the removal of created_by from read_only_fields

The removal of "created_by" from read_only_fields means this field can now be modified through the API. This could potentially allow users to modify who created a project, which might have security implications.

🧰 Tools
🪛 Ruff (0.8.2)

12-12: .issue_type.IssueTypeSerializer imported but unused

Remove unused import: .issue_type.IssueTypeSerializer

(F401)

web/Dockerfile.web (2)

104-107: LGTM: Container configuration looks good

The addition of EXPOSE 3000 and the CMD to run the server are appropriate changes. The port exposure documents the service's network interface, and the command correctly specifies the server script location.


73-74: Verify Next.js export directory structure

The COPY commands have been modified to handle the export directory separately from the .next directory. Ensure this matches the Next.js build output structure.

✅ Verification successful

These scripts will help us understand:

  1. Next.js configuration for export/build
  2. Server file location and structure
  3. Build and export scripts configuration

Based on the analysis of the provided context:

  1. The Next.js configuration shows output: "standalone" which is the correct configuration for Docker deployments
  2. The package.json scripts show both build and export commands for the web package
  3. The build process includes Next.js export functionality

The COPY commands in the Dockerfile are correct and match the Next.js build output structure

The .next directory contains the standalone server build, while the export directory contains the static files. This separation is intentional and follows Next.js best practices for containerized deployments.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if web/server.js exists and contains the expected startup code
test -f web/server.js && head -n 10 web/server.js

Length of output: 23


Script:

#!/bin/bash
# Check Next.js build configuration and server setup
fd -e js -e ts 'next.config' --exec head -n 20 {}

Length of output: 1442


Script:

#!/bin/bash
# Look for server-related files in the web directory
fd -t f . web/ -x echo "File: {}"

Length of output: 66300


Script:

#!/bin/bash
# Check package.json scripts to understand build and export process
fd package.json --exec jq '.scripts' {}

Length of output: 2232

docker-compose-local.yml (1)

113-114: LGTM: Development convenience features added

The addition of stdin_open and tty for the API service is helpful for debugging and development purposes.

apiserver/plane/app/permissions/project.py (1)

18-19: LGTM: Consistent superuser permission checks added.

The addition of superuser permission checks across all permission classes improves consistency in access control.

Also applies to: 53-54, 88-89, 124-125

apiserver/plane/settings/storage.py (1)

16-17: LGTM: Safe defaults for file storage.

Setting file_overwrite=False by default is a good safety measure to prevent accidental file overwrites.

apiserver/plane/authentication/adapter/base.py (1)

152-154: ⚠️ Potential issue

Add username validation and conflict handling

The current implementation lacks validation for usernames and doesn't handle potential conflicts. Consider:

  1. Validating username format (allowed characters, length)
  2. Handling username collisions
  3. Sanitizing username input
apiserver/plane/app/views/issue/base.py (1)

Line range hint 714-793: LGTM! Well-structured date validation.

The date validation implementation is clean and properly handles edge cases. Good job on:

  • Clear validation method
  • Proper error handling
  • Efficient bulk update implementation
web/ce/constants/project/settings/features.tsx (1)

87-88: Verify the implications of making time tracking available to all users

The change makes time tracking available to all users by setting isPro: false. Please ensure this aligns with:

  1. Business requirements and pricing strategy
  2. Backend service capacity planning
  3. User documentation updates
✅ Verification successful

Let me generate additional scripts to better understand the time tracking feature configuration and its implications.


Time tracking feature change appears to be part of broader feature accessibility update

The change to make time tracking available to all users by setting isPro: false aligns with the codebase structure and existing patterns:

  1. Multiple other features (modules, views, pages, inbox) are also configured with isPro: false and isEnabled: true
  2. The backend model has time tracking as an optional feature (default=False) that can be enabled per project
  3. This appears to be part of a consistent feature management approach where features are controlled at the project level rather than by pro/free tier
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any time tracking related configurations or dependencies

# Check for any other time tracking related configurations
rg -l "time_tracking" 

# Check for any premium/pro feature checks in the codebase
rg "isPro.*true" 

Length of output: 65793


Script:

#!/bin/bash
# Check for time tracking feature configuration and related code
# Look for time tracking related code and configurations
rg -A 5 "time_tracking" 

# Check for feature flag configurations
rg -A 10 "isPro.*false" web/ce/constants/project/settings/features.tsx

# Check for any backend time tracking related configurations
rg -A 5 "time_tracking" apiserver/plane/db/models/project.py

Length of output: 4460

web/core/components/workspace/sidebar/help-section.tsx (1)

Line range hint 55-74: Consider documenting the simplified help section design

The help section has been significantly simplified. While the code is clean, consider:

  1. Documenting the rationale for removing help menu items
  2. Ensuring users can still access help resources through alternative means
web/core/constants/dashboard.ts (1)

261-292: ⚠️ Potential issue

Review the impact of removing key navigation items

The removal of Projects, Cycles, and Analytics from the sidebar menu is a significant change that could impact user workflow. Please verify:

  1. Alternative access paths to these features
  2. Impact on existing user workflows
  3. Navigation structure consistency
✅ Verification successful

The previous commands failed due to incorrect file type specifications. Let's try with simpler commands to gather information about the usage of these features in the codebase.


Let's try to find evidence of alternative navigation paths or if these features have been moved elsewhere in the application.


Let's try to find if these features have been moved to workspace views, which seems to be the new navigation structure based on the changes.


Based on the search results, I can now generate a final response. The evidence shows that these features have been consolidated under a new "Views" navigation structure, with workspace-level views being the primary access point.

Navigation changes are part of UI consolidation

The removal of separate menu items for Projects, Cycles, and Analytics is intentional as these features are now accessible through the new "Views" system. Evidence shows:

  1. A new centralized "Views" navigation item has replaced the individual menu items
  2. The features are accessible via /workspace-views/ routes
  3. Both workspace-level and project-level views are supported through:
    • /workspace-views/ for workspace-wide access
    • /projects/{projectId}/views/ for project-specific access

This appears to be a UI improvement rather than a removal of functionality, consolidating navigation under a more flexible views system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for alternative navigation paths and usage of removed features

# Check for other references to these features
rg -A 5 "Projects|Cycles|Analytics" --type tsx --type ts

# Look for route definitions
fd "routes|navigation" --type ts --type tsx --exec rg -l "projects|cycles|analytics" {}

Length of output: 348


Script:

#!/bin/bash
# Let's try a different approach to search for these features

# Search for references to these features in the codebase
rg -i "projects|cycles|analytics" 

# Search for route definitions using ast-grep
ast-grep --pattern 'const $_ = {
  $$$
  projects: $_,
  $$$
}'

# Also search for any remaining UI components related to these features
rg -i "ProjectsPage|CyclesPage|AnalyticsPage"

Length of output: 71580


Script:

#!/bin/bash
# Let's search for routes and pages related to these features

# Search for route definitions and page components
rg -i "path.*projects|path.*cycles|path.*analytics"

# Search for any imports or references to these pages
rg -i "import.*Projects|import.*Cycles|import.*Analytics"

# Search for any remaining UI components or hooks related to these features
rg -i "use.*Projects|use.*Cycles|use.*Analytics"

Length of output: 65700


Script:

#!/bin/bash
# Let's search for workspace views which might be the new location for these features

# Search for workspace views related files and components
rg -i "workspace.*views|workspace-views"

# Search for any references to these features in the workspace views
rg -i "workspace.*views.*projects|workspace.*views.*cycles|workspace.*views.*analytics"

# Look for any configuration or routing related to workspace views
rg -i "workspace.*views.*config|workspace.*views.*route"

Length of output: 14422

)

# Get the workspace
workspace = Workspace.objects.get(slug=slug)
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle potential workspace lookup failure
Workspace.objects.get(...) can raise DoesNotExist. Consider handling errors or returning a 404 if the workspace doesn’t exist.

- workspace = Workspace.objects.get(slug=slug)
+ try:
+     workspace = Workspace.objects.get(slug=slug)
+ except Workspace.DoesNotExist:
+     return Response({"error": "Workspace not found"}, status=status.HTTP_404_NOT_FOUND)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
workspace = Workspace.objects.get(slug=slug)
try:
workspace = Workspace.objects.get(slug=slug)
except Workspace.DoesNotExist:
return Response({"error": "Workspace not found"}, status=status.HTTP_404_NOT_FOUND)

{"name": "The Property Name is already taken"},
status=status.HTTP_410_GONE,
)
except ValidationError:
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add import for ValidationError
ValidationError is not defined. Import it from django.core.exceptions or rest_framework.exceptions if needed.

from django.core.exceptions import ValidationError
🧰 Tools
🪛 Ruff (0.8.2)

236-236: Undefined name ValidationError

(F821)

Comment on lines +142 to +162
IssueTypeSerializer(issue_comment).data,
cls=DjangoJSONEncoder,
)

# Validation check if the issue already exists
if (
IssueType.objects.filter(
workspace__slug=slug,
name=request.data.get('name')
).exists()
):
return Response(
{
"error": "Issue Comment with the same name already exists",
"id": str(issue_type.id),
},
status=status.HTTP_409_CONFLICT,
)

serializer = IssueTypeSerializer(
issue_comment, data=request.data, partial=True
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix undefined name 'issue_comment'
Use “issue_type” instead of “issue_comment.”

- current_instance = json.dumps(
-     IssueTypeSerializer(issue_comment).data,
-     cls=DjangoJSONEncoder,
- )
...
- serializer = IssueTypeSerializer(issue_comment, data=request.data, partial=True)
+ current_instance = json.dumps(
+     IssueTypeSerializer(issue_type).data,
+     cls=DjangoJSONEncoder,
+ )
...
+ serializer = IssueTypeSerializer(issue_type, data=request.data, partial=True)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
IssueTypeSerializer(issue_comment).data,
cls=DjangoJSONEncoder,
)
# Validation check if the issue already exists
if (
IssueType.objects.filter(
workspace__slug=slug,
name=request.data.get('name')
).exists()
):
return Response(
{
"error": "Issue Comment with the same name already exists",
"id": str(issue_type.id),
},
status=status.HTTP_409_CONFLICT,
)
serializer = IssueTypeSerializer(
issue_comment, data=request.data, partial=True
IssueTypeSerializer(issue_type).data,
cls=DjangoJSONEncoder,
)
# Validation check if the issue already exists
if (
IssueType.objects.filter(
workspace__slug=slug,
name=request.data.get('name')
).exists()
):
return Response(
{
"error": "Issue Comment with the same name already exists",
"id": str(issue_type.id),
},
status=status.HTTP_409_CONFLICT,
)
serializer = IssueTypeSerializer(
issue_type, data=request.data, partial=True
🧰 Tools
🪛 Ruff (0.8.2)

142-142: Undefined name issue_comment

(F821)


162-162: Undefined name issue_comment

(F821)

Comment on lines +78 to +85
echo "Vault CONFIG: \${CONFIG}" # Debugging, remove in production
pwd
mkdir -p apiserver/${configStoragePath}
echo "\${CONFIG}" > apiserver/${configStoragePath}/.env
"""

// Debugging: Show the contents of the .env file (optional for development only)
sh "cat apiserver/${configStoragePath}/.env"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid printing secret values in logs
It appears that the value of CONFIG is being echoed for debugging. This can expose sensitive information in logs if left in production.

Below is a diff to comment out the line that prints the secret value:

-                            echo "Vault CONFIG: ${CONFIG}"   # Debugging, remove in production
+                            # echo "Vault CONFIG: ${CONFIG}"   # Commented out to prevent logging secrets
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "Vault CONFIG: \${CONFIG}" # Debugging, remove in production
pwd
mkdir -p apiserver/${configStoragePath}
echo "\${CONFIG}" > apiserver/${configStoragePath}/.env
"""
// Debugging: Show the contents of the .env file (optional for development only)
sh "cat apiserver/${configStoragePath}/.env"
# echo "Vault CONFIG: ${CONFIG}" # Commented out to prevent logging secrets
pwd
mkdir -p apiserver/${configStoragePath}
echo "\${CONFIG}" > apiserver/${configStoragePath}/.env
"""
// Debugging: Show the contents of the .env file (optional for development only)
sh "cat apiserver/${configStoragePath}/.env"

q |= Q(**{"sequence_id": sequence_id})
else:
q |= Q(**{f"{field}__icontains": query})
q |= Q(**{'custom_properties__value__icontains': query})
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the code analysis from both searches, I can now provide a final response:

Custom properties search could impact performance - indexes recommended
The custom_properties field is implemented as a related model (IssueCustomProperty) with a foreign key relationship to Issue, but there are no indexes defined on the value field that's being searched with icontains. Since this is used in a global search functionality, adding an index on the value field would improve query performance.

  • Consider adding a database index on IssueCustomProperty.value field in apiserver/plane/db/models/issue.py
  • The current implementation performs a case-insensitive contains search (icontains) which might not efficiently use indexes. Consider if exact matches or starts-with searches would be sufficient for your use case.
🔗 Analysis chain

Potential performance considerations
Appending an additional Q(...) for custom_properties might impact performance if the search is done frequently on large datasets. Confirm if an index or other optimizations exist for the JSON fields.


Let me analyze the search results to check for any database indexes or optimizations. I'll search for database migrations or model configurations related to indexes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching references to custom_properties fields to see if indexes or optimizations are implemented
rg -A 5 "custom_properties"

Length of output: 10566


Script:

#!/bin/bash
# Search for database indexes in migrations and models related to custom_properties
rg -A 5 "class Meta.*db_index|Index\(" apiserver/plane/db/models/
rg -A 5 "db\.Index|indexes" apiserver/plane/db/migrations/

Length of output: 128

Comment on lines +34 to +122
def create_project(slug, origin, user, serializer, request_data):

# Add the user as Administrator to the project
_ = ProjectMember.objects.create(
project_id=serializer.data["id"],
member=user,
role=20,
)
# Also create the issue property for the user
_ = IssueUserProperty.objects.create(
project_id=serializer.data["id"],
user=user,
)

if serializer.data["project_lead"] is not None and str(
serializer.data["project_lead"]
) != str(user.id):
ProjectMember.objects.create(
project_id=serializer.data["id"],
member_id=serializer.data["project_lead"],
role=20,
)
# Also create the issue property for the user
IssueUserProperty.objects.create(
project_id=serializer.data["id"],
user_id=serializer.data["project_lead"],
)

# Default states
states = [
{
"name": "Backlog",
"color": "#A3A3A3",
"sequence": 15000,
"group": "backlog",
"default": True,
},
{
"name": "Todo",
"color": "#3A3A3A",
"sequence": 25000,
"group": "unstarted",
},
{
"name": "In Progress",
"color": "#F59E0B",
"sequence": 35000,
"group": "started",
},
{
"name": "Done",
"color": "#16A34A",
"sequence": 45000,
"group": "completed",
},
{
"name": "Cancelled",
"color": "#EF4444",
"sequence": 55000,
"group": "cancelled",
},
]

State.objects.bulk_create(
[
State(
name=state["name"],
color=state["color"],
project=serializer.instance,
sequence=state["sequence"],
workspace=serializer.instance.workspace,
group=state["group"],
default=state.get("default", False),
created_by=user,
)
for state in states
]
)
# Model activity
model_activity.delay(
model_name="project",
model_id=str(serializer.data["id"]),
requested_data=request_data,
current_instance=None,
actor_id=user.id,
slug=slug,
origin=origin,
)
return True
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add transaction management and error handling.

The create_project function performs multiple database operations without transaction management. If any operation fails, it could leave the database in an inconsistent state.

Wrap the operations in a transaction and add error handling:

+from django.db import transaction

-def create_project(slug, origin, user, serializer, request_data):
+def create_project(slug, origin, user, serializer, request_data):
+    try:
+        with transaction.atomic():
             # Add the user as Administrator to the project
             _ = ProjectMember.objects.create(
                 project_id=serializer.data["id"],
                 member=user,
                 role=20,
             )
             # Rest of the function...
+    except Exception as e:
+        # Log the error
+        raise ValidationError(f"Failed to create project: {str(e)}")

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +542 to +560
def filter_custom_properties(params, issue_filter, method, prefix=""):
if method == "GET":
custom_properties = [
item
for item in params.get("custom_properties").split(",")
if item != "null"
]
query = Q()
for row in custom_properties:
key, value = row.split(":")
query &= Q(
Q(custom_properties__project_custom_property_id=key) &
Q(custom_properties__value=value)
)

issue_filter['base'] = query

print(issue_filter)
return issue_filter
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve custom properties filter implementation.

Several issues in the filter_custom_properties function:

  1. Debug print statement should be removed
  2. No validation of the key:value format
  3. Query could be inefficient for large datasets

Consider this improved implementation:

 def filter_custom_properties(params, issue_filter, method, prefix=""):
     if method == "GET":
         custom_properties = [
             item
             for item in params.get("custom_properties").split(",")
             if item != "null"
         ]
         query = Q()
         for row in custom_properties:
+            try:
+                key, value = row.split(":", 1)  # Use maxsplit=1 to handle values containing ':'
+                if not key or not value:
+                    continue
                 query &= Q(
                     Q(custom_properties__project_custom_property_id=key) &
                     Q(custom_properties__value=value)
                 )
+            except ValueError:
+                continue  # Skip invalid format
-        
         issue_filter['base'] = query
-        
-    print(issue_filter)
     return issue_filter
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def filter_custom_properties(params, issue_filter, method, prefix=""):
if method == "GET":
custom_properties = [
item
for item in params.get("custom_properties").split(",")
if item != "null"
]
query = Q()
for row in custom_properties:
key, value = row.split(":")
query &= Q(
Q(custom_properties__project_custom_property_id=key) &
Q(custom_properties__value=value)
)
issue_filter['base'] = query
print(issue_filter)
return issue_filter
def filter_custom_properties(params, issue_filter, method, prefix=""):
if method == "GET":
custom_properties = [
item
for item in params.get("custom_properties").split(",")
if item != "null"
]
query = Q()
for row in custom_properties:
try:
key, value = row.split(":", 1) # Use maxsplit=1 to handle values containing ':'
if not key or not value:
continue
query &= Q(
Q(custom_properties__project_custom_property_id=key) &
Q(custom_properties__value=value)
)
except ValueError:
continue # Skip invalid format
issue_filter['base'] = query
return issue_filter

Comment on lines +714 to +735
class IssueCustomProperty(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="custom_properties"
)
key = models.CharField(max_length=255)
value = models.CharField(max_length=255, null=True, blank=True)
issue_type_custom_property = models.ForeignKey(
"db.IssueTypeCustomProperty",
on_delete=models.SET_NULL,
related_name="issue_type_custom_property",
null=True,
blank=True,
)

class Meta:
verbose_name = "Issue Custom Property"
verbose_name_plural = "Issue Custom Properties"
db_table = "issue_custom_properties"
ordering = ("-created_at",)

def __str__(self):
return f"{self.issue.name} {self.key}" No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding constraints and indexes for better data integrity and performance.

  1. Add a unique constraint to prevent duplicate keys for the same issue
  2. Add an index on the foreign key fields for better query performance
  3. Consider adding validation for the key field format

Apply this diff to enhance the model:

 class IssueCustomProperty(ProjectBaseModel):
     issue = models.ForeignKey(
         Issue, on_delete=models.CASCADE, related_name="custom_properties"
     )
-    key = models.CharField(max_length=255)
+    key = models.CharField(max_length=255, validators=[
+        RegexValidator(
+            regex=r'^[a-zA-Z][a-zA-Z0-9_]*$',
+            message='Key must start with a letter and contain only letters, numbers, and underscores'
+        )
+    ])
     value = models.CharField(max_length=255, null=True, blank=True)
     issue_type_custom_property = models.ForeignKey(
         "db.IssueTypeCustomProperty",
         on_delete=models.SET_NULL,
         related_name="issue_type_custom_property",
         null=True,
         blank=True,
+        db_index=True
     )
     
     class Meta:
         verbose_name = "Issue Custom Property"
         verbose_name_plural = "Issue Custom Properties"
         db_table = "issue_custom_properties"
         ordering = ("-created_at",)
+        unique_together = ["issue", "key", "deleted_at"]
+        indexes = [
+            models.Index(fields=["issue", "key"]),
+        ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class IssueCustomProperty(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="custom_properties"
)
key = models.CharField(max_length=255)
value = models.CharField(max_length=255, null=True, blank=True)
issue_type_custom_property = models.ForeignKey(
"db.IssueTypeCustomProperty",
on_delete=models.SET_NULL,
related_name="issue_type_custom_property",
null=True,
blank=True,
)
class Meta:
verbose_name = "Issue Custom Property"
verbose_name_plural = "Issue Custom Properties"
db_table = "issue_custom_properties"
ordering = ("-created_at",)
def __str__(self):
return f"{self.issue.name} {self.key}"
class IssueCustomProperty(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="custom_properties"
)
key = models.CharField(max_length=255, validators=[
RegexValidator(
regex=r'^[a-zA-Z][a-zA-Z0-9_]*$',
message='Key must start with a letter and contain only letters, numbers, and underscores'
)
])
value = models.CharField(max_length=255, null=True, blank=True)
issue_type_custom_property = models.ForeignKey(
"db.IssueTypeCustomProperty",
on_delete=models.SET_NULL,
related_name="issue_type_custom_property",
null=True,
blank=True,
db_index=True
)
class Meta:
verbose_name = "Issue Custom Property"
verbose_name_plural = "Issue Custom Properties"
db_table = "issue_custom_properties"
ordering = ("-created_at",)
unique_together = ["issue", "key", "deleted_at"]
indexes = [
models.Index(fields=["issue", "key"]),
]
def __str__(self):
return f"{self.issue.name} {self.key}"


if serializer.is_valid():
serializer.save()
print(serializer.data)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove debug print statements.

Debug print statements should not be in production code. Consider using proper logging if debugging information is needed.

Apply this diff to remove the print statements:

-            print(serializer.data)
             # Track the issue
             issue_activity.delay(
                 type="issue.activity.created",
-            print(issue)
             issue = user_timezone_converter(
                 issue, datetime_fields, request.user.user_timezone
             )

Also applies to: 455-455

highlight: (pathname: string, baseUrl: string) => pathname.includes(`${baseUrl}/analytics/`),
Icon: BarChart2,
},
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing comma in array

There's a potential syntax error with the missing comma after the Views menu item, which could cause issues if items are uncommented.

-  }
+  },

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c5f5ea and 9bec624.

📒 Files selected for processing (1)
  • web/Dockerfile.web (2 hunks)
🔇 Additional comments (2)
web/Dockerfile.web (2)

105-105: LGTM: Port exposure is correctly configured

The EXPOSE instruction correctly documents that the application runs on port 3000, which is the default port for Next.js applications.


107-107: Verify the server implementation and dependencies

The CMD instruction runs a custom server implementation. Ensure that:

  1. The server.js file is properly copied to the final image
  2. Required dependencies for running the server are included in package.json

Comment on lines 73 to 74
# COPY --from=installer /app/web/.next/export ./
# COPY --from=installer /app/web/.next ./.next
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

The commented COPY commands should remain uncommented for standalone output

The Next.js configuration explicitly sets output: "standalone" in web/next.config.js, which requires the .next directory to be present in the final image. The commented COPY commands are actually necessary for the application to work properly.

  • The .next directory must be copied when using standalone output mode
  • The current Dockerfile only copies next.config.js, package.json, and public directory
  • Without the .next directory, the application will fail to run
- # COPY --from=installer /app/web/.next/export ./
+ COPY --from=installer /app/web/.next ./.next

Note: Only the second COPY command is needed since we're using standalone output mode, not export mode.

🔗 Analysis chain

Critical: Build artifacts are not being copied to the final image

The COPY commands for the Next.js build output are commented out. This will prevent the application from running as the built files are missing in the final image.

Uncomment and update the COPY commands based on your Next.js output configuration:

- # COPY --from=installer /app/web/.next/export ./
- # COPY --from=installer /app/web/.next ./.next
+ COPY --from=installer /app/web/.next ./.next
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify if server.js exists and check the build output structure
fd -t f "server.js" web/
ast-grep --pattern 'export const config = { output: $_ }'

Length of output: 84


Script:

#!/bin/bash
# Let's check the Next.js configuration and build setup
fd -t f "next.config" .
rg -l "output.*:" --type js
rg -l "standalone|output.*standalone" --type js

Length of output: 323


Script:

#!/bin/bash
# Let's examine the server setup
fd -t f "server" web/
cat web/server.js 2>/dev/null || true

Length of output: 152


Script:

#!/bin/bash
# Check the build script in package.json
rg '"build":.+' package.json

Length of output: 62


Script:

#!/bin/bash
# Check if there are any other Dockerfile stages copying .next
rg "COPY.+\.next" web/Dockerfile.web

Length of output: 134


Script:

#!/bin/bash
# Let's check the content of next.config.js to understand the build output configuration
cat web/next.config.js

Length of output: 4098


Script:

#!/bin/bash
# Let's check if there are any other COPY commands in the Dockerfile that might be handling the build output
rg "COPY.+installer" web/Dockerfile.web

Length of output: 280


Script:

#!/bin/bash
# Let's check for any custom server configuration in the package.json scripts
rg '"(start|dev)":.+' package.json

Length of output: 113

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants