From a81a3ee0e5a371773ba2fc12c058f4eb46b3dbcb Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 13 Aug 2025 11:05:05 +0200 Subject: [PATCH] feat!: rename right to permission (#1277) --- .golangci.yml | 2 +- AGENTS.md | 16 +- .../e2e/project/project-view-list.spec.ts | 2 +- .../cypress/e2e/sharing/linkShare.spec.ts | 2 +- frontend/cypress/factories/link_sharing.ts | 2 +- frontend/cypress/factories/users_project.ts | 2 +- frontend/src/components/home/AppHeader.vue | 4 +- .../home/ProjectsNavigationItem.vue | 8 +- .../project/ProjectSettingsDropdown.vue | 4 +- .../src/components/project/ProjectWrapper.vue | 2 +- .../components/project/views/ProjectGantt.vue | 4 +- .../project/views/ProjectKanban.vue | 4 +- .../components/project/views/ProjectList.vue | 4 +- .../src/components/sharing/LinkSharing.vue | 34 ++-- frontend/src/components/sharing/UserTeam.vue | 54 ++--- frontend/src/constants/permissions.ts | 7 + frontend/src/constants/rights.ts | 7 - frontend/src/modelTypes/IAbstract.ts | 4 +- frontend/src/modelTypes/ILinkShare.ts | 4 +- frontend/src/modelTypes/ITeam.ts | 4 +- frontend/src/modelTypes/ITeamShareBase.ts | 4 +- frontend/src/modelTypes/IUserShareBase.ts | 4 +- frontend/src/models/abstractModel.ts | 6 +- frontend/src/models/linkShare.ts | 4 +- frontend/src/models/team.ts | 4 +- frontend/src/models/teamShareBase.ts | 4 +- frontend/src/models/userProject.ts | 2 +- frontend/src/models/userShareBase.ts | 4 +- frontend/src/services/abstractService.ts | 12 +- frontend/src/stores/base.ts | 18 +- frontend/src/stores/projects.ts | 6 +- .../project/settings/ProjectSettingsEdit.vue | 4 +- .../project/settings/ProjectSettingsShare.vue | 4 +- .../project/settings/ProjectSettingsViews.vue | 4 +- frontend/src/views/tasks/TaskDetailView.vue | 6 +- frontend/src/views/teams/EditTeam.vue | 6 +- magefile.go | 4 +- pkg/db/fixtures/link_shares.yml | 8 +- pkg/db/fixtures/team_projects.yml | 30 +-- pkg/db/fixtures/users_projects.yml | 38 ++-- pkg/mail/send_mail.go | 2 +- pkg/migration/20190818210133.go | 2 +- pkg/migration/20250813093602.go | 44 +++++ pkg/migration/migration.go | 76 +++++++ pkg/models/api_routes.go | 6 +- pkg/models/api_tokens.go | 13 +- ...ns_rights.go => api_tokens_permissions.go} | 0 pkg/models/error.go | 42 ++-- pkg/models/kanban.go | 4 +- ...kanban_rights.go => kanban_permissions.go} | 2 +- pkg/models/kanban_task_bucket.go | 4 +- pkg/models/kanban_test.go | 6 +- pkg/models/label.go | 4 +- .../{label_rights.go => label_permissions.go} | 6 +- pkg/models/label_task.go | 14 +- ...sk_rights.go => label_task_permissions.go} | 0 pkg/models/label_task_test.go | 76 +++---- pkg/models/label_test.go | 30 +-- pkg/models/link_sharing.go | 12 +- ..._rights.go => link_sharing_permissions.go} | 12 +- pkg/models/link_sharing_test.go | 18 +- pkg/models/notifications_database.go | 4 +- pkg/models/{rights.go => permissions.go} | 36 ++-- pkg/models/project.go | 26 +-- pkg/models/project_duplicate.go | 12 +- ...oject_rights.go => project_permissions.go} | 53 ++--- pkg/models/project_team.go | 36 ++-- ..._rights.go => project_team_permissions.go} | 0 pkg/models/project_team_test.go | 94 ++++----- pkg/models/project_users.go | 36 ++-- ...rights.go => project_users_permissions.go} | 0 ...t.go => project_users_permissions_test.go} | 34 ++-- pkg/models/project_users_test.go | 186 +++++++++--------- pkg/models/project_view.go | 4 +- ..._rights.go => project_view_permissions.go} | 0 pkg/models/reaction.go | 4 +- ...tion_rights.go => reaction_permissions.go} | 0 pkg/models/saved_filters.go | 6 +- ...rights.go => saved_filters_permissions.go} | 12 +- pkg/models/saved_filters_test.go | 6 +- pkg/models/subscription.go | 6 +- ..._rights.go => subscription_permissions.go} | 0 pkg/models/subscription_test.go | 4 +- pkg/models/task_assignees.go | 8 +- ...ights.go => task_assignees_permissions.go} | 0 pkg/models/task_attachment.go | 4 +- ...ghts.go => task_attachment_permissions.go} | 0 pkg/models/task_attachment_test.go | 2 +- pkg/models/task_collection.go | 4 +- pkg/models/task_collection_test.go | 8 +- ..._rights.go => task_comment_permissions.go} | 0 pkg/models/task_comments.go | 4 +- pkg/models/task_position.go | 4 +- pkg/models/task_relation.go | 6 +- ...rights.go => task_relation_permissions.go} | 0 pkg/models/task_relation_test.go | 6 +- pkg/models/tasks.go | 6 +- .../{tasks_rights.go => tasks_permissions.go} | 8 +- pkg/models/tasks_test.go | 2 +- pkg/models/team_members.go | 6 +- ..._rights.go => team_members_permissions.go} | 2 +- pkg/models/team_members_test.go | 2 +- pkg/models/teams.go | 8 +- .../{teams_rights.go => teams_permissions.go} | 6 +- ...ghts_test.go => teams_permissions_test.go} | 6 +- pkg/models/teams_test.go | 12 +- pkg/models/user_delete.go | 24 +-- pkg/models/user_project.go | 12 +- pkg/models/webhooks.go | 4 +- ...ooks_rights.go => webhooks_permissions.go} | 0 pkg/modules/auth/auth.go | 2 +- pkg/modules/background/handler/background.go | 8 +- pkg/routes/api/v1/task_attachment.go | 4 +- pkg/routes/api/v1/user_list.go | 2 +- pkg/routes/caldav/listStorageProvider.go | 6 +- pkg/routes/routes.go | 6 +- pkg/swagger/docs.go | 14 +- pkg/web/handler/create.go | 4 +- pkg/web/handler/delete.go | 4 +- pkg/web/handler/helper.go | 2 +- pkg/web/handler/read_one.go | 12 +- pkg/web/handler/update.go | 4 +- pkg/web/readme.md | 28 +-- pkg/web/web.go | 4 +- pkg/webtests/kanban_test.go | 8 +- pkg/webtests/link_share_avatar_test.go | 2 +- pkg/webtests/link_sharing_test.go | 42 ++-- pkg/webtests/project_test.go | 38 ++-- pkg/webtests/task_comment_test.go | 8 +- pkg/webtests/task_test.go | 8 +- 130 files changed, 872 insertions(+), 752 deletions(-) create mode 100644 frontend/src/constants/permissions.ts delete mode 100644 frontend/src/constants/rights.ts create mode 100644 pkg/migration/20250813093602.go rename pkg/models/{api_tokens_rights.go => api_tokens_permissions.go} (100%) rename pkg/models/{kanban_rights.go => kanban_permissions.go} (98%) rename pkg/models/{label_rights.go => label_permissions.go} (94%) rename pkg/models/{label_task_rights.go => label_task_permissions.go} (100%) rename pkg/models/{link_sharing_rights.go => link_sharing_permissions.go} (83%) rename pkg/models/{rights.go => permissions.go} (68%) rename pkg/models/{project_rights.go => project_permissions.go} (80%) rename pkg/models/{project_team_rights.go => project_team_permissions.go} (100%) rename pkg/models/{project_users_rights.go => project_users_permissions.go} (100%) rename pkg/models/{project_users_rights_test.go => project_users_permissions_test.go} (81%) rename pkg/models/{project_view_rights.go => project_view_permissions.go} (100%) rename pkg/models/{reaction_rights.go => reaction_permissions.go} (100%) rename pkg/models/{saved_filters_rights.go => saved_filters_permissions.go} (83%) rename pkg/models/{subscription_rights.go => subscription_permissions.go} (100%) rename pkg/models/{task_assignees_rights.go => task_assignees_permissions.go} (100%) rename pkg/models/{task_attachment_rights.go => task_attachment_permissions.go} (100%) rename pkg/models/{task_comment_rights.go => task_comment_permissions.go} (100%) rename pkg/models/{task_relation_rights.go => task_relation_permissions.go} (100%) rename pkg/models/{tasks_rights.go => tasks_permissions.go} (90%) rename pkg/models/{team_members_rights.go => team_members_permissions.go} (96%) rename pkg/models/{teams_rights.go => teams_permissions.go} (96%) rename pkg/models/{teams_rights_test.go => teams_permissions_test.go} (95%) rename pkg/models/{webhooks_rights.go => webhooks_permissions.go} (100%) diff --git a/.golangci.yml b/.golangci.yml index 304e41de1..4800096d9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -139,7 +139,7 @@ linters: text: 'G115: integer overflow conversion int -> uint64' - linters: - recvcheck - text: the methods of "Right" use pointer receiver and non-pointer receiver. + text: the methods of "Permission" use pointer receiver and non-pointer receiver. - linters: - recvcheck text: the methods of "SubscriptionEntityType" use pointer receiver and non-pointer receiver. diff --git a/AGENTS.md b/AGENTS.md index 54b4ba1ca..18025e6ce 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -73,7 +73,7 @@ The Go backend follows a layered architecture with clear separation of concerns: **Key Patterns:** - **Generic CRUD**: Models implement `CRUDable` interface for standardized database operations -- **Rights System**: Three-tier permissions (Read/Write/Admin) enforced across all operations +- **Permissions System**: Three-tier permissions (Read/Write/Admin) enforced across all operations - **Event-Driven**: Event system for notifications, webhooks, and cross-cutting concerns - **Modular Design**: Pluggable authentication, avatar providers, migration tools @@ -115,7 +115,7 @@ Modern Vue 3 composition API application with TypeScript: ### Adding New Features **Backend Changes:** -1. Create/modify models in `pkg/models/` with proper CRUD and Rights interfaces as required +1. Create/modify models in `pkg/models/` with proper CRUD and Permissions interfaces as required 2. Add database migration if needed: `mage dev:make-migration ` 3. Create/update services in `pkg/services/` for complex business logic 4. Add API routes in `pkg/routes/api/v1/` following existing patterns @@ -137,7 +137,7 @@ Modern Vue 3 composition API application with TypeScript: ### API Development - All API endpoints follow RESTful conventions under `/api/v1/` - Use generic web handlers in `pkg/web/handler/` for standard CRUD operations -- Implement proper rights checking using the Rights interface +- Implement proper permissions checking using the Permissions interface - Add Swagger annotations for automatic documentation generation ### Testing @@ -175,7 +175,7 @@ After adjusting the source string, you need to call the respective translation l - Use `pkg/config/` for configuration management **Code Style:** -- Go: golangci-lint per `.golangci.yml`; use goimports; wrap errors with `fmt.Errorf("...: %w", err)`; enforce rights checks in models; never log secrets; do not edit generated `pkg/swagger/*` +- Go: golangci-lint per `.golangci.yml`; use goimports; wrap errors with `fmt.Errorf("...: %w", err)`; enforce permissions checks in models; never log secrets; do not edit generated `pkg/swagger/*` - Vue: ESLint + TS; single quotes, trailing commas, no semicolons, tab indent; script setup + lang ts; keep services/models in sync with backend - Follow existing patterns for consistency @@ -184,16 +184,16 @@ After adjusting the source string, you need to call the respective translation l - Vue: PascalCase for components, camelCase for composables - API endpoints: kebab-case in URLs, camelCase in JSON -**Rights and Permissions:** -- Always implement Rights interface for new models +**Permissions and Permissions:** +- Always implement Permissions interface for new models - Use `CanRead`, `CanWrite`, `CanCreate`, `CanDelete` methods -- Rights are enforced at the model level, not just routes +- Permissions are enforced at the model level, not just routes ## Common Gotchas - Database migrations are irreversible in production - test thoroughly - Frontend services must match backend model structure exactly -- Rights checking is mandatory for all CRUD operations +- Permissions checking is mandatory for all CRUD operations - Event listeners in `pkg/*/listeners.go` must be registered properly - CORS settings in backend must allow frontend domain - API tokens have different scopes - check permissions carefully diff --git a/frontend/cypress/e2e/project/project-view-list.spec.ts b/frontend/cypress/e2e/project/project-view-list.spec.ts index a6414621d..482fcce98 100644 --- a/frontend/cypress/e2e/project/project-view-list.spec.ts +++ b/frontend/cypress/e2e/project/project-view-list.spec.ts @@ -59,7 +59,7 @@ describe('Project View List', () => { UserProjectFactory.create(1, { project_id: 2, user_id: 1, - right: 0, + permission: 0, }) const projects = ProjectFactory.create(2, { owner_id: '{increment}', diff --git a/frontend/cypress/e2e/sharing/linkShare.spec.ts b/frontend/cypress/e2e/sharing/linkShare.spec.ts index 37b5b8cc3..0792948f7 100644 --- a/frontend/cypress/e2e/sharing/linkShare.spec.ts +++ b/frontend/cypress/e2e/sharing/linkShare.spec.ts @@ -11,7 +11,7 @@ function prepareLinkShare() { }) const linkShares = LinkShareFactory.create(1, { project_id: projects[0].id, - right: 0, + permission: 0, }) return { diff --git a/frontend/cypress/factories/link_sharing.ts b/frontend/cypress/factories/link_sharing.ts index c420e6297..b09ddfca2 100644 --- a/frontend/cypress/factories/link_sharing.ts +++ b/frontend/cypress/factories/link_sharing.ts @@ -11,7 +11,7 @@ export class LinkShareFactory extends Factory { id: '{increment}', hash: faker.lorem.word(32), project_id: 1, - right: 0, + permission: 0, sharing_type: 0, shared_by_id: 1, created: now.toISOString(), diff --git a/frontend/cypress/factories/users_project.ts b/frontend/cypress/factories/users_project.ts index c85ed2371..b6bdde356 100644 --- a/frontend/cypress/factories/users_project.ts +++ b/frontend/cypress/factories/users_project.ts @@ -10,7 +10,7 @@ export class UserProjectFactory extends Factory { id: '{increment}', project_id: 1, user_id: 1, - right: 0, + permission: 0, created: now.toISOString(), updated: now.toISOString(), } diff --git a/frontend/src/components/home/AppHeader.vue b/frontend/src/components/home/AppHeader.vue index e5dd2aa9b..14056f3a4 100644 --- a/frontend/src/components/home/AppHeader.vue +++ b/frontend/src/components/home/AppHeader.vue @@ -116,7 +116,7 @@