Coverage for src/lexigram/admin/rbac/schema.py: 100%

21 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-24 23:39 +0800

1"""Permission schemas for resources, fields, and actions.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass, field 

6 

7 

8@dataclass 

9class FieldPermission: 

10 """Permission rules for a single field.""" 

11 

12 view_roles: set[str] = field(default_factory=lambda: {"*"}) # Who can see 

13 edit_roles: set[str] = field(default_factory=lambda: {"*"}) # Who can edit 

14 mask_for: set[str] = field(default_factory=set) # Roles to mask for 

15 

16 

17@dataclass 

18class ActionPermission: 

19 """Permission rules for an action button/operation.""" 

20 

21 allowed_roles: set[str] = field(default_factory=lambda: {"*"}) 

22 condition: str | None = None # UI-side condition (e.g. Alpine expression) 

23 

24 

25@dataclass 

26class ResourcePermissions: 

27 """Complete permission schema for a resource.""" 

28 

29 # CRUD permissions (sets of roles, "*" means any role) 

30 can_list: set[str] = field(default_factory=lambda: {"*"}) 

31 can_view: set[str] = field(default_factory=lambda: {"*"}) 

32 can_create: set[str] = field(default_factory=lambda: {"*"}) 

33 can_edit: set[str] = field(default_factory=lambda: {"*"}) 

34 can_delete: set[str] = field(default_factory=lambda: {"admin"}) 

35 

36 # Field-level permissions 

37 fields: dict[str, FieldPermission] = field(default_factory=dict) 

38 

39 # Action-level permissions 

40 actions: dict[str, ActionPermission] = field(default_factory=dict) 

41 

42 # RLS policy name or identifier 

43 rls_policy: str | None = None