-
Notifications
You must be signed in to change notification settings - Fork 2.9k
[WEB-5254] chore: add bot user to create workspace seed data #8225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Linked to Plane Work Item(s) This comment was auto-generated by Plane |
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughAdds 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 Changes
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (3)📓 Common learnings📚 Learning: 2025-09-12T07:29:36.083ZApplied to files:
📚 Learning: 2025-07-23T18:18:06.875ZApplied to files:
🧬 Code graph analysis (1)apps/api/plane/bgtasks/workspace_seed_task.py (1)
⏰ 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)
🔇 Additional comments (3)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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.pyat 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
📒 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
modelsimport on line 14 will become unnecessary onceBotTypeEnumis imported fromplane.db.models.userinstead of being redefined here.Also applies to: 39-39
71-168: LGTM!The function correctly accepts the
bot_userparameter and consistently usesbot_user.idfor all auditing fields (created_by_id). The bulk create operations forProjectMemberandIssueUserPropertyare properly structured.
171-203: LGTM!All seed creation helper functions have been consistently updated to:
- Accept the
bot_userparameter- Use
bot_user.idfor auditing fields (created_by_id,updated_by_id,owned_by_id,actor_idwhere 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_userparameter, 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, andissue_views_viewby 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
WorkspaceMemberandProjectMemberby design—all member queries in the codebase explicitly filtermember__is_bot=False. The bot user serves solely as an audit trail (recordingcreated_by,owned_by, andactorfields) 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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 retriesCreating the bot user with
User.objects.create(...)and a deterministicusername/workspace.idintroduces a non‑idempotent step inworkspace_seed. If the task is retried or accidentally run twice for the same workspace, the second run will hit the unique constraints onusernameand/orTo make the seeding task safer and retry‑friendly, consider switching to
get_or_createkeyed 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 nitUsing
bot_userforcreated_by_idinProject,ProjectMember, andIssueUserPropertykeeps ownership/audit consistently attributed to the bot and matches the PR’s goal. Keepingcycle_view,module_view, andissue_views_viewenabled on the seed project also aligns with the existing seed-data behavior for full demo workspaces (per prior learning).One minor optional improvement:
workspace_membersis iterated twice (forProjectMemberandIssueUserProperty). 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 validationUsing
bot_user.idforIssue.created_by_id,IssueSequence.created_by_id,IssueActivity.actor_id, and all the relatedIssueLabel,CycleIssue, andModuleIssuerows 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(...) continueThe
continuehere only skips the rest of the inner loop iteration, but the outer loop still proceeds to accessissue_seed[field]later, which would raise aKeyErrorif 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 dictUsing
created_by_idandowned_by_idfrombot_userincreate_cyclesis correct and consistent with other helpers.Small robustness/tidiness tweak: when
cycle_seedsis falsy you currentlyreturnwithout a value, which means callers getNoneinstead of an empty mapping despite the type hint and docstring promising aDict[int, uuid.UUID]. To make the function behavior predictable, you can initializecycle_mapfirst 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_mapThis keeps call sites simple and avoids having to handle
Nonespecially.
429-460: Modules use bot user attribution; fix the return type hint / empty‑seed behaviorSwitching
Module.created_by_idtobot_user.idaligns with the rest of the seeding changes.Two minor consistency issues worth fixing while you’re here:
- The function annotation says
-> None, but it actually returnsmodule_map.- When
module_seedsis falsy, youreturnwithout a value, so callers will seeNoneinstead 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_mapThis keeps the API accurate and avoids
Noneleaking to callers.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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: MakingBotTypeEnumpart of the public model surface looks correctExporting
BotTypeEnumalongsideUserkeeps the public API consistent and allows call sites (like the workspace seed task) to depend onplane.db.modelswithout 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 usageThe additional imports (
make_password,User,BotTypeEnum) are all used inworkspace_seedand 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 userPassing
bot_userintocreate_project_statesand settingcreated_by_id=bot_user.idensures 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_labelsnow takesbot_userand usescreated_by_id=bot_user.idfor 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 coherentFor
PageandProjectPageyou now setcreated_by_id,updated_by_id, and (where applicable)owned_by_idtobot_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_viewsnow sets bothcreated_by_idandowned_by_idfrombot_user.idfor eachIssueView, which is consistent with how cycles and pages are handled. Behavior otherwise unchanged; looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a 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_SEEDto 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_idfields
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
apps/api/plane/bgtasks/workspace_seed_task.py (1)
505-515: Useget_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 theusernameandget_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
📒 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)
|
@pablohashescobar Look into the Coderabbit suggestion and resolve the conversations. |
…rkspace seed task
Description
Type of Change
Test Scenarios
References
WEB-5254
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.