# Story 1: Business Unit Management ## Story Overview **As a** system administrator **I want** to manage business units in the system **So that** I can organize applications under their respective organizational units **Story Type**: Feature **Priority**: High **Estimated Effort**: 3-5 days **Dependencies**: Story 0 (Foundation) --- ## Business Value Business units represent the organizational structure within which applications are managed. This story enables: - Clear organizational hierarchy - Application ownership mapping - Contact management at the business unit level - Foundation for multi-tenant capabilities --- ## Scope ### In Scope ✅ Business unit CRUD operations ✅ Business unit listing with search/filter ✅ Basic contact association (simplified for MVP) ✅ Validation (unique names, required fields) ### Out of Scope ❌ Complex hierarchical business units (parent/child relationships) ❌ Full contact management (covered in Story 3) ❌ Business unit-specific permissions ❌ Bulk import of business units --- ## Technical Implementation ### Backend Tasks #### 1. Database Migration - [ ] Create Liquibase migration file: `003-create-business-unit-tables.xml` - [ ] Create `business_unit` table: ```sql - id (UUID, PK) - name (VARCHAR(255), unique, not null) - description (TEXT, nullable) - created_at (TIMESTAMP, not null) - updated_at (TIMESTAMP, not null) ``` - [ ] Add index on `name` for search performance - [ ] Insert sample data (3-5 business units) for testing #### 2. JPA Entity - [ ] Create `BusinessUnit` entity extending `BaseEntity` ```java @Entity @Table(name = "business_unit") public class BusinessUnit extends BaseEntity { @Column(nullable = false, unique = true) private String name; @Column(columnDefinition = "TEXT") private String description; // Getters, setters, constructors } ``` #### 3. Repository Layer - [ ] Create `BusinessUnitRepository` interface ```java public interface BusinessUnitRepository extends JpaRepository { Optional findByName(String name); boolean existsByName(String name); Page findByNameContainingIgnoreCase(String name, Pageable pageable); } ``` #### 4. DTOs - [ ] Create `CreateBusinessUnitRequest`: - `name` (required, max 255 chars) - `description` (optional) - [ ] Create `UpdateBusinessUnitRequest`: - `name` (optional, max 255 chars) - `description` (optional) - [ ] Create `BusinessUnitResponse`: - `id`, `name`, `description`, `createdAt`, `updatedAt` - [ ] Create `BusinessUnitSummaryResponse` (for lists): - `id`, `name` #### 5. Service Layer - [ ] Create `BusinessUnitService` with methods: ```java BusinessUnitResponse create(CreateBusinessUnitRequest request); BusinessUnitResponse update(UUID id, UpdateBusinessUnitRequest request); BusinessUnitResponse findById(UUID id); Page findAll(Pageable pageable); Page search(String query, Pageable pageable); void delete(UUID id); ``` - [ ] Implement business logic: - Check uniqueness of name on create/update - Throw `ResourceNotFoundException` if not found - Throw `BadRequestException` for duplicate names - [ ] Add validation for required fields #### 6. Controller Layer - [ ] Create `BusinessUnitController` with endpoints: ```java GET /api/business-units - List all (paginated) GET /api/business-units/search?q={query} - Search by name GET /api/business-units/{id} - Get by ID POST /api/business-units - Create new PUT /api/business-units/{id} - Update DELETE /api/business-units/{id} - Delete ``` - [ ] Add validation annotations (`@Valid`, `@NotNull`, etc.) - [ ] Add Swagger/OpenAPI annotations - [ ] Add security: require authentication for all endpoints #### 7. Testing - [ ] Unit tests for `BusinessUnitService`: - Test create with valid data - Test create with duplicate name (should fail) - Test update existing business unit - Test delete business unit - Test search functionality - [ ] Integration tests for `BusinessUnitController`: - Test full CRUD flow - Test pagination and sorting - Test search with various queries - Test error cases (404, 400) - [ ] Test coverage > 80% --- ### Frontend Tasks #### 1. Models - [ ] Create `business-unit.model.ts`: ```typescript export interface BusinessUnit { id: string; name: string; description?: string; createdAt: Date; updatedAt: Date; } export interface BusinessUnitSummary { id: string; name: string; } export interface CreateBusinessUnitRequest { name: string; description?: string; } export interface UpdateBusinessUnitRequest { name?: string; description?: string; } ``` #### 2. Service - [ ] Create `business-unit.service.ts`: ```typescript @Injectable({ providedIn: 'root' }) export class BusinessUnitService { getBusinessUnits(page, size, sort): Observable> searchBusinessUnits(query, page, size): Observable> getBusinessUnit(id): Observable createBusinessUnit(data): Observable updateBusinessUnit(id, data): Observable deleteBusinessUnit(id): Observable } ``` #### 3. Components ##### BusinessUnitListComponent - [ ] Create component with template and styles - [ ] Features: - Table/list view of business units - Columns: Name, Description, Actions - Pagination controls (page size: 20) - Sort by name - Search bar (filter by name) - "Create New" button - Actions per row: View, Edit, Delete - [ ] Implement component logic: - Load business units on init - Handle pagination events - Handle sort events - Handle search with debounce (300ms) - Navigate to detail/form pages - Handle delete with confirmation ##### BusinessUnitDetailComponent - [ ] Create component with template and styles - [ ] Features: - Display all business unit details - "Edit" button - "Delete" button - "Back to List" button - Show created/updated timestamps - [ ] Load business unit by ID from route params ##### BusinessUnitFormComponent - [ ] Create component with template and styles - [ ] Reactive form with fields: - Name (required, max 255 chars) - Description (optional, textarea) - [ ] Form validation: - Name required - Max length validation - Show validation errors - [ ] Support both create and edit modes (based on route) - [ ] Handle form submission: - Call appropriate service method - Show loading indicator during save - Navigate to list on success - Show error notification on failure - [ ] "Cancel" button (navigate back) #### 4. Routing - [ ] Add routes to `app.routes.ts`: ```typescript { path: 'business-units', canActivate: [AuthGuard], children: [ { path: '', component: BusinessUnitListComponent }, { path: 'new', component: BusinessUnitFormComponent }, { path: ':id', component: BusinessUnitDetailComponent }, { path: ':id/edit', component: BusinessUnitFormComponent } ] } ``` #### 5. Navigation - [ ] Add "Business Units" link to header/sidebar navigation #### 6. Testing - [ ] Unit tests for `BusinessUnitService` - [ ] Component tests for `BusinessUnitListComponent`: - Test rendering of business units - Test pagination - Test search - Test navigation to create/edit/detail - [ ] Component tests for `BusinessUnitFormComponent`: - Test form validation - Test create mode - Test edit mode - Test form submission - [ ] E2E test: Full CRUD flow - [ ] Test coverage > 70% --- ## Acceptance Criteria ### Backend - [ ] Business unit can be created with unique name - [ ] Duplicate business unit names are rejected with 400 error - [ ] Business unit can be updated - [ ] Business unit can be deleted - [ ] Business units can be listed with pagination - [ ] Business units can be searched by name (case-insensitive) - [ ] All endpoints are authenticated - [ ] All endpoints return proper HTTP status codes - [ ] API is documented in Swagger ### Frontend - [ ] User can view list of all business units - [ ] List supports pagination (20 items per page) - [ ] User can search business units by name - [ ] Search has debounce (doesn't query on every keystroke) - [ ] User can create new business unit - [ ] Form validates required fields - [ ] User cannot create duplicate business unit names - [ ] User can view business unit details - [ ] User can edit existing business unit - [ ] User can delete business unit (with confirmation) - [ ] Success/error notifications are displayed - [ ] Navigation is intuitive and works correctly ### Testing - [ ] Backend unit tests pass (>80% coverage) - [ ] Backend integration tests pass - [ ] Frontend unit tests pass (>70% coverage) - [ ] E2E tests pass --- ## Testing Scenarios ### Scenario 1: Create Business Unit 1. Navigate to business units list 2. Click "Create New Business Unit" 3. Fill in form: - Name: "Digital Services" - Description: "Digital transformation initiatives" 4. Click "Save" 5. Verify success notification 6. Verify redirect to business unit list 7. Verify new business unit appears in list ### Scenario 2: Duplicate Name Prevention 1. Navigate to create business unit form 2. Enter name of existing business unit 3. Click "Save" 4. Verify error message: "Business unit with this name already exists" 5. Verify business unit is not created ### Scenario 3: Edit Business Unit 1. Navigate to business units list 2. Click "Edit" on a business unit 3. Modify description 4. Click "Save" 5. Verify success notification 6. Verify changes are reflected in detail view ### Scenario 4: Delete Business Unit 1. Navigate to business units list 2. Click "Delete" on a business unit 3. Confirm deletion in dialog 4. Verify success notification 5. Verify business unit is removed from list ### Scenario 5: Search Business Units 1. Navigate to business units list 2. Enter search query: "digital" 3. Wait for debounce (300ms) 4. Verify filtered results contain only matching business units 5. Clear search 6. Verify all business units are shown again ### Scenario 6: Pagination 1. Create 25+ business units (if not exists) 2. Navigate to business units list 3. Verify only 20 items shown on page 1 4. Click "Next page" 5. Verify remaining items shown on page 2 6. Click "Previous page" 7. Verify back to page 1 --- ## Definition of Done - [ ] All backend tasks completed - [ ] All frontend tasks completed - [ ] All acceptance criteria met - [ ] All tests passing (unit, integration, E2E) - [ ] Code reviewed and approved - [ ] API documented in Swagger - [ ] User can perform all CRUD operations via UI - [ ] Demo conducted successfully - [ ] Code merged to main branch --- ## Technical Debt & Future Improvements ### Known Limitations - No hierarchical business units (flat structure only) - No business unit deactivation (only hard delete) - No audit trail for changes - No bulk operations ### Future Enhancements - Add parent-child relationships between business units - Implement soft delete with deactivation flag - Add audit logging for business unit changes - Add bulk import from CSV/Excel - Add business unit-specific settings - Implement business unit archiving --- ## Dependencies & Blockers ### Dependencies - Story 0 (Foundation) must be complete ### Potential Blockers - None identified --- ## API Specification ### Endpoints #### GET /api/business-units **Description**: List all business units **Query Parameters**: - `page` (default: 0) - `size` (default: 20) - `sort` (default: name,asc) **Response**: `200 OK` ```json { "content": [ { "id": "uuid", "name": "Digital Services", "description": "Digital transformation initiatives", "createdAt": "2026-02-01T10:00:00Z", "updatedAt": "2026-02-01T10:00:00Z" } ], "pageable": { "pageNumber": 0, "pageSize": 20, "sort": { "sorted": true, "unsorted": false } }, "totalElements": 5, "totalPages": 1 } ``` #### GET /api/business-units/search **Description**: Search business units by name **Query Parameters**: - `q` (search query) - `page`, `size`, `sort` **Response**: Same as GET /api/business-units #### GET /api/business-units/{id} **Description**: Get business unit by ID **Response**: `200 OK` ```json { "id": "uuid", "name": "Digital Services", "description": "Digital transformation initiatives", "createdAt": "2026-02-01T10:00:00Z", "updatedAt": "2026-02-01T10:00:00Z" } ``` **Error**: `404 Not Found` if business unit doesn't exist #### POST /api/business-units **Description**: Create new business unit **Request Body**: ```json { "name": "Digital Services", "description": "Digital transformation initiatives" } ``` **Response**: `201 Created` ```json { "id": "uuid", "name": "Digital Services", "description": "Digital transformation initiatives", "createdAt": "2026-02-01T10:00:00Z", "updatedAt": "2026-02-01T10:00:00Z" } ``` **Errors**: - `400 Bad Request` if name is duplicate or validation fails - `401 Unauthorized` if not authenticated #### PUT /api/business-units/{id} **Description**: Update business unit **Request Body**: ```json { "name": "Digital Services", "description": "Updated description" } ``` **Response**: `200 OK` (same format as POST) **Errors**: - `404 Not Found` if business unit doesn't exist - `400 Bad Request` if validation fails #### DELETE /api/business-units/{id} **Description**: Delete business unit **Response**: `204 No Content` **Error**: `404 Not Found` if business unit doesn't exist --- **Story Status**: Ready for Development **Story Created**: February 2026 **Estimated Completion**: 3-5 days from start