Skip to content

Conversation

@pablohashescobar
Copy link
Member

@pablohashescobar pablohashescobar commented Dec 3, 2025

Description

  • chore: add bot user to create workspace seed data

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Test Scenarios

  • create a new workspace and verify all the entities are created by plane bot.

References

WEB-5254

Summary by CodeRabbit

  • Refactor
    • Workspace initialization now uses a dedicated bot account for all seeded content; projects, issues, pages, cycles, modules, views, labels and memberships are attributed to this bot for consistent ownership and audit fields.
  • New Features
    • Added a bot type for workspace seeding and updated seed orchestration so all seeded entities are created and tracked under that bot account.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 3, 2025 09:13
@makeplane
Copy link

makeplane bot commented Dec 3, 2025

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a workspace bot user type and updates the workspace seeding flow to create a bot user and pass it into all seed helper functions; all seeded entities now set created_by_id, updated_by_id, and owned_by_id to the bot user's id.

Changes

Cohort / File(s) Summary
Bot User Model Definition
apps/api/plane/db/models/user.py
Added BotTypeEnum (Django TextChoices) with WORKSPACE_SEED option.
Public Exports
apps/api/plane/db/models/__init__.py
Exported BotTypeEnum from .user alongside existing model exports.
Workspace Seeding & Helpers
apps/api/plane/bgtasks/workspace_seed_task.py
Create bot_user (bot_type set) and pass it into all seed helpers. Updated multiple helper function signatures to accept bot_user (e.g., create_project_and_member, create_project_states, create_project_labels, create_project_issues, create_pages, create_cycles, create_modules, create_views) and replaced created_by_id, updated_by_id, and owned_by_id usages with bot_user.id. Seed file reads adapted to apply bot_user for ownership/audit fields.

Sequence Diagram

sequenceDiagram
    participant Task as WorkspaceSeedTask
    participant DB as Database
    participant Helpers as SeedHelpers

    Task->>DB: create bot_user (BotTypeEnum.WORKSPACE_SEED)
    DB-->>Task: bot_user (id)

    Task->>Helpers: create_project_and_member(workspace, bot_user)
    Helpers->>DB: insert projects/members (created_by_id=bot_user.id, owned_by_id=bot_user.id)
    DB-->>Helpers: project_map

    Task->>Helpers: create_project_states(workspace, project_map, bot_user)
    Helpers->>DB: insert states (created_by_id=bot_user.id)
    DB-->>Helpers: states_map

    Task->>Helpers: create_project_labels(workspace, project_map, bot_user)
    Helpers->>DB: insert labels (created_by_id=bot_user.id)
    DB-->>Helpers: labels_map

    Task->>Helpers: create_cycles/create_modules/create_pages/create_views(..., bot_user)
    Helpers->>DB: insert entities (created_by_id/owned_by_id=bot_user.id)
    DB-->>Helpers: maps/results

    Task->>Helpers: create_project_issues(workspace, project_map, states_map, labels_map, cycles_map, module_map, bot_user)
    Helpers->>DB: insert issues (created_by_id/owned_by_id=bot_user.id)
    DB-->>Helpers: issues created
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify every seed helper signature and all call sites consistently accept and pass bot_user.
  • Confirm all seeded entities use bot_user.id for created_by_id, updated_by_id, and owned_by_id.
  • Check bot user creation for required fields (unique username/email, flags) and that BotTypeEnum is correctly imported/exported.
  • Inspect any tests or tooling that assume non-bot ownership for seeded records.

Poem

🐰 A tiny bot with ear held high,
Seeds projects beneath the sky,
Marks each row with one soft paw,
Owned and logged—no need for awe,
Hops away with a satisfied sigh.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description includes most required sections but lacks detailed explanation of changes and comprehensive test scenario documentation. Expand the Description section with detailed explanation of what bot user accomplishes and why it's needed. Provide more comprehensive test scenarios beyond basic verification.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a bot user for workspace seed data creation.
Docstring Coverage ✅ Passed Docstring coverage is 90.91% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore-workspace-seed-task

📜 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 30fce45 and 730e099.

📒 Files selected for processing (1)
  • apps/api/plane/bgtasks/workspace_seed_task.py (18 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.
📚 Learning: 2025-09-12T07:29:36.083Z
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
📚 Learning: 2025-07-23T18:18:06.875Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane 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.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
🧬 Code graph analysis (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)
apps/api/plane/db/models/user.py (2)
  • User (42-168)
  • BotTypeEnum (38-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Build and lint web apps
🔇 Additional comments (3)
apps/api/plane/bgtasks/workspace_seed_task.py (3)

13-13: Imports for bot user functionality look correct and are in use

make_password, User, and BotTypeEnum are all used in workspace_seed and keep the dependency surface minimal. No changes needed.

Also applies to: 38-39


97-107: Consistent use of bot_user for seeded data ownership/audit looks good

Projects, project members, issue user properties, states, labels, issues, cycles, modules, pages, project pages, and views now consistently set created_by_id / updated_by_id / owned_by_id (or actor_id for activities) to bot_user.id, which cleanly separates seed/demo data from real user activity. Also good to see cycle_view, module_view, and issue_views_view forced to True on seeded projects so the demo is fully featured.

Based on learnings, this matches the expectation that workspace seed projects have all views enabled.

Also applies to: 110-119, 122-159, 190-195, 224-228, 275-281, 282-287, 289-296, 301-307, 311-317, 322-328, 350-362, 366-372, 413-421, 449-456, 477-483


378-390: Cycle seeding return behavior is now type‑consistent

create_cycles is annotated to return Dict[int, uuid.UUID] and now returns {} when cycle_seeds is empty while returning a populated cycle_map otherwise. This resolves the earlier inconsistency and keeps call sites simpler.

Also applies to: 419-421


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pablohashescobar pablohashescobar requested review from dheeru0198 and sriramveeraghanta and removed request for Copilot December 3, 2025 09:16
Copilot finished reviewing on behalf of pablohashescobar December 3, 2025 09:17
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

♻️ Duplicate comments (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)

45-47: Remove duplicate BotTypeEnum definition.

This duplicate definition was already flagged in the review of apps/api/plane/db/models/user.py at lines 38-40.

🧹 Nitpick comments (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)

508-519: Use enum value instead of string literal for bot_type.

Line 515 sets bot_type="WORKSPACE_SEED" as a string literal. For type safety and maintainability, use the enum value instead: bot_type=BotTypeEnum.WORKSPACE_SEED.

Apply this diff:

         bot_user = User.objects.create(
             username=f"bot_user_{workspace.id}",
             display_name="Plane Bot",
             first_name="Plane",
             last_name="Bot",
             is_bot=True,
-            bot_type="WORKSPACE_SEED",
+            bot_type=BotTypeEnum.WORKSPACE_SEED,
             email=f"bot_user_{workspace.id}@plane.so",
             password=make_password(uuid.uuid4().hex),
             is_password_autoset=True,
         )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7ffcb and 9d44bb6.

📒 Files selected for processing (2)
  • apps/api/plane/bgtasks/workspace_seed_task.py (18 hunks)
  • apps/api/plane/db/models/user.py (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.
📚 Learning: 2025-09-12T07:29:36.083Z
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
📚 Learning: 2025-07-23T18:18:06.875Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane 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.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
🧬 Code graph analysis (2)
apps/api/plane/db/models/user.py (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)
  • BotTypeEnum (45-46)
apps/api/plane/bgtasks/workspace_seed_task.py (1)
apps/api/plane/db/models/user.py (1)
  • BotTypeEnum (38-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: CodeQL analysis (python)
  • GitHub Check: Agent
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
apps/api/plane/bgtasks/workspace_seed_task.py (6)

13-14: LGTM with note on future cleanup.

The imports are appropriate for the bot user creation workflow. Note that the models import on line 14 will become unnecessary once BotTypeEnum is imported from plane.db.models.user instead of being redefined here.

Also applies to: 39-39


71-168: LGTM!

The function correctly accepts the bot_user parameter and consistently uses bot_user.id for all auditing fields (created_by_id). The bulk create operations for ProjectMember and IssueUserProperty are properly structured.


171-203: LGTM!

All seed creation helper functions have been consistently updated to:

  • Accept the bot_user parameter
  • Use bot_user.id for auditing fields (created_by_id, updated_by_id, owned_by_id, actor_id where applicable)
  • Maintain proper function signatures with updated docstrings

The refactoring is thorough and maintains consistency across the entire seeding workflow.

Also applies to: 206-236, 239-335, 338-379, 382-429, 432-463, 466-487


522-543: LGTM!

All seed creation functions are correctly invoked with the bot_user parameter, maintaining consistency with the updated function signatures. The execution order is logical, creating foundational elements (projects, states, labels) before dependent entities (issues, cycles, modules).


108-110: Proper alignment with workspace seed requirements.

The code correctly enables cycle_view, module_view, and issue_views_view by default for seed data, providing users with a complete demo experience. Based on learnings, this is the expected behavior for seeded workspaces.


508-519: Bot user design is intentional and correct; no membership concern.

The bot user is intentionally excluded from WorkspaceMember and ProjectMember by design—all member queries in the codebase explicitly filter member__is_bot=False. The bot user serves solely as an audit trail (recording created_by, owned_by, and actor fields) and does not participate in permission or membership checks. This design is sound.

However, note that the bot user is never cleaned up, either after successful seeding or if seeding fails (line 546-549). If cleanup is desired, consider deleting the bot user post-seeding or on failure.

Copilot AI review requested due to automatic review settings December 3, 2025 09:27
Copilot finished reviewing on behalf of pablohashescobar December 3, 2025 09:32
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)

487-546: Make bot user creation idempotent to avoid unique-constraint failures on retries

Creating the bot user with User.objects.create(...) and a deterministic username/email based on workspace.id introduces a non‑idempotent step in workspace_seed. If the task is retried or accidentally run twice for the same workspace, the second run will hit the unique constraints on username and/or email and fail before any seeding work happens, leaving the workspace in a partially seeded state that can be hard to recover from.

To make the seeding task safer and retry‑friendly, consider switching to get_or_create keyed by the same identifier you’re using now:

-        # Create a bot user for creating all the workspace data
-        bot_user = User.objects.create(
-            username=f"bot_user_{workspace.id}",
-            display_name="Plane Bot",
-            first_name="Plane",
-            last_name="Bot",
-            is_bot=True,
-            bot_type=BotTypeEnum.WORKSPACE_SEED,
-            email=f"bot_user_{workspace.id}@plane.so",
-            password=make_password(uuid.uuid4().hex),
-            is_password_autoset=True,
-        )
+        # Create or reuse a bot user for creating all the workspace data
+        bot_username = f"bot_user_{workspace.id}"
+        bot_email = f"{bot_username}@plane.so"
+        bot_user, _ = User.objects.get_or_create(
+            username=bot_username,
+            defaults={
+                "display_name": "Plane Bot",
+                "first_name": "Plane",
+                "last_name": "Bot",
+                "is_bot": True,
+                "bot_type": BotTypeEnum.WORKSPACE_SEED,
+                "email": bot_email,
+                "password": make_password(uuid.uuid4().hex),
+                "is_password_autoset": True,
+            },
+        )

This keeps the “one bot per workspace” design but makes the task robust to retries and concurrent executions that might otherwise trip over the unique constraints.

🧹 Nitpick comments (4)
apps/api/plane/bgtasks/workspace_seed_task.py (4)

68-160: Bot user propagation into project/members/user-properties is consistent; minor perf nit

Using bot_user for created_by_id in Project, ProjectMember, and IssueUserProperty keeps ownership/audit consistently attributed to the bot and matches the PR’s goal. Keeping cycle_view, module_view, and issue_views_view enabled on the seed project also aligns with the existing seed-data behavior for full demo workspaces (per prior learning).

One minor optional improvement: workspace_members is iterated twice (for ProjectMember and IssueUserProperty). To avoid re-evaluating the queryset on each loop, you could materialize it once:

-    workspace_members = WorkspaceMember.objects.filter(workspace=workspace).values("member_id", "role")
+    workspace_members = list(
+        WorkspaceMember.objects.filter(workspace=workspace).values("member_id", "role")
+    )

This is non-blocking and just a small efficiency/readability tweak.


236-333: Issue-related entities correctly use bot user; consider tightening required-field validation

Using bot_user.id for Issue.created_by_id, IssueSequence.created_by_id, IssueActivity.actor_id, and all the related IssueLabel, CycleIssue, and ModuleIssue rows matches the intended “Plane bot created everything” story and is implemented consistently.

One improvement opportunity in the existing logic is the required-field check:

for field in required_fields:
    if field not in issue_seed:
        logger.error(...)
        continue

The continue here only skips the rest of the inner loop iteration, but the outer loop still proceeds to access issue_seed[field] later, which would raise a KeyError if the seed is malformed. If you want to enforce that all required fields are present before attempting creation, consider short‑circuiting the whole issue seed:

-        for field in required_fields:
-            if field not in issue_seed:
-                logger.error(f"Task: workspace_seed_task -> Required field '{field}' missing in issue seed")
-                continue
+        for field in required_fields:
+            if field not in issue_seed:
+                logger.error(
+                    "Task: workspace_seed_task -> Required field '%s' missing in issue seed",
+                    field,
+                )
+                # Skip this issue entirely if required data is missing
+                break
+        else:
+            # only executes if no `break` occurred
+            ...

Where the ... wraps the existing logic that extracts fields and creates the issue and related rows. That would make this task more robust against accidental seed-file regressions.


379-426: Cycles now attributed to bot user; consider always returning a dict

Using created_by_id and owned_by_id from bot_user in create_cycles is correct and consistent with other helpers.

Small robustness/tidiness tweak: when cycle_seeds is falsy you currently return without a value, which means callers get None instead of an empty mapping despite the type hint and docstring promising a Dict[int, uuid.UUID]. To make the function behavior predictable, you can initialize cycle_map first and always return it:

-    cycle_seeds = read_seed_file("cycles.json")
-    if not cycle_seeds:
-        return
-
-    cycle_map: Dict[int, uuid.UUID] = {}
+    cycle_map: Dict[int, uuid.UUID] = {}
+    cycle_seeds = read_seed_file("cycles.json")
+    if not cycle_seeds:
+        return cycle_map

This keeps call sites simple and avoids having to handle None specially.


429-460: Modules use bot user attribution; fix the return type hint / empty‑seed behavior

Switching Module.created_by_id to bot_user.id aligns with the rest of the seeding changes.

Two minor consistency issues worth fixing while you’re here:

  1. The function annotation says -> None, but it actually returns module_map.
  2. When module_seeds is falsy, you return without a value, so callers will see None instead of an empty map.

You can address both with a small edit:

-def create_modules(workspace: Workspace, project_map: Dict[int, uuid.UUID], bot_user: User) -> None:
+def create_modules(
+    workspace: Workspace, project_map: Dict[int, uuid.UUID], bot_user: User
+) -> Dict[int, uuid.UUID]:
@@
-    module_seeds = read_seed_file("modules.json")
-    if not module_seeds:
-        return
-
-    module_map: Dict[int, uuid.UUID] = {}
+    module_map: Dict[int, uuid.UUID] = {}
+    module_seeds = read_seed_file("modules.json")
+    if not module_seeds:
+        return module_map

This keeps the API accurate and avoids None leaking to callers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d44bb6 and 9346c35.

📒 Files selected for processing (2)
  • apps/api/plane/bgtasks/workspace_seed_task.py (18 hunks)
  • apps/api/plane/db/models/__init__.py (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.
📚 Learning: 2025-09-12T07:29:36.083Z
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
📚 Learning: 2025-07-23T18:18:06.875Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane 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.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
🧬 Code graph analysis (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)
apps/api/plane/db/models/user.py (2)
  • User (42-168)
  • BotTypeEnum (38-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Agent
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
apps/api/plane/db/models/__init__.py (1)

61-61: Making BotTypeEnum part of the public model surface looks correct

Exporting BotTypeEnum alongside User keeps the public API consistent and allows call sites (like the workspace seed task) to depend on plane.db.models without reaching into internal modules. No issues here.

apps/api/plane/bgtasks/workspace_seed_task.py (5)

13-15: New model and auth-related imports are aligned with later usage

The additional imports (make_password, User, BotTypeEnum) are all used in workspace_seed and keep the dependencies local to this task module. No issues with the import changes themselves.

Also applies to: 39-41


168-200: State creation now correctly attributes rows to the bot user

Passing bot_user into create_project_states and setting created_by_id=bot_user.id ensures all seed states are owned by the bot user while leaving other behavior unchanged. Looks good.


203-233: Label seeding attribution to bot user is straightforward and correct

create_project_labels now takes bot_user and uses created_by_id=bot_user.id for all labels. This cleanly switches attribution without altering label semantics. No changes needed.


335-376: Page and project-page ownership/auditing via bot user is coherent

For Page and ProjectPage you now set created_by_id, updated_by_id, and (where applicable) owned_by_id to bot_user.id. This provides a clear audit trail that the Plane bot seeded these records while still associating them to the correct workspace/project. Implementation looks sound.


463-484: Views seeding cleanly adopts bot user for ownership

create_views now sets both created_by_id and owned_by_id from bot_user.id for each IssueView, which is consistent with how cycles and pages are handled. Behavior otherwise unchanged; looks good.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a dedicated bot user account for workspace seed data creation, improving audit trail accuracy by attributing all initial workspace data to a system bot instead of the workspace creator.

Key Changes

  • Added BotTypeEnum.WORKSPACE_SEED to classify bot users by their purpose
  • Modified workspace seed task to create a dedicated bot user per workspace
  • Updated all seed data creation functions to use the bot user ID for created_by_id fields

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
apps/api/plane/db/models/user.py Introduces BotTypeEnum with WORKSPACE_SEED type for categorizing bot users
apps/api/plane/db/models/init.py Exports BotTypeEnum to make it available throughout the codebase
apps/api/plane/bgtasks/workspace_seed_task.py Creates a unique bot user per workspace and propagates it through all seed data creation functions (projects, states, labels, issues, pages, cycles, modules, views) to ensure consistent attribution
Comments suppressed due to low confidence (1)

apps/api/plane/bgtasks/workspace_seed_task.py:14

  • Import of 'models' is not used.
from django.db import models

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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: 2

♻️ Duplicate comments (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)

505-515: Use get_or_create() for idempotent bot user creation.

If the workspace seed task is retried for the same workspace, User.objects.create() will fail on unique constraint violations for the username and email fields. Use get_or_create() to handle retries gracefully.

Apply this diff:

-        bot_user = User.objects.create(
-            username=f"bot_user_{workspace.id}",
-            display_name="Plane",
-            first_name="Plane",
-            last_name="",
-            is_bot=True,
-            bot_type=BotTypeEnum.WORKSPACE_SEED,
-            email=f"bot_user_{workspace.id}@plane.so",
-            password=make_password(uuid.uuid4().hex),
-            is_password_autoset=True,
-        )
+        bot_user, created = User.objects.get_or_create(
+            username=f"bot_user_{workspace.id}",
+            defaults={
+                "display_name": "Plane",
+                "first_name": "Plane",
+                "last_name": "",
+                "is_bot": True,
+                "bot_type": BotTypeEnum.WORKSPACE_SEED,
+                "email": f"bot_user_{workspace.id}@plane.so",
+                "password": make_password(uuid.uuid4().hex),
+                "is_password_autoset": True,
+            }
+        )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9346c35 and 30fce45.

📒 Files selected for processing (1)
  • apps/api/plane/bgtasks/workspace_seed_task.py (18 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.
📚 Learning: 2025-09-12T07:29:36.083Z
Learnt from: dheeru0198
Repo: makeplane/plane PR: 7625
File: apps/api/plane/bgtasks/workspace_seed_task.py:95-98
Timestamp: 2025-09-12T07:29:36.083Z
Learning: In the Plane codebase, workspace seed data should have project features (cycle_view, module_view, issue_views_view) enabled by default, even when regular project creation has these features disabled. This provides users with a complete demo experience in the seeded workspace.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
📚 Learning: 2025-07-23T18:18:06.875Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane 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.

Applied to files:

  • apps/api/plane/bgtasks/workspace_seed_task.py
🧬 Code graph analysis (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)
apps/api/plane/db/models/user.py (2)
  • User (42-168)
  • BotTypeEnum (38-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build and lint web apps
  • GitHub Check: Analyze (javascript)

@sriramveeraghanta
Copy link
Member

@pablohashescobar Look into the Coderabbit suggestion and resolve the conversations.

@sriramveeraghanta sriramveeraghanta merged commit d34c7f9 into preview Dec 5, 2025
7 checks passed
@sriramveeraghanta sriramveeraghanta deleted the chore-workspace-seed-task branch December 5, 2025 12:34
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.

4 participants