Group Management

Overview Description

The Group Management feature provides administrators with tools to oversee and manage organizational groups within the system. Administrators can view, create, edit, and delete groups, as well as change their status. Each group has associated attributes including a name, creator, package subscription, and status. This feature implements role-based access controls, where certain operations may be restricted based on the administrator's role level or relationship to the group.

Activity Diagram

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    %% Main components
    AdminUser[Admin User]
    AdminInterface[Group Management Interface]
    ActionSelect{Action Selection}
    
    %% Flow connections with numbered steps
    AdminUser --- Step1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>Access Interface</p>
        </div>
    ]
    Step1 --> AdminInterface
    
    AdminInterface --- Step2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>Select Action</p>
        </div>
    ]
    Step2 --> ActionSelect
    
    ActionSelect --- Step3A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3A</span>
            <p style='margin-top: 8px'>View Groups</p>
        </div>
    ]
    Step3A --> ViewGroups[List Groups]
    
    ActionSelect --- Step3B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3B</span>
            <p style='margin-top: 8px'>View Details</p>
        </div>
    ]
    Step3B --> GroupDetails[Group Details]
    
    ActionSelect --- Step3C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3C</span>
            <p style='margin-top: 8px'>Create Group</p>
        </div>
    ]
    Step3C --> CreateForm[Group Creation Form]
    
    ActionSelect --- Step3D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3D</span>
            <p style='margin-top: 8px'>Update Group</p>
        </div>
    ]
    Step3D --> EditForm[Group Edit Form]
    
    ActionSelect --- Step3E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3E</span>
            <p style='margin-top: 8px'>Change Status</p>
        </div>
    ]
    Step3E --> ToggleStatus[Toggle Group Status]
    
    ActionSelect --- Step3F[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3F</span>
            <p style='margin-top: 8px'>Delete Group</p>
        </div>
    ]
    Step3F --> DeleteConfirm{Confirm Deletion}
    
    ViewGroups --- Step4A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4A</span>
            <p style='margin-top: 8px'>Filter/Sort</p>
        </div>
    ]
    Step4A --> FilterSort[Apply Filters/Sorting]
    
    CreateForm --- Step4C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4C</span>
            <p style='margin-top: 8px'>Validate</p>
        </div>
    ]
    Step4C --> ValidateCreate{Validate Input}
    
    EditForm --- Step4D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4D</span>
            <p style='margin-top: 8px'>Validate</p>
        </div>
    ]
    Step4D --> ValidateEdit{Validate Input}
    
    ToggleStatus --- Step4E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4E</span>
            <p style='margin-top: 8px'>Update Status</p>
        </div>
    ]
    Step4E --> UpdateStatusDB[Update Status in Database]
    
    DeleteConfirm --- Step4F[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4F</span>
            <p style='margin-top: 8px'>Delete Record</p>
        </div>
    ]
    Step4F --> DeleteGroupDB[Delete Group from Database]
    
    ValidateCreate --- Step5C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5C</span>
            <p style='margin-top: 8px'>Create Record</p>
        </div>
    ]
    Step5C --> CreateGroupDB[Create Group in Database]
    
    ValidateEdit --- Step5D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5D</span>
            <p style='margin-top: 8px'>Update Record</p>
        </div>
    ]
    Step5D --> UpdateGroupDB[Update Group in Database]
    
    FilterSort --- Step5A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5A</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step5A --> AdminInterface
    
    CreateGroupDB --- Step6C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6C</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step6C --> AdminInterface
    
    UpdateGroupDB --- Step6D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6D</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step6D --> AdminInterface
    
    UpdateStatusDB --- Step5E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5E</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step5E --> AdminInterface
    
    DeleteGroupDB --- Step5F[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5F</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step5F --> AdminInterface
    
    ValidateCreate -.->|Invalid| CreateForm
    ValidateEdit -.->|Invalid| EditForm
    DeleteConfirm -.->|Cancel| AdminInterface
    
    %% Styling
    style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style AdminInterface fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style ActionSelect fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style ViewGroups fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style GroupDetails fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style CreateForm fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style EditForm fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ToggleStatus fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style DeleteConfirm fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style FilterSort fill:#fff0f5,stroke:#cc6699,stroke-width:2px
    style ValidateCreate fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style ValidateEdit fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style UpdateStatusDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style DeleteGroupDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style CreateGroupDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style UpdateGroupDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    
    style Step1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step3A fill:transparent,stroke:transparent,stroke-width:1px
    style Step3B fill:transparent,stroke:transparent,stroke-width:1px
    style Step3C fill:transparent,stroke:transparent,stroke-width:1px
    style Step3D fill:transparent,stroke:transparent,stroke-width:1px
    style Step3E fill:transparent,stroke:transparent,stroke-width:1px
    style Step3F fill:transparent,stroke:transparent,stroke-width:1px
    style Step4A fill:transparent,stroke:transparent,stroke-width:1px
    style Step4C fill:transparent,stroke:transparent,stroke-width:1px
    style Step4D fill:transparent,stroke:transparent,stroke-width:1px
    style Step4E fill:transparent,stroke:transparent,stroke-width:1px
    style Step4F fill:transparent,stroke:transparent,stroke-width:1px
    style Step5A fill:transparent,stroke:transparent,stroke-width:1px
    style Step5C fill:transparent,stroke:transparent,stroke-width:1px
    style Step5D fill:transparent,stroke:transparent,stroke-width:1px
    style Step5E fill:transparent,stroke:transparent,stroke-width:1px
    style Step5F fill:transparent,stroke:transparent,stroke-width:1px
    style Step6C fill:transparent,stroke:transparent,stroke-width:1px
    style Step6D fill:transparent,stroke:transparent,stroke-width:1px

API: Group Management API

Case Documentation

Case 1: Listing Groups

Description

Administrator retrieves a paginated list of groups with optional filtering and sorting.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as GroupController
    participant Service as GroupService
    participant DB as Database

    Note over Admin,DB: Step 1: Request Group List
    Admin->>API: GET /api/admin/groups (with query params)
    
    Note over API,Service: Step 2: Retrieve Group Data
    API->>Service: list(params)
    Service->>DB: Query Groups with Filters
    DB-->>Service: Return Matching Groups
    Service-->>API: Return Paginated Results
    
    Note over API,Admin: Step 3: Return Group List
    API-->>Admin: 200 OK (groups collection)

Steps

Step 1: Request Group List

  • Description: Admin requests the list of groups with optional filters
  • Request: GET /api/admin/groups
  • Query Parameters:
    • perpage: Number of items per page
    • page: Page number
    • name: Filter groups by name
    • orderBy: Field to order by
    • sortBy: Sort direction (asc or desc)
    • status: Filter groups by status

Step 2: Retrieve Group Data

  • Description: System fetches groups from the database based on filters
  • Action:
    • Apply filters from query parameters
    • Include related data (creator, package)
    • Paginate the results

Step 3: Return Group List

  • Description: Return the paginated list of groups
  • Response:
    • Success: 200 OK with group collection and pagination metadata
    • Error: Appropriate error message

Error Handling

  • Log
    • Group list retrieval failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "グループリストの取得に失敗しました。" When an error occurs during retrieval
    400 "このリソースにアクセスする権限がありません。" When user does not have admin permissions
    400 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur

Case 2: Viewing Group Details

Description

Administrator views detailed information about a specific group.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as GroupController
    participant Service as GroupService
    participant DB as Database

    Note over Admin,DB: Step 1: Request Group Details
    Admin->>API: GET /api/admin/groups/{id}
    
    Note over API,API: Step 2: Check Access Permission
    API->>API: checkId(id)
    
    Note over API,Service: Step 3: Retrieve Group Data
    API->>Service: getById(id)
    Service->>DB: Fetch Group with Relations
    DB-->>Service: Return Group Data
    Service-->>API: Return Group with Subscription
    
    Note over API,Admin: Step 4: Return Group Details
    API-->>Admin: 200 OK (group resource)

Steps

Step 1: Request Group Details

  • Description: Admin requests details for a specific group
  • Request: GET /api/admin/groups/{id}

Step 2: Check Access Permission

  • Description: System verifies the admin has permission to access this group
  • Action:
    • Check if admin is Super Admin
    • If not, verify the admin belongs to the requested group
  • Potential errors: Insufficient permissions

Step 3: Retrieve Group Data

  • Description: System fetches the group with related data
  • Action:
    • Retrieve group by ID
    • Load related subscription data

Step 4: Return Group Details

  • Description: Return the group details
  • Response:
    • Success: 200 OK with group resource including related data
    • Error: Appropriate error message

Error Handling

  • Log
    • Group details retrieval failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    403 "グループデータの取得に失敗しました。" When access is denied or group not found

Case 3: Creating a New Group

Description

Administrator creates a new group with associated admin user and package plan.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as GroupController
    participant Service as GroupService
    participant DB as Database

    Note over Admin,DB: Step 1: Submit Group Creation
    Admin->>API: POST /api/admin/groups (group_data)
    
    Note over API,API: Step 2: Check Admin Permissions
    API->>API: Check Admin Role
    
    Note over API,API: Step 3: Validate Input
    API->>API: Validate Request Data
    
    Note over API,Service: Step 4: Create Group
    API->>Service: create(validated_data)
    Service->>DB: Create Group, Admin, and Subscription
    DB-->>Service: Return Created Group
    
    Note over API,Admin: Step 5: Return Response
    Service-->>API: Return Group Data
    API-->>Admin: 200 OK (group resource)

Steps

Step 1: Submit Group Creation

  • Description: Admin submits form to create a new group
  • Request: POST /api/admin/groups
  • Required fields:
    • name: Group name
    • email: Email for group admin
    • adminName: Name for group admin
    • plan: Package plan ID
    • status: Group status

Step 2: Check Admin Permissions

  • Description: System verifies the admin has appropriate permissions
  • Action: Check admin role is not AdminStaff
  • Potential errors: Insufficient permissions (400)

Step 3: Validate Input

  • Description: System validates all input data
  • Action: Runs validation rules from StoreGroupRequest
  • Potential errors: Validation failures

Step 4: Create Group

  • Description: System creates the group and associated data
  • Action:
    • Create group record
    • Create or assign admin user
    • Create subscription with selected package

Step 5: Return Response

  • Description: Return the created group data
  • Response:
    • Success: 200 OK with group data
    • Error: Appropriate error message

Error Handling

  • Log
    • Group creation failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "このリソースにアクセスする権限がありません。" When admin is AdminStaff role
    400 "グループの作成に失敗しました。" When group creation fails
    400 "メールアドレスはすでに使用されています。" When email already exists
    400 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur

Case 4: Updating a Group

Description

Administrator updates an existing group's information.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as GroupController
    participant Service as GroupService
    participant DB as Database

    Note over Admin,DB: Step 1: Submit Group Update
    Admin->>API: PUT /api/admin/groups/{id} (updated_data)
    
    Note over API,API: Step 2: Check Access Permission
    API->>API: checkId(id)
    
    Note over API,API: Step 3: Validate Input
    API->>API: Validate Request Data
    
    Note over API,Service: Step 4: Update Group
    API->>Service: update(id, validated_data)
    Service->>DB: Update Group Record
    DB-->>Service: Return Updated Group
    
    Note over API,Admin: Step 5: Return Response
    Service-->>API: Return Group Data
    API-->>Admin: 200 OK (group resource)

Steps

Step 1: Submit Group Update

  • Description: Admin submits form to update group information
  • Request: PUT /api/admin/groups/{id}
  • Updatable fields:
    • name: Group name
    • adminName: Name for group admin
    • plan: Package plan ID
    • status: Group status

Step 2: Check Access Permission

  • Description: System verifies the admin has permission to update this group
  • Action:
    • Check if admin is Super Admin
    • If not, verify the admin belongs to the requested group
  • Potential errors: Insufficient permissions

Step 3: Validate Input

  • Description: System validates all input data
  • Action: Runs validation rules from UpdateGroupRequest
  • Potential errors: Validation failures

Step 4: Update Group

  • Description: System updates the group information
  • Action: Update group record with new data

Step 5: Return Response

  • Description: Return the updated group data
  • Response:
    • Success: 200 OK with updated group data
    • Error: Appropriate error message

Error Handling

  • Log
    • Group update failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "グループデータの更新に失敗しました。" When group update fails
    400 "このリソースにアクセスする権限がありません。" When user does not have admin permissions
    400 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur

Case 5: Changing Group Status

Description

Administrator activates or deactivates a group.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as GroupController
    participant Service as GroupService
    participant DB as Database

    Note over Admin,DB: Step 1: Request Status Change
    Admin->>API: POST /api/admin/groups/{id}/change-status
    
    Note over API,API: Step 2: Check Access Permission
    API->>API: checkId(id)
    
    Note over API,Service: Step 3: Toggle Group Status
    API->>Service: updateStatusById(id)
    Service->>DB: Update Status
    DB-->>Service: Return Updated Group
    
    Note over API,Admin: Step 4: Return Response
    Service-->>API: Return Group Data
    API-->>Admin: 200 OK (group resource)

Steps

Step 1: Request Status Change

  • Description: Admin requests to change a group's active status
  • Request: POST /api/admin/groups/{id}/change-status

Step 2: Check Access Permission

  • Description: System verifies the admin has permission to modify this group
  • Action:
    • Check if admin is Super Admin
    • If not, verify the admin belongs to the requested group
  • Potential errors: Insufficient permissions

Step 3: Toggle Group Status

  • Description: System toggles the group's active status
  • Action:
    • Update status to opposite value (active to inactive or vice versa)

Step 4: Return Response

  • Description: Return the updated group data
  • Response:
    • Success: 200 OK with updated group data including new status
    • Error: Appropriate error message

Error Handling

  • Log
    • Status change failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "グループデータの更新に失敗しました。" When status update fails
    400 "このリソースにアクセスする権限がありません。" When user does not have admin permissions
    400 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur

Case 6: Deleting a Group

Description

Administrator removes a group from the system.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as GroupController
    participant Service as GroupService
    participant DB as Database

    Note over Admin,DB: Step 1: Request Group Deletion
    Admin->>API: DELETE /api/admin/groups/{id}
    
    Note over API,API: Step 2: Check Access Permission
    API->>API: checkId(id)
    
    Note over API,Service: Step 3: Delete Group
    API->>Service: delete(id)
    Service->>DB: Delete Group Record
    DB-->>Service: Confirm Deletion
    
    Note over API,Admin: Step 4: Return Response
    Service-->>API: Deletion Status
    API-->>Admin: 200 OK (success message)

Steps

Step 1: Request Group Deletion

  • Description: Admin requests to delete a group
  • Request: DELETE /api/admin/groups/{id}

Step 2: Check Access Permission

  • Description: System verifies the admin has permission to delete this group
  • Action:
    • Check if admin is Super Admin
    • If not, verify the admin belongs to the requested group
  • Potential errors: Insufficient permissions

Step 3: Delete Group

  • Description: System removes the group from the database
  • Action: Delete group record and possibly associated data

Step 4: Return Response

  • Description: Confirm successful deletion
  • Response:
    • Success: 200 OK with success message
    • Error: Appropriate error message

Error Handling

  • Log
    • Group deletion failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "グループデータの削除に失敗しました。" When deletion fails
    400 "このリソースにアクセスする権限がありません。" When user does not have admin permissions
    400 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur

Additional Notes

  • The Group Management module implements a hierarchical access control system where:
    • Super Admins can access and modify all groups
    • Group admins can only access and modify their own group
    • Admin Staff have limited permissions for group operations
  • Each group is associated with a package subscription that determines its resource limits
  • Group status changes affect the ability of group members to access system resources
  • Group deletion might not physically remove data immediately, but may mark it as deleted (soft delete) depending on implementation

Database Related Tables & Fields

erDiagram
    groups {
        id bigint "Primary key"
        name string "Group name"
        created_by bigint "Reference to users table"
        status int "Group status (0: Inactive, 1: Active)"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    users {
        id bigint "Primary key"
        name string "User's full name"
        email string "User's email address (unique)"
        uid string "Firebase UID (unique)"
        payment_provider_customer_id string "Payment provider customer ID (nullable)"
        status int "Account status (0: Inactive, 1: Active)"
        is_first_login int "First login flag (0: not yet, 1: logged in)"
        remember_token string "Remember token"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
        deleted_at timestamp "Soft delete timestamp"
    }
    group_members {
        id bigint "Primary key"
        group_id bigint "Reference to groups table"
        user_id bigint "Reference to users table"
        group_role_id bigint "Reference to group_roles table"
        is_creator boolean "Whether user is group creator"
        joined_at timestamp "When user joined the group"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    group_roles {
        id bigint "Primary key"
        name string "Role name (50 chars)"
        slug string "Role slug (50 chars, unique)"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }

    groups }|--|| users : created_by
    groups ||--o{ group_members : has
    users ||--o{ group_members : has
    group_roles ||--o{ group_members : has