fec3953009
- Three category scopes: personal / group / system (watch) - PascalCase-with-dashes naming convention enforced at backend + frontend - is_group_admin flag on GroupMembership; PATCH endpoint for admins to toggle it - Categories router: scope-based list/create/rename/delete with _check_can_manage_cat - Documents router: delete uses is_admin + can_delete share flag + group-admin check; remove_category requires doc ownership; assign_category accepts group/system categories - Proxy layers inject x-user-is-admin and x-user-admin-groups headers - Frontend: ManageCategoriesDialog grouped by scope with lock icons; SourcePanel scope picker + client-side name validation; AdminGroupsPage group-admin checkbox Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
2026-04-18 — Category scopes, group admin role, and permission model
Timestamp: 2026-04-18T00:00:00Z
Summary
Introduces three category scopes (personal / group / system), a PascalCase-with-dashes naming convention, a group-admin role on group memberships, and a full permission model for who can create, rename, and delete categories and documents.
Files Added
backend/alembic/versions/e1f2a3b4c5d6_add_group_member_is_admin.py— addsis_group_admin BOOLEANtogroup_membershipsfeatures/doc-service/alembic/versions/0005_add_share_can_delete.py— addscan_delete BOOLEANtodocument_shares(backfill from feat/document-delete-permissions)features/doc-service/alembic/versions/0006_add_category_scope.py— addsscope VARCHAR(16)andgroup_id VARCHARtodocument_categories; data-migrates watch categories to scope='system'
Files Modified
backend/app/models/group.py— addedis_group_admintoGroupMembershipbackend/app/schemas/group.py— addedis_group_admintoGroupMemberOut; newGroupMemberAdminUpdatebackend/app/schemas/user.py— addedis_group_admintoUserGroupOutbackend/app/routers/users.py—get_my_groupsnow joinsGroupMembershipto includeis_group_adminbackend/app/routers/groups.py—get_groupincludesis_group_admin; newPATCH /{id}/members/{user_id}/adminendpointbackend/app/routers/categories_proxy.py— injectsx-user-is-adminandx-user-admin-groupsheadersbackend/app/routers/documents_proxy.py— injectsx-user-admin-groupsheader (was already injectingx-user-is-admin)features/doc-service/app/models/category.py— addedscope,group_idcolumnsfeatures/doc-service/app/schemas/category.py—CategoryOutincludesscope/group_id;CategoryCreateacceptsgroup_idfeatures/doc-service/app/deps.py— addedget_user_is_admin,get_user_admin_groupsfeatures/doc-service/app/routers/categories.py— full rewrite: name validation regex, scope-based list/create,_check_can_manage_catpermission helper, scope-aware rename/deletefeatures/doc-service/app/routers/documents.py—delete_documentenforces is_admin/can_delete/group-admin hierarchy;remove_categoryrequires doc ownership;assign_categoryaccepts group/system categoriesfrontend/src/api/client.ts—CategoryOutgainsscope/group_id;createCategoryaccepts optionalgroupId;UserGroupOut/GroupMemberOutgainis_group_admin; newadminSetGroupMemberAdmin();ApiErrorexportedfrontend/src/components/ManageCategoriesDialog.tsx— categories grouped by scope; lock icons for unmanageable categories; rename/delete gated by scope permissions; inline rename error displayfrontend/src/components/SourcePanel.tsx— categories shown in sections (Mine / Group name / System); scope picker on new category form; client-side name validationfrontend/src/pages/AdminGroupsPage.tsx— group admin checkbox column in members tablebackend/CLAUDE.md— updatedgroup_membershipsmodel, migration chain, endpointsfeatures/doc-service/CLAUDE.md— updateddocument_categoriesmodel,document_sharesmodel, migration chain, deps note